From 892e2ec117f817d5a439dfb39104b2be4678cd0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 3 Feb 2019 14:33:16 +0100 Subject: [PATCH 1/2] fuzzing: Add a --release flag to the predicate script. When you're not testing for debug assertions this is much faster. --- Cargo.lock | 2 ++ csmith-fuzzing/predicate.py | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 838994ee73..8b8107c7f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "aho-corasick" version = "0.6.8" diff --git a/csmith-fuzzing/predicate.py b/csmith-fuzzing/predicate.py index 4909b4f689..043a993534 100755 --- a/csmith-fuzzing/predicate.py +++ b/csmith-fuzzing/predicate.py @@ -65,6 +65,10 @@ reducing = parser.add_argument_group("reducing arguments", REDUCING_DESC.strip()) +reducing.add_argument( + "--release", + action="store_true", + help="Use a release instead of a debug build.") reducing.add_argument( "--expect-bindgen-fail", action="store_true", @@ -194,13 +198,13 @@ def run_bindgen(args, bindings): manifest_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..", "Cargo.toml")) - child = run( - ["cargo", "run", - "--manifest-path", manifest_path, - "--", - args.input, "-o", bindings] + shlex.split(args.bindgen_args), - stderr=subprocess.PIPE, - stdout=subprocess.PIPE) + command = ["cargo", "run", "--manifest-path", manifest_path] + if args.release: + command += ["--release"] + command += ["--", args.input, "-o", bindings] + command += shlex.split(args.bindgen_args) + + child = run(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) if args.bindgen_grep: pattern = regexp(args.bindgen_grep) From 1ea12aa2dfbfcb27ef102ec8a001a3a05175004f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 3 Feb 2019 14:38:35 +0100 Subject: [PATCH 2/2] ir: Ignore constructors with bogus spellings. --- src/ir/function.rs | 24 +++++++++++++++++------- tests/expectations/tests/issue-1464.rs | 8 ++++++++ tests/headers/issue-1464.hpp | 7 +++++++ tests/tests.rs | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 tests/expectations/tests/issue-1464.rs create mode 100644 tests/headers/issue-1464.hpp diff --git a/src/ir/function.rs b/src/ir/function.rs index acbfe707ce..fae6e056aa 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -337,7 +337,8 @@ impl FunctionSig { debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor); // Skip function templates - if cursor.kind() == CXCursor_FunctionTemplate { + let kind = cursor.kind(); + if kind == CXCursor_FunctionTemplate { return Err(ParseError::Continue); } @@ -347,13 +348,22 @@ impl FunctionSig { return Err(ParseError::Continue); } + // Constructors of non-type template parameter classes for some reason + // include the template parameter in their name. Just skip them, since + // we don't handle well non-type template parameters anyway. + if (kind == CXCursor_Constructor || kind == CXCursor_Destructor) && + spelling.contains('<') + { + return Err(ParseError::Continue); + } + let cursor = if cursor.is_valid() { *cursor } else { ty.declaration() }; - let mut args: Vec<_> = match cursor.kind() { + let mut args: Vec<_> = match kind { CXCursor_FunctionDecl | CXCursor_Constructor | CXCursor_CXXMethod | @@ -397,9 +407,9 @@ impl FunctionSig { let must_use = ctx.options().enable_function_attribute_detection && cursor.has_simple_attr("warn_unused_result"); - let is_method = cursor.kind() == CXCursor_CXXMethod; - let is_constructor = cursor.kind() == CXCursor_Constructor; - let is_destructor = cursor.kind() == CXCursor_Destructor; + let is_method = kind == CXCursor_CXXMethod; + let is_constructor = kind == CXCursor_Constructor; + let is_destructor = kind == CXCursor_Destructor; if (is_constructor || is_destructor || is_method) && cursor.lexical_parent() != cursor.semantic_parent() { @@ -442,8 +452,8 @@ impl FunctionSig { } } - let ty_ret_type = if cursor.kind() == CXCursor_ObjCInstanceMethodDecl || - cursor.kind() == CXCursor_ObjCClassMethodDecl + let ty_ret_type = if kind == CXCursor_ObjCInstanceMethodDecl || + kind == CXCursor_ObjCClassMethodDecl { ty.ret_type().or_else(|| cursor.ret_type()).ok_or( ParseError::Continue, diff --git a/tests/expectations/tests/issue-1464.rs b/tests/expectations/tests/issue-1464.rs new file mode 100644 index 0000000000..d6776794e9 --- /dev/null +++ b/tests/expectations/tests/issue-1464.rs @@ -0,0 +1,8 @@ +/* automatically generated by rust-bindgen */ + +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] diff --git a/tests/headers/issue-1464.hpp b/tests/headers/issue-1464.hpp new file mode 100644 index 0000000000..d34d0fe3e5 --- /dev/null +++ b/tests/headers/issue-1464.hpp @@ -0,0 +1,7 @@ + +// Should not crash. +template class Bar { +public: + Bar(); + ~Bar(); +}; diff --git a/tests/tests.rs b/tests/tests.rs index 93b8971b0a..0966f8771f 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -207,7 +207,7 @@ fn compare_generated_header( expectation_file.write_all(actual.as_bytes())?; } - Err(Error::new(ErrorKind::Other, "Header and binding differ!")) + Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation.")) } fn create_bindgen_builder(header: &PathBuf) -> Result, Error> {