From 5ce024bf6e182e9ee22c78324d46ca9c5bc19c90 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 13 Dec 2017 02:47:02 -0800 Subject: [PATCH] [clang] do not error on bogus arguments to `fsanitize` Summary: Simpler approach than having to look into argfiles Reviewed By: mbouaziz Differential Revision: D6546388 fbshipit-source-id: 3d08001 --- Makefile | 1 + infer/src/base/Pp.ml | 4 +--- infer/src/clang/Capture.ml | 2 +- infer/src/clang/ClangCommand.ml | 7 ++----- infer/src/clang/ClangCommand.mli | 2 +- infer/src/clang/ClangWrapper.ml | 16 ++++++++++------ infer/src/integration/Driver.ml | 6 +++--- .../clang_with_blacklisted_flags/Makefile | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index c6af1b47d..74267287c 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ BUILD_SYSTEMS_TESTS += \ clang_multiple_files \ clang_translation \ clang_unknown_ext \ + clang_with_blacklisted_flags \ clang_with_E_flag \ clang_with_M_flag \ clang_with_MD_flag \ diff --git a/infer/src/base/Pp.ml b/infer/src/base/Pp.ml index c0f91127d..3136a86fe 100644 --- a/infer/src/base/Pp.ml +++ b/infer/src/base/Pp.ml @@ -144,8 +144,6 @@ let pp_argfile fmt fname = let cli_args fmt args = - F.fprintf fmt "%a@\n%a" - (seq ~sep:(String.of_char CLOpt.env_var_sep) string) - args (seq ~sep:"\n" pp_argfile) + F.fprintf fmt "'%a'@\n%a" (seq ~sep:"' '" string) args (seq ~sep:"\n" pp_argfile) (List.filter_map ~f:(String.chop_prefix ~prefix:"@") args) diff --git a/infer/src/clang/Capture.ml b/infer/src/clang/Capture.ml index 24995dff5..139fe8f39 100644 --- a/infer/src/clang/Capture.ml +++ b/infer/src/clang/Capture.ml @@ -139,7 +139,7 @@ let cc1_capture clang_cmd = let root = Unix.getcwd () in let orig_argv = ClangCommand.get_orig_argv clang_cmd in (* the source file is always the last argument of the original -cc1 clang command *) - Utils.filename_to_absolute ~root orig_argv.(Array.length orig_argv - 1) + Utils.filename_to_absolute ~root (List.last_exn orig_argv) in L.(debug Capture Quiet) "@\n*** Beginning capture of file %s ***@\n" source_path ; if Config.equal_analyzer Config.analyzer Config.CompileOnly diff --git a/infer/src/clang/ClangCommand.ml b/infer/src/clang/ClangCommand.ml index a5f2442ed..5e9b5c60b 100644 --- a/infer/src/clang/ClangCommand.ml +++ b/infer/src/clang/ClangCommand.ml @@ -130,11 +130,8 @@ let clang_cc1_cmd_sanitizer cmd = let mk quoting_style ~prog ~args = (* Some arguments break the compiler so they need to be removed even before the normalization step *) - let blacklisted_flags = ["-fsanitize=builtin"] in let blacklisted_flags_with_arg = ["-index-store-path"] in - let sanitized_args = - filter_and_replace_unsupported_args ~blacklisted_flags ~blacklisted_flags_with_arg args - in + let sanitized_args = filter_and_replace_unsupported_args ~blacklisted_flags_with_arg args in {exec= prog; orig_argv= sanitized_args; argv= sanitized_args; quoting_style} @@ -197,4 +194,4 @@ let prepend_args args clang_args = {clang_args with argv= args @ clang_args.argv let append_args args clang_args = {clang_args with argv= clang_args.argv @ args} -let get_orig_argv {exec; orig_argv} = Array.of_list (exec :: orig_argv) +let get_orig_argv {exec; orig_argv} = exec :: orig_argv diff --git a/infer/src/clang/ClangCommand.mli b/infer/src/clang/ClangCommand.mli index 97300f187..c2331f8b4 100644 --- a/infer/src/clang/ClangCommand.mli +++ b/infer/src/clang/ClangCommand.mli @@ -40,7 +40,7 @@ val prepend_args : string list -> t -> t val append_args : string list -> t -> t -val get_orig_argv : t -> string array +val get_orig_argv : t -> string list val with_exec : string -> t -> t (** update the executable to be run *) diff --git a/infer/src/clang/ClangWrapper.ml b/infer/src/clang/ClangWrapper.ml index 55332c2f7..f8a785a11 100644 --- a/infer/src/clang/ClangWrapper.ml +++ b/infer/src/clang/ClangWrapper.ml @@ -94,13 +94,17 @@ let normalize ~prog ~args : action_item list = (* commands generated by `clang -### ...` start with ' "/absolute/path/to/binary"' *) Str.regexp " \"/\\|clang[^ :]*: \\(error\\|warning\\): " in + let ignored_errors = + Str.regexp "clang[^ :]*: \\(error\\|warning\\): unsupported argument .* to option 'fsanitize='" + in let consume_input i = try while true do let line = In_channel.input_line_exn i in (* keep only commands and errors *) - if Str.string_match commands_or_errors line 0 then normalized_commands - := one_line line :: !normalized_commands + if Str.string_match commands_or_errors line 0 + && not (Str.string_match ignored_errors line 0) + then normalized_commands := one_line line :: !normalized_commands done with End_of_file -> () in @@ -110,13 +114,13 @@ let normalize ~prog ~args : action_item list = !normalized_commands -let exec_action_item = function +let exec_action_item ~prog ~args = function | ClangError error -> (* An error in the output of `clang -### ...`. Outputs the error and fail. This is because `clang -###` pretty much never fails, but warns of failures on stderr instead. *) L.(die UserError) - "Failed to execute compilation command. Output:@\n%s@\n*** Infer needs a working compilation command to run." - error + "Failed to execute compilation command:@\n'%s' %a@\n@\nError message:@\n%s@\n@\n*** Infer needs a working compilation command to run." + prog Pp.cli_args args error | ClangWarning warning -> L.external_warning "%s@\n" warning | Command clang_cmd -> @@ -140,7 +144,7 @@ let exe ~prog ~args = | None -> (clang_xx, false) in - List.iter ~f:exec_action_item commands ; + List.iter ~f:(exec_action_item ~prog ~args) commands ; if List.is_empty commands || should_run_original_command then ( if List.is_empty commands then (* No command to execute after -###, let's execute the original command diff --git a/infer/src/integration/Driver.ml b/infer/src/integration/Driver.ml index 9ed81406f..c953e7616 100644 --- a/infer/src/integration/Driver.ml +++ b/infer/src/integration/Driver.ml @@ -43,11 +43,11 @@ let pp_mode fmt mode = (* these are pretty boring, do not log anything *) () | Javac (_, prog, args) -> - F.fprintf fmt "Javac driver mode:@\nprog = %s@\nargs = %a" prog Pp.cli_args args + F.fprintf fmt "Javac driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args | Maven (prog, args) -> - F.fprintf fmt "Maven driver mode:@\nprog = %s@\nargs = %a" prog Pp.cli_args args + F.fprintf fmt "Maven driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args | Clang (_, prog, args) -> - F.fprintf fmt "Clang driver mode:@\nprog = %s@\nargs = %a" prog Pp.cli_args args + F.fprintf fmt "Clang driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args (* A clean command for each driver mode to be suggested to the user diff --git a/infer/tests/build_systems/clang_with_blacklisted_flags/Makefile b/infer/tests/build_systems/clang_with_blacklisted_flags/Makefile index e5be65d14..c5efa07c1 100644 --- a/infer/tests/build_systems/clang_with_blacklisted_flags/Makefile +++ b/infer/tests/build_systems/clang_with_blacklisted_flags/Makefile @@ -13,7 +13,7 @@ ANALYZER = checkers # a folder, is not discarded, and Clang considers it as a source file. This # leads to an error. This weird case can be observed when -index-store-path is # passed in a sequence like the one in CLANG_OPTIONS. -CLANG_OPTIONS = -x c -index-store-path . -c -fsanitize=builtin +CLANG_OPTIONS = -x c -index-store-path . -c -fsanitize=builtin -fsanitize=address,builtin INFER_OPTIONS = --report-custom-error --developer-mode --project-root ../codetoanalyze INFERPRINT_OPTIONS = --issues-tests