diff --git a/Makefile b/Makefile index 6e3b1acbf..6418ab78c 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ endif ifeq ($(BUILD_C_ANALYZERS),yes) BUILD_SYSTEMS_TESTS += \ assembly \ + backtrack_level \ ck_analytics ck_imports \ clang_compilation_db_escaped clang_compilation_db_relpath \ clang_multiple_files \ diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 9685336f7..2ce393a21 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1854,7 +1854,7 @@ and reactive_capture = and reanalyze = CLOpt.mk_bool ~long:"reanalyze" "Rerun the analysis" -and relative_path_backtack = +and relative_path_backtrack = CLOpt.mk_int ~long:"backtrack-level" ~default:0 ~meta:"int" "Maximum level of backtracking to convert an absolute path to path relative to the common \ prefix between the project root and the path. For instance, with bactraking level 1, it will \ @@ -2875,7 +2875,7 @@ and reactive_capture = !reactive_capture and reanalyze = !reanalyze -and relative_path_backtack = !relative_path_backtack +and relative_path_backtrack = !relative_path_backtrack and report = !report diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index eb805e08f..5e6f43d6b 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -157,7 +157,7 @@ val property_attributes : string val racerd_issues_dir_name : string -val relative_path_backtack : int +val relative_path_backtrack : int val report : bool diff --git a/infer/src/base/SourceFile.ml b/infer/src/base/SourceFile.ml index 7d99e21c5..243a606c6 100644 --- a/infer/src/base/SourceFile.ml +++ b/infer/src/base/SourceFile.ml @@ -51,7 +51,7 @@ let from_abs_path ?(warn_on_error = true) fname = let project_root_real = Utils.realpath ~warn_on_error Config.project_root in let models_dir_real = Config.models_src_dir in match - Utils.filename_to_relative ~backtrack:Config.relative_path_backtack ~root:project_root_real + Utils.filename_to_relative ~backtrack:Config.relative_path_backtrack ~root:project_root_real fname_real with | Some path -> diff --git a/infer/src/base/Utils.ml b/infer/src/base/Utils.ml index 65e0f38ef..96184aad9 100644 --- a/infer/src/base/Utils.ml +++ b/infer/src/base/Utils.ml @@ -96,20 +96,21 @@ let filename_to_absolute ~root fname = (** Convert an absolute filename to one relative to the given directory. *) let filename_to_relative ?(backtrack = 0) ~root fname = - let rec relativize_if_under prefix backtrack origin target = + let rec relativize_if_under origin target = match (origin, target) with | x :: xs, y :: ys when String.equal x y -> - relativize_if_under prefix backtrack xs ys - | _ :: xs, y :: ys when backtrack > 0 -> - relativize_if_under (Filename.parent_dir_name :: y :: prefix) (backtrack - 1) xs ys + relativize_if_under xs ys + | _ :: _, _ when backtrack >= List.length origin -> + let parent_dir = List.init (List.length origin) ~f:(fun _ -> Filename.parent_dir_name) in + Some (Filename.of_parts (parent_dir @ target)) | [], [] -> Some "." | [], ys -> - Some (Filename.of_parts (prefix @ ys)) + Some (Filename.of_parts ys) | _ -> None in - relativize_if_under [] backtrack (Filename.parts root) (Filename.parts fname) + relativize_if_under (Filename.parts root) (Filename.parts fname) let directory_fold f init path = diff --git a/infer/tests/build_systems/backtrack_level/Makefile b/infer/tests/build_systems/backtrack_level/Makefile new file mode 100644 index 000000000..c304fb60a --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/Makefile @@ -0,0 +1,50 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +ROOT_DIR = ../../../.. + +include $(ROOT_DIR)/Makefile.config + +LEVEL1_DIR = level1 +LEVEL2_DIR = $(LEVEL1_DIR)/level2 +LEVEL3_DIR = $(LEVEL2_DIR)/level3 + +LEVELS = LEVEL1 LEVEL2 LEVEL3 +TESTS = $(LEVELS:%=%_TEST) +PRINTS = $(LEVELS:%=%_PRINT) +CLEANS = $(LEVELS:%=%_CLEAN) +REPLACES = $(LEVELS:%=%_REPLACE) + +.PHONY: default +default: print + +.PHONY: $(TESTS) +$(TESTS): %_TEST: + $(QUIET)$(MAKE) -C $($*_DIR) test + +.PHONY: test +test: $(TESTS) + +.PHONY: $(PRINTS) +$(PRINTS): %_PRINT: + $(QUIET)$(MAKE) -C $($*_DIR) print + +.PHONY: print +print: $(PRINTS) + +.PHONY: $(CLEANS) +$(CLEANS): %_CLEAN: + $(QUIET)$(MAKE) -C $($*_DIR) clean + $(QUIET)$(REMOVE) $($*_DIR)/*.o + +.PHONY: clean +clean: $(CLEANS) + +.PHONY: $(REPLACES) +$(REPLACES): %_REPLACE: + $(QUIET)$(MAKE) -C $($*_DIR) replace + +.PHONY: replace +replace: $(REPLACES) diff --git a/infer/tests/build_systems/backtrack_level/backtrack_level.make b/infer/tests/build_systems/backtrack_level/backtrack_level.make new file mode 100644 index 000000000..dc4be181f --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/backtrack_level.make @@ -0,0 +1,12 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +CLANG_OPTIONS = -c +INFER_OPTIONS = --backtrack-level $(BACKTRACK_LEVEL) +INFERPRINT_OPTIONS = --issues-tests + +SOURCES = $(TESTS_DIR)/build_systems/backtrack_level/hello.c + +include $(TESTS_DIR)/clang.make diff --git a/infer/tests/build_systems/backtrack_level/hello.c b/infer/tests/build_systems/backtrack_level/hello.c new file mode 100644 index 000000000..d1dd780a4 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/hello.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +void test() { + int* s = NULL; + *s = 42; +} diff --git a/infer/tests/build_systems/backtrack_level/level1/Makefile b/infer/tests/build_systems/backtrack_level/level1/Makefile new file mode 100644 index 000000000..1bafe81b0 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/Makefile @@ -0,0 +1,9 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../../.. +BACKTRACK_LEVEL = 1 + +include $(TESTS_DIR)/build_systems/backtrack_level/backtrack_level.make diff --git a/infer/tests/build_systems/backtrack_level/level1/issues.exp b/infer/tests/build_systems/backtrack_level/level1/issues.exp new file mode 100644 index 000000000..0761235d0 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/issues.exp @@ -0,0 +1 @@ +../hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()] diff --git a/infer/tests/build_systems/backtrack_level/level1/level2/Makefile b/infer/tests/build_systems/backtrack_level/level1/level2/Makefile new file mode 100644 index 000000000..9e927467e --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/level2/Makefile @@ -0,0 +1,9 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../../../.. +BACKTRACK_LEVEL = 2 + +include $(TESTS_DIR)/build_systems/backtrack_level/backtrack_level.make diff --git a/infer/tests/build_systems/backtrack_level/level1/level2/issues.exp b/infer/tests/build_systems/backtrack_level/level1/level2/issues.exp new file mode 100644 index 000000000..fb38c0163 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/level2/issues.exp @@ -0,0 +1 @@ +../../hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()] diff --git a/infer/tests/build_systems/backtrack_level/level1/level2/level3/Makefile b/infer/tests/build_systems/backtrack_level/level1/level2/level3/Makefile new file mode 100644 index 000000000..1eb472d63 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/level2/level3/Makefile @@ -0,0 +1,9 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../../../../.. +BACKTRACK_LEVEL = 3 + +include $(TESTS_DIR)/build_systems/backtrack_level/backtrack_level.make diff --git a/infer/tests/build_systems/backtrack_level/level1/level2/level3/issues.exp b/infer/tests/build_systems/backtrack_level/level1/level2/level3/issues.exp new file mode 100644 index 000000000..d342b3f62 --- /dev/null +++ b/infer/tests/build_systems/backtrack_level/level1/level2/level3/issues.exp @@ -0,0 +1 @@ +../../../hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()]