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