From a044ba0667d0ca62d8a4e3c3b28605d66198ce7f Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 30 Dec 2020 22:09:26 -0500 Subject: [PATCH] [bindings] Use new non-null annotation feature in cbindgen This adds a new annotation for objects we take by reference in the C header indicating the pointers must not be null. We have to disable some warning clang now dumps that we haven't annotated all pointers, as cbindgen is not yet able to add a nullable annotation. --- c-bindings-gen/src/main.rs | 16 ++++++++++++---- genbindings.sh | 16 +++++++++------- lightning-c-bindings/cbindgen.toml | 3 +++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 9f86579a7..c74344321 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -1555,10 +1555,18 @@ fn main() { let mut cpp_header_file = std::fs::OpenOptions::new().write(true).create(true).truncate(true) .open(&args[6]).expect("Unable to open new header file"); - writeln!(header_file, "#if defined(__GNUC__)\n#define MUST_USE_STRUCT __attribute__((warn_unused))").unwrap(); - writeln!(header_file, "#else\n#define MUST_USE_STRUCT\n#endif").unwrap(); - writeln!(header_file, "#if defined(__GNUC__)\n#define MUST_USE_RES __attribute__((warn_unused_result))").unwrap(); - writeln!(header_file, "#else\n#define MUST_USE_RES\n#endif").unwrap(); + writeln!(header_file, "#if defined(__GNUC__)").unwrap(); + writeln!(header_file, "#define MUST_USE_STRUCT __attribute__((warn_unused))").unwrap(); + writeln!(header_file, "#define MUST_USE_RES __attribute__((warn_unused_result))").unwrap(); + writeln!(header_file, "#else").unwrap(); + writeln!(header_file, "#define MUST_USE_STRUCT").unwrap(); + writeln!(header_file, "#define MUST_USE_RES").unwrap(); + writeln!(header_file, "#endif").unwrap(); + writeln!(header_file, "#if defined(__clang__)").unwrap(); + writeln!(header_file, "#define NONNULL_PTR _Nonnull").unwrap(); + writeln!(header_file, "#else").unwrap(); + writeln!(header_file, "#define NONNULL_PTR").unwrap(); + writeln!(header_file, "#endif").unwrap(); writeln!(cpp_header_file, "#include \nnamespace LDK {{").unwrap(); // First parse the full crate's ASTs, caching them so that we can hold references to the AST diff --git a/genbindings.sh b/genbindings.sh index 007f69e99..c63de7dbc 100755 --- a/genbindings.sh +++ b/genbindings.sh @@ -60,9 +60,11 @@ else echo "WARNING: Please install valgrind for more testing" fi +CLANGOPTS="-Wall -Wno-nullability-completeness -pthread" + # Test a statically-linked C++ version, tracking the resulting binary size and runtime # across debug, LTO, and cross-language LTO builds (using the same compiler each time). -clang++ -std=c++11 -Wall -pthread demo.cpp target/debug/libldk.a -ldl +clang++ $CLANGOPTS demo.cpp target/debug/libldk.a -ldl strip ./a.out echo " C++ Bin size and runtime w/o optimization:" ls -lha a.out @@ -83,11 +85,11 @@ if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" ]; then set +e # First the C demo app... - clang-$LLVM_V -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -Wall -g -pthread demo.c target/debug/libldk.a -ldl + clang-$LLVM_V $CLANGOPTS -fsanitize=memory -fsanitize-memory-track-origins -g demo.c target/debug/libldk.a -ldl ./a.out # ...then the C++ demo app - clang++-$LLVM_V -std=c++11 -fsanitize=memory -fsanitize-memory-track-origins -Wall -g -pthread demo.cpp target/debug/libldk.a -ldl + clang++-$LLVM_V -std=c++11 $CLANGOPTS -fsanitize=memory -fsanitize-memory-track-origins -g demo.cpp target/debug/libldk.a -ldl ./a.out >/dev/null # restore exit-on-failure @@ -153,11 +155,11 @@ if [ "$HOST_PLATFORM" = "host: x86_64-unknown-linux-gnu" -o "$HOST_PLATFORM" = " mv Cargo.toml.bk Cargo.toml # First the C demo app... - $CLANG -fsanitize=address -Wall -g -pthread demo.c target/debug/libldk.a -ldl + $CLANG $CLANGOPTS -fsanitize=address -g demo.c target/debug/libldk.a -ldl ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out # ...then the C++ demo app - $CLANGPP -std=c++11 -fsanitize=address -Wall -g -pthread demo.cpp target/debug/libldk.a -ldl + $CLANGPP $CLANGOPTS -std=c++11 -fsanitize=address -g demo.cpp target/debug/libldk.a -ldl ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' ./a.out >/dev/null else echo "WARNING: Please install clang-$RUSTC_LLVM_V and clang++-$RUSTC_LLVM_V to build with address sanitizer" @@ -168,7 +170,7 @@ fi # Now build with LTO on on both C++ and rust, but without cross-language LTO: CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C lto -clang++ -std=c++11 -Wall -flto -O2 -pthread demo.cpp target/release/libldk.a -ldl +clang++ $CLANGOPTS -std=c++11 -flto -O2 demo.cpp target/release/libldk.a -ldl strip ./a.out echo "C++ Bin size and runtime with only RL (LTO) optimized:" ls -lha a.out @@ -181,7 +183,7 @@ if [ "$HOST_PLATFORM" != "host: x86_64-apple-darwin" -a "$CLANGPP" != "" ]; then # packaging than simply shipping the rustup binaries (eg Debian should Just Work # here). CARGO_PROFILE_RELEASE_LTO=true cargo rustc -v --release -- -C linker-plugin-lto -C lto -C link-arg=-fuse-ld=lld - $CLANGPP -Wall -std=c++11 -flto -fuse-ld=lld -O2 -pthread demo.cpp target/release/libldk.a -ldl + $CLANGPP $CLANGOPTS -flto -fuse-ld=lld -O2 demo.cpp target/release/libldk.a -ldl strip ./a.out echo "C++ Bin size and runtime with cross-language LTO:" ls -lha a.out diff --git a/lightning-c-bindings/cbindgen.toml b/lightning-c-bindings/cbindgen.toml index 48267780f..9480b8688 100644 --- a/lightning-c-bindings/cbindgen.toml +++ b/lightning-c-bindings/cbindgen.toml @@ -550,3 +550,6 @@ default_features = true # # default: [] features = ["cbindgen"] + +[ptr] +non_null_attribute = "NONNULL_PTR" -- 2.39.5