From c20ace4a1a98f6c1abc2c0c08a3dbdfb1fa3f5a4 Mon Sep 17 00:00:00 2001 From: Dulma Rodriguez Date: Thu, 10 Mar 2016 02:27:59 -0800 Subject: [PATCH] Add flag cxx experimental to the clang frontend Reviewed By: cristianoc Differential Revision: D3029574 fb-gh-sync-id: 5ac4478 shipit-source-id: 5ac4478 --- infer/lib/python/inferlib/capture/util.py | 10 ++++- infer/models/cpp/Makefile.in | 2 +- infer/src/clang/cFrontend.ml | 2 +- infer/src/clang/cFrontend_config.ml | 2 + infer/src/clang/cFrontend_config.mli | 2 + infer/src/clang/cLocation.ml | 13 +++--- infer/src/clang/cLocation.mli | 2 - infer/src/clang/cMain.ml | 9 +++- .../cpp/IncludeHeaderNoTemplTest.java | 2 +- .../endtoend/cpp/IncludeHeaderTemplTest.java | 2 +- .../tests/frontend/cpp/IncludeHeaderTest.java | 2 +- infer/tests/utils/ClangFrontendUtils.java | 26 +++++++++--- infer/tests/utils/InferRunner.java | 41 ++++++++++++++++++- 13 files changed, 93 insertions(+), 22 deletions(-) diff --git a/infer/lib/python/inferlib/capture/util.py b/infer/lib/python/inferlib/capture/util.py index fddf8838c..5be188d11 100644 --- a/infer/lib/python/inferlib/capture/util.py +++ b/infer/lib/python/inferlib/capture/util.py @@ -100,8 +100,12 @@ def clang_frontend_argparser(description, module_name): '-tm', '--testing_mode', dest='testing_mode', action='store_true', - help='Testing mode for the translation: Do not translate libraries' - ' (including enums)') + help='Testing mode for the translation: Do not translate headers') + group.add_argument( + '--cxx', + dest='cxx', + action='store_true', + help='Analyze C++ methods, still experimental') group.add_argument( '-fs', '--frontend-stats', dest='frontend_stats', @@ -132,6 +136,8 @@ def get_clang_frontend_envvars(args): frontend_args += ['-project_root', args.project_root] if args.testing_mode: frontend_args.append('-testing_mode') + if args.cxx: + frontend_args.append('-cxx-experimental') if args.frontend_debug: frontend_args += ['-debug'] env_vars['FCP_DEBUG_MODE'] = '1' diff --git a/infer/models/cpp/Makefile.in b/infer/models/cpp/Makefile.in index 9f931a7ad..a4483b24e 100644 --- a/infer/models/cpp/Makefile.in +++ b/infer/models/cpp/Makefile.in @@ -19,7 +19,7 @@ all: $(CPP_MODELS_FILE) $(CPP_MODELS_FILE): $(CPP_MODELS_SOURCES) $(CLANG_DEPS) # make clean in src/ in case $(CLANG_DEPS) have changed $(MAKE) -C src clean - $(INFER) -o out/ --models_mode --no_failures_allowed -- $(MAKE) -C src + $(INFER) -o out/ --models_mode --no_failures_allowed --cxx -- $(MAKE) -C src touch $(CPP_MODELS_FILE) install: $(CPP_MODELS_FILE) diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index 378607c2b..7e42b31d2 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -79,7 +79,7 @@ let rec translate_one_declaration tenv cg cfg parent_dec dec = | Some (ClassTemplateSpecializationDecl _ as d) -> let class_name = CTypes_decl.get_record_name d in let curr_class = CContext.ContextCls(class_name, None, []) in - if !CFrontend_config.testing_mode then + if !CFrontend_config.cxx_experimental then CMethod_declImpl.process_methods tenv cg cfg curr_class [dec] | Some dec -> Printing.log_stats "Methods of %s skipped\n" (Ast_utils.string_of_decl dec) | None -> ()) diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index 70255880d..44c6f5ea6 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -13,6 +13,8 @@ let no_translate_libs = ref true let testing_mode = ref false +let cxx_experimental = ref false + let array_with_objects_count_m = "arrayWithObjects:count:" let object_at_indexed_subscript_m = "objectAtIndexedSubscript:" diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 7ee5420a6..91df893c2 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -39,6 +39,8 @@ val no_translate_libs : bool ref val testing_mode : bool ref +val cxx_experimental : bool ref + (** constants *) val json : string ref diff --git a/infer/src/clang/cLocation.ml b/infer/src/clang/cLocation.ml index adae51a5c..b79803077 100644 --- a/infer/src/clang/cLocation.ml +++ b/infer/src/clang/cLocation.ml @@ -74,6 +74,12 @@ let clang_to_sil_location clang_loc procdesc_opt = | None -> !curr_file, !Config.nLOC in Location.{line; col; file; nLOC} +(* We translate by default the instructions in the current file.*) +(* In C++ development, we also translate the headers that are part *) +(* of the project. However, in testing mode, we don't want to translate *) +(* the headers because the dot files in the frontend tests should contain nothing *) +(* else than the source file to avoid conflicts between different versions of the *) +(* libraries in the CI *) let should_translate (loc_start, loc_end) = let map_path_of pred loc = match loc.Clang_ast_t.sl_file with @@ -96,16 +102,13 @@ let should_translate (loc_start, loc_end) = equal_current_source !curr_file || map_file_of equal_current_source loc_end || map_file_of equal_current_source loc_start - || (!CFrontend_config.testing_mode && file_in_project) + || (!CFrontend_config.cxx_experimental && file_in_project + && not (!CFrontend_config.testing_mode)) let should_translate_lib source_range = not !CFrontend_config.no_translate_libs || should_translate source_range -let should_translate_enum source_range = - not !CFrontend_config.testing_mode - || should_translate source_range - let get_sil_location_from_range source_range prefer_first = let sloc1, sloc2 = source_range in let sloc = if not prefer_first then sloc2 else choose_sloc sloc1 sloc2 in diff --git a/infer/src/clang/cLocation.mli b/infer/src/clang/cLocation.mli index 365fa616e..4d56cb928 100644 --- a/infer/src/clang/cLocation.mli +++ b/infer/src/clang/cLocation.mli @@ -21,8 +21,6 @@ val get_sil_location : Clang_ast_t.stmt_info -> CContext.t -> Location.t val should_translate_lib : Clang_ast_t.source_range -> bool -val should_translate_enum : Clang_ast_t.source_range -> bool - val update_curr_file : Clang_ast_t.decl_info -> unit val check_source_file : string -> unit diff --git a/infer/src/clang/cMain.ml b/infer/src/clang/cMain.ml index 48ba4d9b6..e84b10af4 100644 --- a/infer/src/clang/cMain.ml +++ b/infer/src/clang/cMain.ml @@ -52,8 +52,8 @@ let arg_desc = "-testing_mode", Arg.Unit (fun _ -> CFrontend_config.testing_mode := true), None, - "Mode for testing, where no libraries are translated, \ - including enums defined in the libraries" + "Mode for testing, where no headers are translated, \ + and dot files are created" ; "-debug", Arg.Unit (fun _ -> CFrontend_config.debug_mode := true), @@ -81,6 +81,11 @@ let arg_desc = None, "Mode for computing the models" ; + "-cxx-experimental", + Arg.Unit (fun _ -> CFrontend_config.cxx_experimental := true), + None, + "Analyze C++ methods, still experimental" + ; ] in Arg.create_options_desc false "Parsing Options" desc diff --git a/infer/tests/endtoend/cpp/IncludeHeaderNoTemplTest.java b/infer/tests/endtoend/cpp/IncludeHeaderNoTemplTest.java index ca3700695..cecc7b15a 100644 --- a/infer/tests/endtoend/cpp/IncludeHeaderNoTemplTest.java +++ b/infer/tests/endtoend/cpp/IncludeHeaderNoTemplTest.java @@ -42,7 +42,7 @@ public class IncludeHeaderNoTemplTest { @BeforeClass public static void runInfer() throws InterruptedException, IOException { - inferCmd = InferRunner.createCPPInferCommand(folder, FILE); + inferCmd = InferRunner.createCPPInferCommandIncludeHeaders(folder, FILE); } @Test diff --git a/infer/tests/endtoend/cpp/IncludeHeaderTemplTest.java b/infer/tests/endtoend/cpp/IncludeHeaderTemplTest.java index 0939216d3..b8198ccd1 100644 --- a/infer/tests/endtoend/cpp/IncludeHeaderTemplTest.java +++ b/infer/tests/endtoend/cpp/IncludeHeaderTemplTest.java @@ -42,7 +42,7 @@ public class IncludeHeaderTemplTest { @BeforeClass public static void runInfer() throws InterruptedException, IOException { - inferCmd = InferRunner.createCPPInferCommand(folder, FILE); + inferCmd = InferRunner.createCPPInferCommandIncludeHeaders(folder, FILE); } @Test diff --git a/infer/tests/frontend/cpp/IncludeHeaderTest.java b/infer/tests/frontend/cpp/IncludeHeaderTest.java index 5070aa4f9..46ecf33c3 100644 --- a/infer/tests/frontend/cpp/IncludeHeaderTest.java +++ b/infer/tests/frontend/cpp/IncludeHeaderTest.java @@ -26,7 +26,7 @@ public class IncludeHeaderTest { public DebuggableTemporaryFolder folder = new DebuggableTemporaryFolder(); void frontendTest(String fileRelative) throws InterruptedException, IOException, InferException { - ClangFrontendUtils.createAndCompareCppDotFiles(folder, basePath + fileRelative); + ClangFrontendUtils.createAndCompareCppDotFilesIncludeHeaders(folder, basePath + fileRelative); } @Test diff --git a/infer/tests/utils/ClangFrontendUtils.java b/infer/tests/utils/ClangFrontendUtils.java index cc02f5ee7..f096f7ab2 100644 --- a/infer/tests/utils/ClangFrontendUtils.java +++ b/infer/tests/utils/ClangFrontendUtils.java @@ -22,15 +22,19 @@ import utils.InferException; import utils.InferRunner; public class ClangFrontendUtils { - public static void createAndCompareCppDotFiles(DebuggableTemporaryFolder folder, String pathToSrcFile) + public static void createAndCompareCppDotFiles ( + DebuggableTemporaryFolder folder, + String pathToSrcFile, + boolean headers) throws InterruptedException, IOException, InferException { String test_src = pathToSrcFile; String test_dotty = pathToSrcFile + ".dot"; - ImmutableList inferCmd = - InferRunner.createCPPInferCommandFrontend( - folder, - test_src); + ImmutableList inferCmd; + if (headers) + inferCmd = InferRunner.createCPPInferCommandIncludeHeaders(folder, test_src); + else + inferCmd = InferRunner.createCPPInferCommandFrontend(folder, test_src); File newDotFile = InferRunner.runInferFrontend(inferCmd); assertThat( "In the capture of " + test_src + @@ -38,6 +42,18 @@ public class ClangFrontendUtils { newDotFile, dotFileEqualTo(test_dotty)); } + public static void createAndCompareCppDotFiles(DebuggableTemporaryFolder folder, + String pathToSrcFile) + throws InterruptedException, IOException, InferException { + createAndCompareCppDotFiles(folder, pathToSrcFile, false); + } + + public static void createAndCompareCppDotFilesIncludeHeaders(DebuggableTemporaryFolder folder, + String pathToSrcFile) + throws InterruptedException, IOException, InferException { + createAndCompareCppDotFiles(folder, pathToSrcFile, true); + } + public static void createAndCompareCDotFiles(DebuggableTemporaryFolder folder, String pathToSrcFile) throws InterruptedException, IOException, InferException { diff --git a/infer/tests/utils/InferRunner.java b/infer/tests/utils/InferRunner.java index 344123e86..687968336 100644 --- a/infer/tests/utils/InferRunner.java +++ b/infer/tests/utils/InferRunner.java @@ -243,7 +243,8 @@ public class InferRunner { boolean analyze, @Nullable String isysroot, @Nullable String ml_buckets, - boolean arc) { + boolean arc, + boolean headers) { File resultsDir = createResultsDir(folder); String resultsDirName = resultsDir.getAbsolutePath(); InferRunner.bugsFile = new File(resultsDir, BUGS_FILE_NAME); @@ -255,6 +256,10 @@ public class InferRunner { .add("--analyzer") .add("capture"); } + if (headers) { + analyzeOption + .add("--headers"); + } ImmutableList.Builder ml_bucketsOption = new ImmutableList.Builder<>(); ml_bucketsOption @@ -267,6 +272,7 @@ public class InferRunner { .add("--out") .add(resultsDirName) .add("--testing_mode") + .add("--cxx") .addAll(analyzeOption.build()) .addAll(ml_bucketsOption.build()) .add("--") @@ -275,6 +281,25 @@ public class InferRunner { return inferCmd; } + public static ImmutableList createClangInferCommand( + TemporaryFolder folder, + String sourceFile, + Language lang, + boolean analyze, + @Nullable String isysroot, + @Nullable String ml_buckets, + boolean arc) { + return createClangInferCommand( + folder, + sourceFile, + lang, + analyze, + isysroot, + ml_buckets, + arc, + false); + } + public static ImmutableList createCInferCommandFrontend( TemporaryFolder folder, String sourceFile) { @@ -366,6 +391,20 @@ public class InferRunner { false); } + public static ImmutableList createCPPInferCommandIncludeHeaders( + TemporaryFolder folder, + String sourceFile) { + return createClangInferCommand( + folder, + sourceFile, + Language.CPP, + true, + null, + null, + false, + true); + } + public static ImmutableList createCPPInferCommandWithMLBuckets( TemporaryFolder folder, String sourceFile,