diff --git a/.gitignore b/.gitignore index 16d2722cd..61f4e89a5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ duplicates.txt /infer/tests/build_systems/buck_export_changed_functions/diff.mod.test /infer/tests/build_systems/clang_compilation_db_escaped/compile_commands.json /infer/tests/build_systems/clang_compilation_db_relpath/compile_commands.json +/infer/tests/build_systems/clang_test_determinator/*.test /infer/tests/build_systems/export_changed_functions/*.test /infer/tests/build_systems/clang_with_MD_flag/hello.d /infer/tests/build_systems/codetoanalyze/mvn/**/target/ diff --git a/Makefile b/Makefile index dc4893e32..a91942073 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ BUILD_SYSTEMS_TESTS += \ ck_analytics ck_imports \ clang_compilation_db_escaped clang_compilation_db_relpath \ clang_multiple_files \ + clang_test_determinator \ clang_translation \ clang_unknown_ext \ clang_with_blacklisted_flags \ diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index dd6961ac5..51cca7cd5 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -1575,9 +1575,9 @@ INTERNAL OPTIONS --per-procedure-parallelism. If 0 is specified, each file is divided into --jobs groups of procedures. - --no-process-clang-ast - Deactivates: process the ast to emit some info about the file (Not - available for Java) (Conversely: --process-clang-ast) + --process-clang-ast + Activates: process the ast to emit some info about the file (Not + available for Java) (Conversely: --no-process-clang-ast) --procs-csv file Write statistics for each procedure in CSV format to a file diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 22543d960..15f72cb58 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1883,8 +1883,7 @@ and procedures_source_file = and process_clang_ast = - CLOpt.mk_bool ~long:"process-clang-ast" - ~default:true (* To be made false after this is deployed *) + CLOpt.mk_bool ~long:"process-clang-ast" ~default:false "process the ast to emit some info about the file (Not available for Java)" diff --git a/infer/src/clang/ProcessAST.ml b/infer/src/clang/ProcessAST.ml index f72b6617c..423d14426 100644 --- a/infer/src/clang/ProcessAST.ml +++ b/infer/src/clang/ProcessAST.ml @@ -7,12 +7,21 @@ open! IStd module F = Format -let export_changed_functions trans_unit_ctx ast_decl = +let export_changed_functions source_file ast_decl = + let clang_range_map = AstToRangeMap.process_ast ast_decl source_file in + TestDeterminator.compute_and_emit_relevant_methods ~clang_range_map ~source_file + + +let export_tests_to_run source_file ast_decl = + let clang_range_map = AstToRangeMap.process_ast ast_decl source_file in + TestDeterminator.compute_and_emit_test_to_run ~clang_range_map ~source_file () + + +let process_ast trans_unit_ctx ast_decl = let source_file = trans_unit_ctx.CFrontend_config.source_file in let f () = - if Config.export_changed_functions then - let clang_range_map = AstToRangeMap.process_ast ast_decl source_file in - TestDeterminator.compute_and_emit_relevant_methods ~clang_range_map ~source_file + if Config.export_changed_functions then export_changed_functions source_file ast_decl ; + if Config.test_determinator then export_tests_to_run source_file ast_decl in let call_f () = CFrontend_errors.protect trans_unit_ctx @@ -21,7 +30,3 @@ let export_changed_functions trans_unit_ctx ast_decl = ~f in call_f () - - -let process_ast trans_unit_ctx ast_decl = - if Config.export_changed_functions then export_changed_functions trans_unit_ctx ast_decl diff --git a/infer/src/infer.ml b/infer/src/infer.ml index c904af5e9..47fd86f1a 100644 --- a/infer/src/infer.ml +++ b/infer/src/infer.ml @@ -138,7 +138,8 @@ let () = if Config.debug_mode && CLOpt.is_originator then ( L.progress "Logs in %s@." (Config.results_dir ^/ Config.log_file) ; L.progress "Execution ID %Ld@." Config.execution_id ) ; - ( if Config.test_determinator then TestDeterminator.compute_and_emit_test_to_run () + ( if Config.test_determinator && not Config.process_clang_ast then + TestDeterminator.compute_and_emit_test_to_run () else match Config.command with | Analyze -> diff --git a/infer/tests/build_systems/buck_export_changed_functions/Makefile b/infer/tests/build_systems/buck_export_changed_functions/Makefile index f1e06fc8e..1c283581d 100644 --- a/infer/tests/build_systems/buck_export_changed_functions/Makefile +++ b/infer/tests/build_systems/buck_export_changed_functions/Makefile @@ -11,7 +11,7 @@ B_CPP = src/b.cpp BUCK_TARGET = //src:test TEST_DETERMINATOR_RESULT = infer-out/changed_functions.json DIFF_OUTPUT = diff.mod.test -INFER_OPTIONS = --flavors --linters --no-capture --export-changed-functions --modified-lines $(DIFF_OUTPUT) --project-root $(TESTS_DIR) +INFER_OPTIONS = --flavors --process-clang-ast --no-linters --no-capture --export-changed-functions --modified-lines $(DIFF_OUTPUT) --project-root $(TESTS_DIR) $(DIFF_OUTPUT): $(QUIET)echo -n '$(A_CPP):' > diff.mod.test diff --git a/infer/tests/build_systems/clang_test_determinator/Makefile b/infer/tests/build_systems/clang_test_determinator/Makefile new file mode 100644 index 000000000..6bb366d98 --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/Makefile @@ -0,0 +1,47 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# E2E test involving the test_determinator feature + +TESTS_DIR = ../.. +include $(TESTS_DIR)/base.make + +A_CPP = A.cpp +TEST_DETERMINATOR_RESULT = infer-out-mod2/diff_determinator.json +DIFF_OUTPUT = diff.mod2.test +INFER_OPTIONS = --test-determinator --process-clang-ast --no-linters --no-capture + +default: $(TEST_DETERMINATOR_RESULT) + +$(DIFF_OUTPUT): + $(QUIET)echo -n '$(A_CPP):' > diff.mod1.test + $(QUIET)(diff -N --unchanged-line-format="U" --old-line-format="O" --new-line-format="N" \ + orig-$(A_CPP) mod1-$(A_CPP) || [ $$? = 1 ]) >> diff.mod1.test + $(QUIET)echo -n '$(A_CPP):' > diff.mod2.test + $(QUIET)(diff -N --unchanged-line-format="U" --old-line-format="O" --new-line-format="N" \ + orig-$(A_CPP) mod2-$(A_CPP) || [ $$? = 1 ]) >> diff.mod2.test + +$(TEST_DETERMINATOR_RESULT): $(DIFF_OUTPUT) + $(QUIET)$(call silent_on_success,Testing clang test-determinator with set of changes in mod1,\ + cp mod1-$(A_CPP) $(A_CPP);\ + $(INFER_BIN) -o infer-out-mod1 $(INFER_OPTIONS) --profiler-samples profiler_samples.json --modified-lines diff.mod1.test -- clang -c $(A_CPP)) + $(QUIET)$(call silent_on_success,Testing test-determinator-clang with set of changes in mod2,\ + cp mod2-$(A_CPP) $(A_CPP);\ + $(INFER_BIN) -o infer-out-mod2 $(INFER_OPTIONS) --profiler-samples profiler_samples.json --modified-lines diff.mod2.test -- clang -c $(A_CPP)) + $(QUIET) rm $(A_CPP) + +.PHONY: test +test: $(TEST_DETERMINATOR_RESULT) + $(QUIET)$(call check_no_diff,test_determinator.json.mod1.exp,infer-out-mod1/test_determinator.json) + $(QUIET)$(call check_no_diff,test_determinator.json.mod2.exp,infer-out-mod2/test_determinator.json) + +.PHONY: replace +replace: $(TEST_DETERMINATOR_RESULT) + $(COPY) infer-out-mod1/test_determinator.json test_determinator.json.mod1.exp + $(COPY) infer-out-mod2/test_determinator.json test_determinator.json.mod2.exp + +.PHONY: clean +clean: + $(REMOVE_DIR) *.test infer-out-mod* *.o diff --git a/infer/tests/build_systems/clang_test_determinator/mod1-A.cpp b/infer/tests/build_systems/clang_test_determinator/mod1-A.cpp new file mode 100644 index 000000000..4177d5de0 --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/mod1-A.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +int example_function1() { return 111; } + +int example_function2() { return 2; } + +namespace Shapes { + +class Cube { + int size; + + public: + void set_size(int); + int area() { return size * size * size; }; + void sort(Cube*, unsigned); +}; + +void Cube::set_size(int s) { size = s; } + +void Cube::sort(Cube* xs, unsigned n) { + std::sort(xs, xs + n, [](Cube a, Cube b) { return (a.area() > b.area()); }); +} +} // namespace Shapes diff --git a/infer/tests/build_systems/clang_test_determinator/mod2-A.cpp b/infer/tests/build_systems/clang_test_determinator/mod2-A.cpp new file mode 100644 index 000000000..0ded1e827 --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/mod2-A.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +int example_function1() { return 1; } + +int example_function2() { return 222; } + +namespace Shapes { + +class Cube { + int size; + + public: + void set_size(int); + int area() { return size * size; }; + void sort(Cube*, unsigned); +}; + +void Cube::set_size(int s) { size = s; } + +void Cube::sort(Cube* xs, unsigned n) { + // this is a lambda folks + std::sort(xs, xs + n, [](Cube a, Cube b) { return (a.area() < b.area()); }); +} +} // namespace Shapes diff --git a/infer/tests/build_systems/clang_test_determinator/orig-A.cpp b/infer/tests/build_systems/clang_test_determinator/orig-A.cpp new file mode 100644 index 000000000..d7f9a599a --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/orig-A.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +int example_function1() { return 1; } + +int example_function2() { return 2; } + +namespace Shapes { + +class Cube { + int size; + + public: + void set_size(int); + int area() { return size * size; }; + void sort(Cube*, unsigned); +}; + +void Cube::set_size(int s) { size = s; } + +void Cube::sort(Cube* xs, unsigned n) { + std::sort(xs, xs + n, [](Cube a, Cube b) { return (a.area() < b.area()); }); +} +} // namespace Shapes diff --git a/infer/tests/build_systems/clang_test_determinator/profiler_samples.json b/infer/tests/build_systems/clang_test_determinator/profiler_samples.json new file mode 100644 index 000000000..6e5eb8373 --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/profiler_samples.json @@ -0,0 +1,35 @@ +[ + { + "field1": {}, + "test": "label1", + "field2": {}, + "native_symbols": [ + { + "name": "example_function1" + }, + { + "name": "example_function10", + "mangled_name" : "example_function10" + } + ], + "field3": {} + }, + { + "field1": {}, + "field2": {}, + "field3": {}, + "test": "label2", + "field4": {}, + "native_symbols": [ + { + "name": "example_function2" + }, + { + "name": "example_function20", + "mangled_name" : "example_function20" + } + ], + "field5": {}, + "field6": {} + } + ] diff --git a/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod1.exp b/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod1.exp new file mode 100644 index 000000000..262097c58 --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod1.exp @@ -0,0 +1 @@ +["label1"] \ No newline at end of file diff --git a/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod2.exp b/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod2.exp new file mode 100644 index 000000000..1b7164c2e --- /dev/null +++ b/infer/tests/build_systems/clang_test_determinator/test_determinator.json.mod2.exp @@ -0,0 +1 @@ +["label2"] \ No newline at end of file diff --git a/infer/tests/build_systems/export_changed_functions/Makefile b/infer/tests/build_systems/export_changed_functions/Makefile index 550d290b3..570eae78b 100644 --- a/infer/tests/build_systems/export_changed_functions/Makefile +++ b/infer/tests/build_systems/export_changed_functions/Makefile @@ -11,7 +11,7 @@ include $(TESTS_DIR)/base.make A_CPP = A.cpp TEST_DETERMINATOR_RESULT = infer-out-mod2/diff_determinator.json DIFF_OUTPUT = diff.mod2.test -INFER_OPTIONS = --export-changed-functions --linters --no-capture --buck-compilation-database 'no-deps' +INFER_OPTIONS = --export-changed-functions --process-clang-ast --no-linters --no-capture --buck-compilation-database 'no-deps' default: $(TEST_DETERMINATOR_RESULT)