Summary: First steps towards implementing diff analysis functionalities inside infer itself. What works: run infer, checkout parent, re-run infer, checkout top revision, compute the reportdiff (but no final surfacing on the console). Lots of TODO still, inlined in the code. Reviewed By: jberdine Differential Revision: D5364226 fbshipit-source-id: 5b7f9a5master
parent
b0c2cfd7d4
commit
d07c8a0403
@ -0,0 +1,65 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
module F = Format
|
||||||
|
module L = Logging
|
||||||
|
|
||||||
|
type revision = Current | Previous
|
||||||
|
|
||||||
|
let string_of_revision = function Current -> "current" | Previous -> "previous"
|
||||||
|
|
||||||
|
let pp_revision f r = F.fprintf f "%s" (string_of_revision r)
|
||||||
|
|
||||||
|
let checkout revision =
|
||||||
|
let script_opt =
|
||||||
|
match revision with
|
||||||
|
| Current
|
||||||
|
-> Config.previous_to_current_script
|
||||||
|
| Previous
|
||||||
|
-> Config.current_to_previous_script
|
||||||
|
in
|
||||||
|
match script_opt with
|
||||||
|
| None
|
||||||
|
-> L.(die UserError)
|
||||||
|
"Please specify a script to checkout the %a revision of your project using --checkout-%a <script>."
|
||||||
|
pp_revision revision pp_revision revision
|
||||||
|
| Some script
|
||||||
|
-> L.progress "Checking out %a version:@\n %s@\n" pp_revision revision script ;
|
||||||
|
let (), exit_or_signal = Utils.with_process_in script Utils.consume_in in
|
||||||
|
Result.iter_error exit_or_signal ~f:(fun _ ->
|
||||||
|
L.(die ExternalError)
|
||||||
|
"Failed to checkout %a revision: %s" pp_revision revision
|
||||||
|
(Unix.Exit_or_signal.to_string_hum exit_or_signal) )
|
||||||
|
|
||||||
|
let save_report revision =
|
||||||
|
let report_name = Config.results_dir ^/ F.asprintf "report-%a.json" pp_revision revision in
|
||||||
|
Unix.rename ~src:Config.(results_dir ^/ report_json) ~dst:report_name ;
|
||||||
|
L.progress "Results for the %a revision stored in %s@\n" pp_revision revision report_name ;
|
||||||
|
report_name
|
||||||
|
|
||||||
|
let diff driver_mode =
|
||||||
|
(* TODO(t15553258) run gen-build script if specified *)
|
||||||
|
(* run capture *)
|
||||||
|
Driver.capture driver_mode ~changed_files:None ;
|
||||||
|
(* run analysis TODO(t15553258) add --reactive and --changed_files_index *)
|
||||||
|
Driver.analyze_and_report driver_mode ~changed_files:None ;
|
||||||
|
let current_report = Some (save_report Current) in
|
||||||
|
(* TODO(t15553258) bail if nothing to analyze (configurable, some people might care about bugs
|
||||||
|
fixed more than about time to analyze) *)
|
||||||
|
checkout Previous ;
|
||||||
|
(* TODO(t15553258) run gen-build script if specified *)
|
||||||
|
(* run capture TODO(t15553258) add --reactive and --continue *)
|
||||||
|
Driver.capture driver_mode ~changed_files:None ;
|
||||||
|
(* run analysis TODO(t15553258) add --reactive and --changed_files_index *)
|
||||||
|
Driver.analyze_and_report driver_mode ~changed_files:None ;
|
||||||
|
checkout Current ;
|
||||||
|
let previous_report = Some (save_report Previous) in
|
||||||
|
(* compute differential *)
|
||||||
|
ReportDiff.reportdiff ~current_report ~previous_report ; (* TODO(t15553258) report new bugs! *)
|
||||||
|
()
|
@ -0,0 +1,13 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
val diff : Driver.mode -> unit
|
||||||
|
(** orchestrates the analysis of a code change *)
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void test1() {
|
||||||
|
int* s1 = NULL;
|
||||||
|
*s1 = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2() {
|
||||||
|
int* s2 = NULL;
|
||||||
|
*s2 = 42;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void test1() {
|
||||||
|
int* s1 = NULL;
|
||||||
|
*s1 = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3() {
|
||||||
|
int* s3 = malloc(1);
|
||||||
|
if (s3 != NULL) {
|
||||||
|
*s3 = 42;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
# Copyright (c) 2017 - present Facebook, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the BSD style license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
# of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
TESTS_DIR = ../..
|
||||||
|
|
||||||
|
include $(TESTS_DIR)/base.make
|
||||||
|
|
||||||
|
SRC_DIR = $(CURDIR)/../codetoanalyze
|
||||||
|
INFER_OUT = infer-out
|
||||||
|
INFER_OPTIONS = \
|
||||||
|
--previous-to-current-script '$(COPY) $(SRC_DIR)/some_bugs.c src/hello.c' \
|
||||||
|
--current-to-previous-script '$(COPY) $(SRC_DIR)/some_different_bugs.c src/hello.c' \
|
||||||
|
--report-hook '/bin/true' \
|
||||||
|
-- clang -c src/hello.c
|
||||||
|
|
||||||
|
SOURCES = $(SRC_DIR)/some_bugs.c $(SRC_DIR)/some_different_bugs.c
|
||||||
|
|
||||||
|
default: analyze
|
||||||
|
|
||||||
|
.PHONY: analyze
|
||||||
|
analyze: $(INFER_OUT)/differential/introduced.json
|
||||||
|
|
||||||
|
$(INFER_OUT)/differential/introduced.json: $(SOURCES) $(CLANG_DEPS)
|
||||||
|
$(QUIET)$(MKDIR_P) src
|
||||||
|
$(QUIET)$(COPY) $(SRC_DIR)/some_bugs.c src/hello.c
|
||||||
|
$(QUIET)$(call silent_on_success,Running diff analysis in $(TEST_REL_DIR),\
|
||||||
|
$(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) diff \
|
||||||
|
$(INFER_OPTIONS))
|
||||||
|
|
||||||
|
introduced.exp.test: $(INFER_OUT)/differential/introduced.json $(INFER_BIN)
|
||||||
|
$(QUIET)$(INFER_BIN) report \
|
||||||
|
--from-json-report $(INFER_OUT)/differential/introduced.json \
|
||||||
|
--issues-tests introduced.exp.test
|
||||||
|
$(QUIET)$(INFER_BIN) report \
|
||||||
|
--from-json-report $(INFER_OUT)/differential/fixed.json \
|
||||||
|
--issues-tests fixed.exp.test
|
||||||
|
$(QUIET)$(INFER_BIN) report \
|
||||||
|
--from-json-report $(INFER_OUT)/differential/preexisting.json \
|
||||||
|
--issues-tests preexisting.exp.test
|
||||||
|
|
||||||
|
.PHONY: print
|
||||||
|
print: introduced.exp.test
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: print
|
||||||
|
$(QUIET)$(call check_no_diff,introduced.exp,introduced.exp.test)
|
||||||
|
$(QUIET)$(call check_no_diff,fixed.exp,fixed.exp.test)
|
||||||
|
$(QUIET)$(call check_no_diff,preexisting.exp,preexisting.exp.test)
|
||||||
|
|
||||||
|
.PHONY: replace
|
||||||
|
replace: $(EXPECTED_TEST_OUTPUT)
|
||||||
|
$(COPY) introduced.exp.test introduced.exp
|
||||||
|
$(COPY) fixed.exp.test fixed.exp
|
||||||
|
$(COPY) preexisting.exp.test preexisting.exp
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
$(REMOVE_DIR) *.exp.test $(INFER_OUT) $(CURRENT_DIR) $(PREVIOUS_DIR) \
|
||||||
|
$(CLEAN_EXTRA)
|
@ -0,0 +1 @@
|
|||||||
|
src/hello.c, test3, 3, MEMORY_LEAK, [start of procedure test3(),Condition is true]
|
@ -0,0 +1 @@
|
|||||||
|
src/hello.c, test2, 2, NULL_DEREFERENCE, [start of procedure test2()]
|
@ -0,0 +1 @@
|
|||||||
|
src/hello.c, test1, 2, NULL_DEREFERENCE, [start of procedure test1()]
|
Loading…
Reference in new issue