From 25f2293e709c4e2703b37152b643e701a9df26a7 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 20 Nov 2019 08:37:19 -0800 Subject: [PATCH] [test determinator] Add the hash function that we use in the plugin to hash the mangled names to compare input mangled names Reviewed By: dulmarod Differential Revision: D17602494 fbshipit-source-id: ad704cf19 --- Makefile | 4 +++- infer/bin/infer.byte | 11 +++++++++++ infer/src/Makefile | 8 +++++++- infer/src/c_stubs/Fnv64Hash.ml | 8 ++++++++ infer/src/c_stubs/InferCStubs.opam | 0 infer/src/c_stubs/dune | 18 +++++++++++++++++ infer/src/c_stubs/dune-project | 2 ++ infer/src/c_stubs/fnv64_hash.c | 31 ++++++++++++++++++++++++++++++ infer/src/deadcode/Makefile | 8 ++++---- infer/src/dune.in | 6 ++++-- infer/src/unit/CStubsTests.ml | 26 +++++++++++++++++++++++++ infer/src/unit/inferunit.ml | 1 + scripts/dune_exec_shim.sh | 25 ++++++++++++++++++++++++ scripts/infer_repl | 2 +- 14 files changed, 141 insertions(+), 9 deletions(-) create mode 100755 infer/bin/infer.byte create mode 100644 infer/src/c_stubs/Fnv64Hash.ml create mode 100644 infer/src/c_stubs/InferCStubs.opam create mode 100644 infer/src/c_stubs/dune create mode 100644 infer/src/c_stubs/dune-project create mode 100644 infer/src/c_stubs/fnv64_hash.c create mode 100644 infer/src/unit/CStubsTests.ml create mode 100755 scripts/dune_exec_shim.sh diff --git a/Makefile b/Makefile index b9e275608..62fbbf307 100644 --- a/Makefile +++ b/Makefile @@ -419,7 +419,9 @@ clang_plugin_test_replace: clang_setup ocaml_unit_test: test_build $(QUIET)$(REMOVE_DIR) infer-out-unit-tests $(QUIET)$(call silent_on_success,Running OCaml unit tests,\ - INFER_ARGS=--results-dir^infer-out-unit-tests $(BUILD_DIR)/test/inferunit.bc) + INFER_ARGS=--results-dir^infer-out-unit-tests \ + BUILD_DIR=$(BUILD_DIR)/test \ + $(SCRIPT_DIR)/dune_exec_shim.sh $(BUILD_DIR)/test/inferunit.bc) define silence_make $(1) 2> >(grep -v 'warning: \(ignoring old\|overriding\) \(commands\|recipe\) for target') diff --git a/infer/bin/infer.byte b/infer/bin/infer.byte new file mode 100755 index 000000000..2efdd3bdb --- /dev/null +++ b/infer/bin/infer.byte @@ -0,0 +1,11 @@ +#!/bin/bash +# 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. + +## Wrapper around the bytecode version of infer produced by `make byte` +# This is needed to find the dynamic libraries of our C stubs + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +exec "$SCRIPT_DIR"/../../scripts/dune_exec_shim.sh "${0%.byte}.bc" "$@" diff --git a/infer/src/Makefile b/infer/src/Makefile index f6dd52d83..55b287700 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -112,6 +112,8 @@ $(INFER_BUILD_DIR)/$(INFER_MAIN).exe: $(SRC_BUILD_COMMON) $(MAKEFILE_LIST) .PHONY: test test: $(SRC_BUILD_COMMON) $(MAKEFILE_LIST) +# needed for dune to "install" the relevant dynamic libraries for the C stubs + $(QUIET)cd c_stubs; dune build InferCStubs.install $(QUIET)dune build \ $(patsubst $(INFER_BUILD_DIR)/%.exe,_build/test/%.bc,$(INFER_CONFIG_TARGETS)) \ _build/test/scripts/checkCopyright.bc _build/test/$(INFERUNIT_MAIN).bc _build/test/infertop.bc @@ -160,10 +162,12 @@ ifeq ($(IS_FACEBOOK_TREE),yes) $(INSTALL_PROGRAM) -C $(INFER_BUILD_DIR)/$(INFER_CREATE_TRACEVIEW_LINKS_MAIN).bc \ $(INFER_CREATE_TRACEVIEW_LINKS_BIN) endif +# needed for dune to "install" the relevant dynamic libraries for the C stubs + cd c_stubs; dune build InferCStubs.install .PHONY: byte byte: $(INFER_BIN).bc - $(INSTALL_PROGRAM) -C $(INFER_BIN).bc $(INFER_BIN) + $(INSTALL_PROGRAM) -C $(INFER_BIN).byte $(INFER_BIN) $(MAKE) $(INFER_BIN_ALIASES) roots:=Infer @@ -193,6 +197,8 @@ dsort: $(INFER_BUILD_DIR)/infertop.bc: $(SRC_DIR)/infertop.ml $(SRC_BUILD_COMMON) $(MAKEFILE_LIST) dune build $@ +# needed for dune to "install" the relevant dynamic libraries for the C stubs + cd c_stubs; dune build InferCStubs.install $(QUIET)touch $@ $(INFERTOP_BIN): $(INFER_BUILD_DIR)/infertop.bc diff --git a/infer/src/c_stubs/Fnv64Hash.ml b/infer/src/c_stubs/Fnv64Hash.ml new file mode 100644 index 000000000..8ba5ff88c --- /dev/null +++ b/infer/src/c_stubs/Fnv64Hash.ml @@ -0,0 +1,8 @@ +(* + * 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. + *) + +external fnv64_hash : string -> string = "fnv64_hash" diff --git a/infer/src/c_stubs/InferCStubs.opam b/infer/src/c_stubs/InferCStubs.opam new file mode 100644 index 000000000..e69de29bb diff --git a/infer/src/c_stubs/dune b/infer/src/c_stubs/dune new file mode 100644 index 000000000..4e363f6f3 --- /dev/null +++ b/infer/src/c_stubs/dune @@ -0,0 +1,18 @@ +(* -*- tuareg -*- *) +(* + * 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. + *) + +;; +Format.sprintf + {| +(library + (name InferCStubs) + (public_name InferCStubs) + (c_names fnv64_hash) +) +|} +|> Jbuild_plugin.V1.send diff --git a/infer/src/c_stubs/dune-project b/infer/src/c_stubs/dune-project new file mode 100644 index 000000000..4fd7479b2 --- /dev/null +++ b/infer/src/c_stubs/dune-project @@ -0,0 +1,2 @@ +(lang dune 1.10) +(name CStubs) diff --git a/infer/src/c_stubs/fnv64_hash.c b/infer/src/c_stubs/fnv64_hash.c new file mode 100644 index 000000000..90638b982 --- /dev/null +++ b/infer/src/c_stubs/fnv64_hash.c @@ -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 +#include +#include +#include + +// 64 bits fnv-1a +const uint64_t FNV64_hash_start = 14695981039346656037ULL; +const uint64_t FNV64_prime = 1099511628211ULL; +uint64_t fnv64_hash_impl(const char* s) { + uint64_t hash = FNV64_hash_start; + while (*s != 0) { + hash ^= *s; + hash *= FNV64_prime; + s++; + } + return hash; +} + +CAMLprim value fnv64_hash(value c) { + char* c_string = String_val(c); + uint64_t hashed = fnv64_hash_impl(c_string); + char str[21]; + snprintf(str, 21, "%" PRIu64, hashed); + return caml_copy_string(str); +} diff --git a/infer/src/deadcode/Makefile b/infer/src/deadcode/Makefile index 79bbdf6d8..9e42bff04 100644 --- a/infer/src/deadcode/Makefile +++ b/infer/src/deadcode/Makefile @@ -34,18 +34,18 @@ ALL_INFER_IN_ONE_FILE_ML = all_infer_in_one_file.ml default: detect_dead_code -ml_src_files_from_mlly:=$(shell find .. -not -path "../*stubs*" -regex '\.\./[a-zA-Z].*\.ml[ly]') +ml_src_files_from_mlly:=$(shell find .. -not -path "../*clang_stubs/*" -not -path "../*java_stubs/*" -not -path "../_build/*" -regex '\.\./[a-zA-Z].*\.ml[ly]') -ml_src_files:=$(shell cd .. && find . -not -path "./*stubs*" -regex '\./[a-zA-Z].*\.mli*') +ml_src_files:=$(shell find .. -not -path "../*clang_stubs/*" -not -path "../*java_stubs/*" -not -path "../_build/*" -regex '\.\./[a-zA-Z].*\.mli') -ml_src_files_without_mli:=$(shell cd .. && for i in $$(find . -not -path "./*stubs*" -regex '\./[a-zA-Z].*\.ml'); do [ -f $${i}i ] || echo $$i; done) +ml_src_files_without_mli:=$(shell cd .. && for i in $$(find . -not -path "../*clang_stubs/*" -not -path "../*java_stubs/*" -not -path "../_build/*" -regex '\./[a-zA-Z].*\.ml'); do [ -f $${i}i ] || echo $$i; done) .PHONY: depend depend: cd .. && \ ocamldep -native \ -I IR -I absint -I al -I atd -I backend -I base -I biabduction -I bufferoverrun \ - -I checkers -I clang -I concurrency -I facebook -I integration -I istd -I java \ + -I c_stubs -I checkers -I clang -I concurrency -I facebook -I integration -I istd -I java \ -I labs -I nullsafe -I pulse -I scuba -I quandary -I topl -I unit -I unit/clang -I unit/nullsafe -I deadcode \ -I test_determinator \ $(ml_src_files) > deadcode/.depend diff --git a/infer/src/dune.in b/infer/src/dune.in index b1c9e3928..6b295132a 100644 --- a/infer/src/dune.in +++ b/infer/src/dune.in @@ -47,7 +47,9 @@ let infer_cflags = ; "-open" ; "InferIR" ; "-open" - ; "InferBase" ] + ; "InferBase" + ; "-open" + ; "InferCStubs" ] (** The build stanzas to be passed to dune *) @@ -75,7 +77,7 @@ let stanzas = |} (String.concat " " infer_cflags) (String.concat " " common_optflags) - (String.concat " " ("InferIR" :: common_libraries)) + (String.concat " " ("InferCStubs" :: "InferIR" :: common_libraries)) (String.concat " " infer_binaries) ; Format.sprintf {| diff --git a/infer/src/unit/CStubsTests.ml b/infer/src/unit/CStubsTests.ml new file mode 100644 index 000000000..41781b327 --- /dev/null +++ b/infer/src/unit/CStubsTests.ml @@ -0,0 +1,26 @@ +(* + * 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. + *) + +open! IStd +open OUnit2 + +let pp_diff_of_hashed_value fmt (expected, actual) = + Format.fprintf fmt "Expected: [%s] Found: [%s]" expected actual + + +let test_fnv64_hash_function = + let create_test (input : string) (hashed_input : string) _ = + let actual_hashed_value = Fnv64Hash.fnv64_hash input in + let cmp s1 s2 = String.equal s1 s2 in + assert_equal ~pp_diff:pp_diff_of_hashed_value ~cmp hashed_input actual_hashed_value + in + [("test_correct_hash", "_Z4testv", "18241244337164948030")] + |> List.map ~f:(fun (name, test_input, expected_output) -> + name >:: create_test test_input expected_output ) + + +let tests = "fnv64_hash_function_suite" >::: test_fnv64_hash_function diff --git a/infer/src/unit/inferunit.ml b/infer/src/unit/inferunit.ml index 2e4ae5610..5f951d19e 100644 --- a/infer/src/unit/inferunit.ml +++ b/infer/src/unit/inferunit.ml @@ -30,6 +30,7 @@ let () = ; AccessPathTests.tests ; AccessTreeTests.tests ; AddressTakenTests.tests + ; CStubsTests.tests ; DifferentialFiltersTests.tests ; DifferentialTests.tests ; FileDiffTests.tests diff --git a/scripts/dune_exec_shim.sh b/scripts/dune_exec_shim.sh new file mode 100755 index 000000000..de2c804d7 --- /dev/null +++ b/scripts/dune_exec_shim.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# 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. + +## Wrapper around the bytecode versions of infer +# This is needed to find the dynamic libraries of our C stubs + +if [ "$#" -lt 1 ]; then + echo "usage: $0 BYTECODE_PROGRAM" >&2 + exit 1 +fi + +prog=$1 +shift + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SRC_DIR="$SCRIPT_DIR"/../infer/src +BUILD_MODE=${BUILD_MODE:-default} +DUNE_INSTALL_DIR=${INSTALL_DIR:-"$SRC_DIR/_build/install/$BUILD_MODE"} + +export CAML_LD_LIBRARY_PATH="$DUNE_INSTALL_DIR"/lib/stublibs:"$CAML_LD_LIBRARY_PATH" + +exec "$prog" "$@" diff --git a/scripts/infer_repl b/scripts/infer_repl index 758322312..f91266588 100755 --- a/scripts/infer_repl +++ b/scripts/infer_repl @@ -17,7 +17,7 @@ INCLUDE_FLAGS=$(find "$BUILD_DIR" -type d -name '*.objs' -exec printf -- '-I {}/ # file. In interactive mode $SCRIPT_DIR isn't needed set -x -"$SCRIPT_DIR"/../infer/bin/infertop.bc \ +"$SCRIPT_DIR"/dune_exec_shim.sh infertop.bc \ -init "$SCRIPT_DIR"/toplevel_init \ $INCLUDE_FLAGS \ -I "$SCRIPT_DIR" \