diff --git a/.gitignore b/.gitignore index 9c31b154a..8850f866a 100644 --- a/.gitignore +++ b/.gitignore @@ -163,6 +163,8 @@ infer/src/.project /infer/dune-workspace /infer/src/dune.common /infer/src/dune +/infer/src/al/dune +/infer/src/clang/dune /infer/src/java/dune /infer/src/opensource/dune .merlin diff --git a/infer/src/Makefile b/infer/src/Makefile index 938761e30..c0de58c74 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -76,7 +76,7 @@ GENERATED_FROM_AUTOCONF = dune.common ../dune-workspace base/Version.ml .PHONY: dune-workspace dune-workspace: ../dune-workspace -GENERATED_DUNES += dune java/dune opensource/dune +GENERATED_DUNES += dune al/dune clang/dune java/dune opensource/dune SRC_BUILD_COMMON = $(GENERATED_FROM_AUTOCONF) $(GENERATED_DUNES) $(OCAML_SOURCES) ifeq ($(BUILD_C_ANALYZERS),yes) @@ -242,6 +242,8 @@ $(GENERATED_DUNES): dune.common $(QUIET)cat $+ > $@ dune: dune.in +al/dune: al/dune.in +clang/dune: clang/dune.in deadcode/dune: deadcode/dune.in java/dune: java/dune.in opensource/dune: opensource/dune.in diff --git a/infer/src/al/ALIssues.ml b/infer/src/al/ALIssues.ml index f438766c2..1ea81dee6 100644 --- a/infer/src/al/ALIssues.ml +++ b/infer/src/al/ALIssues.ml @@ -485,7 +485,7 @@ let log_frontend_issue method_decl_opt (node : Ctl_parser_types.ast_node) let issue_log', errlog = IssueLog.get_or_add ~proc:procname !issue_log in issue_log := issue_log' ; let err_desc = - Errdesc.explain_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc + Localise.desc_frontend_warning issue_desc.description issue_desc.suggestion issue_desc.loc in let exn = Exceptions.Frontend_warning (issue_desc.issue_type, err_desc, __POS__) in let trace = [Errlog.make_trace_element 0 issue_desc.loc "" []] in diff --git a/infer/src/clang_stubs/CTLParserHelper.ml b/infer/src/al/RegisterCallback.ml similarity index 61% rename from infer/src/clang_stubs/CTLParserHelper.ml rename to infer/src/al/RegisterCallback.ml index e0fbc439b..5e58a0eca 100644 --- a/infer/src/clang_stubs/CTLParserHelper.ml +++ b/infer/src/al/RegisterCallback.ml @@ -7,6 +7,5 @@ open! IStd -let validate_al_files () = - prerr_endline "ERROR: infer was built without clang support." ; - Die.exit 1 +let register_frontend_checks () = + if Config.is_checker_enabled Linters then Capture.al_callback_ref := AL.do_frontend_checks diff --git a/infer/src/clang_stubs/CTLParserHelper.mli b/infer/src/al/RegisterCallback.mli similarity index 67% rename from infer/src/clang_stubs/CTLParserHelper.mli rename to infer/src/al/RegisterCallback.mli index 3cc6c856c..8b850297b 100644 --- a/infer/src/clang_stubs/CTLParserHelper.mli +++ b/infer/src/al/RegisterCallback.mli @@ -7,4 +7,5 @@ open! IStd -val validate_al_files : unit -> (unit, string) Result.t +val register_frontend_checks : unit -> unit +(** call this before running the clang frontend *) diff --git a/infer/src/al/dune.in b/infer/src/al/dune.in new file mode 100644 index 000000000..1b4d275da --- /dev/null +++ b/infer/src/al/dune.in @@ -0,0 +1,31 @@ +(* -*- 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. + *) +(* NOTE: prepend dune.common to this file! *) + +let al = + Printf.sprintf + {|(ocamllex types_lexer ctl_lexer) + +(menhir (modules types_parser ctl_parser)) + +(library + (name ASTLanguage) + (public_name infer.ASTLanguage) + (modules %s) + (flags + (:standard + -open Core -open InferStdlib -open IStd -open OpenSource -open InferGenerated + -open InferBase -open InferIR -open Absint -open ClangFrontend)) + (libraries core InferStdlib InferGenerated InferBase InferIR absint ClangFrontend) + (preprocess (pps ppx_compare)) +)|} + (if clang then ":standard" else "") + + +;; +Jbuild_plugin.V1.send al diff --git a/infer/src/biabduction/errdesc.ml b/infer/src/biabduction/errdesc.ml index a38f616e7..22b7827dd 100644 --- a/infer/src/biabduction/errdesc.ml +++ b/infer/src/biabduction/errdesc.ml @@ -1087,9 +1087,6 @@ let explain_divide_by_zero tenv exp node loc = Localise.no_desc -(** explain a frontend warning *) -let explain_frontend_warning loc = Localise.desc_frontend_warning loc - (** explain a condition which is always true or false *) let explain_condition_always_true_false tenv i cond node loc = let cond_str_opt = diff --git a/infer/src/biabduction/errdesc.mli b/infer/src/biabduction/errdesc.mli index 7a6e7f388..12b94551b 100644 --- a/infer/src/biabduction/errdesc.mli +++ b/infer/src/biabduction/errdesc.mli @@ -85,9 +85,6 @@ val explain_stack_variable_address_escape : Location.t -> Pvar.t -> DecompiledExp.t option -> Localise.error_desc (** explain the escape of a stack variable address from its scope *) -val explain_frontend_warning : string -> string option -> Location.t -> Localise.error_desc -(** explain frontend warning *) - val explain_unary_minus_applied_to_unsigned_expression : Tenv.t -> Exp.t -> Typ.t -> Procdesc.Node.t -> Location.t -> Localise.error_desc (** explain unary minus applied to unsigned expression *) diff --git a/infer/src/clang/Capture.ml b/infer/src/clang/Capture.ml index 840a3694c..1f50ca39a 100644 --- a/infer/src/clang/Capture.ml +++ b/infer/src/clang/Capture.ml @@ -7,6 +7,8 @@ open! IStd module L = Logging +let al_callback_ref = ref (fun _ _ -> ()) + (** enable debug mode (to get more data saved to disk for future inspections) *) let debug_mode = Config.debug_mode || Config.frontend_stats @@ -81,7 +83,8 @@ let run_clang_frontend ast_source = ClangPointers.populate_all_tables ast_decl ; L.(debug Capture Medium) "Start %s the AST of %a@\n" Config.clang_frontend_action_string pp_ast_filename ast_source ; - if Config.is_checker_enabled Linters then AL.do_frontend_checks trans_unit_ctx ast_decl ; + (* run callbacks *) + !al_callback_ref trans_unit_ctx ast_decl ; if Config.process_clang_ast then ProcessAST.process_ast trans_unit_ctx ast_decl ; if Config.capture then CFrontend.do_source_file trans_unit_ctx ast_decl ; L.(debug Capture Medium) @@ -196,4 +199,5 @@ let capture clang_cmd = absolute paths. *) L.(debug Capture Medium) "Running non-cc command without capture: %a@\n" ClangCommand.pp clang_cmd ; - run_clang clang_cmd Utils.echo_in ) + run_clang clang_cmd Utils.echo_in ; + () ) diff --git a/infer/src/clang/Capture.mli b/infer/src/clang/Capture.mli index a4e69c527..c755b3684 100644 --- a/infer/src/clang/Capture.mli +++ b/infer/src/clang/Capture.mli @@ -10,3 +10,7 @@ open! IStd val run_clang : ClangCommand.t -> (In_channel.t -> 'a) -> 'a val capture : ClangCommand.t -> unit + +val al_callback_ref : (CFrontend_config.translation_unit_context -> Clang_ast_t.decl -> unit) ref +(** callback set by AL to avoid circular dependencies between clang/ and al/ without having to + expose the clang-only types involved all the way to integration/ *) diff --git a/infer/src/clang/ClangFrontendStubs.ml b/infer/src/clang/ClangFrontendStubs.ml new file mode 100644 index 000000000..660b72080 --- /dev/null +++ b/infer/src/clang/ClangFrontendStubs.ml @@ -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. + *) + +open! IStd + +let die () = + prerr_endline "ERROR: infer was built without clang support." ; + Die.exit 1 + + +module ClangQuotes = struct + type style = EscapedDoubleQuotes | SingleQuotes | EscapedNoQuotes + + let mk_arg_file _ _ _ = die () +end + +module ClangWrapper = struct + let exe ~prog:_ ~args:_ = () +end + +module CTLParserHelper = struct + let validate_al_files () = die () +end + +module RegisterCallback = struct + let register_frontend_checks () = () +end diff --git a/infer/src/clang/ClangFrontendStubs.mli b/infer/src/clang/ClangFrontendStubs.mli new file mode 100644 index 000000000..6146f7d41 --- /dev/null +++ b/infer/src/clang/ClangFrontendStubs.mli @@ -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. + *) + +open! IStd + +(** ****DO NOT USE DIRECTLY**** + + This module is automatically [open]'d by the build system when compiling infer without clang + support. The stubs implemented here do nothing. *) + +module ClangQuotes : sig + type style = EscapedDoubleQuotes | SingleQuotes | EscapedNoQuotes + + val mk_arg_file : string -> style -> string list -> string +end + +module ClangWrapper : sig + val exe : prog:string -> args:string list -> unit +end + +module CTLParserHelper : sig + val validate_al_files : unit -> (unit, string) Result.t +end + +module RegisterCallback : sig + val register_frontend_checks : unit -> unit +end diff --git a/infer/src/integration/ClangQuotes.ml b/infer/src/clang/ClangQuotes.ml similarity index 100% rename from infer/src/integration/ClangQuotes.ml rename to infer/src/clang/ClangQuotes.ml diff --git a/infer/src/integration/ClangQuotes.mli b/infer/src/clang/ClangQuotes.mli similarity index 100% rename from infer/src/integration/ClangQuotes.mli rename to infer/src/clang/ClangQuotes.mli diff --git a/infer/src/clang/dune.in b/infer/src/clang/dune.in new file mode 100644 index 000000000..630db99df --- /dev/null +++ b/infer/src/clang/dune.in @@ -0,0 +1,27 @@ +(* -*- 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. + *) +(* NOTE: prepend dune.common to this file! *) + +let clang = + Printf.sprintf + {|(library + (name ClangFrontend) + (public_name infer.ClangFrontend) + (modules %s) + (flags + (:standard + -open Core -open InferStdlib -open IStd -open OpenSource -open InferGenerated + -open InferBase -open InferIR -open Absint -open Checkers -open TestDeterminators)) + (libraries core InferStdlib InferGenerated InferBase InferIR absint checkers TestDeterminators) + (preprocess (pps ppx_compare)) +)|} + (if clang then ":standard \\ ClangFrontendStubs" else "ClangFrontendStubs") + + +;; +Jbuild_plugin.V1.send clang diff --git a/infer/src/clang_stubs/ClangWrapper.ml b/infer/src/clang_stubs/ClangWrapper.ml deleted file mode 100644 index 57e37ad59..000000000 --- a/infer/src/clang_stubs/ClangWrapper.ml +++ /dev/null @@ -1,10 +0,0 @@ -(* - * 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 - -let exe ~prog:_ ~args:_ = () diff --git a/infer/src/clang_stubs/ClangWrapper.mli b/infer/src/clang_stubs/ClangWrapper.mli deleted file mode 100644 index 0d85c9824..000000000 --- a/infer/src/clang_stubs/ClangWrapper.mli +++ /dev/null @@ -1,10 +0,0 @@ -(* - * 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 - -val exe : prog:string -> args:string list -> unit diff --git a/infer/src/deadcode/Makefile b/infer/src/deadcode/Makefile index 594217e77..6038a0f39 100644 --- a/infer/src/deadcode/Makefile +++ b/infer/src/deadcode/Makefile @@ -50,8 +50,8 @@ endif # Note that we run find under _build directory. Since we copy some # sources from subfolders to src/ folder to avoid duplicates we use # $(DEPTH_ONE) and iteration over main and library folders. -LIBRARY_FOLDERS = . ./IR ./absint ./atd ./backend ./base ./biabduction ./bufferoverrun ./c_stubs ./checkers ./concurrency ./cost ./istd ./java ./labs ./nullsafe ./pulse ./quandary ./scripts ./topl -INCLUDE_FOLDERS = -I absint -I IR -I atd -I backend -I base -I biabduction -I bufferoverrun -I c_stubs -I checkers -I concurrency -I cost -I istd -I java -I labs -I nullsafe -I pulse -I quandary -I scripts -I topl +LIBRARY_FOLDERS = . ./IR ./absint ./al ./atd ./backend ./base ./biabduction ./bufferoverrun ./c_stubs ./checkers ./clang ./concurrency ./cost ./istd ./java ./labs ./nullsafe ./pulse ./quandary ./scripts ./test_determinator ./topl +INCLUDE_FOLDERS = -I IR -I absint -I al -I atd -I backend -I base -I biabduction -I bufferoverrun -I c_stubs -I checkers -I clang -I concurrency -I cost -I istd -I java -I labs -I nullsafe -I pulse -I quandary -I scripts -I test_determinator -I topl ml_src_files:=$(shell \ cd $(INFER_BUILD_DIR); \ diff --git a/infer/src/dune.in b/infer/src/dune.in index 25948ea28..2423bd40f 100644 --- a/infer/src/dune.in +++ b/infer/src/dune.in @@ -10,8 +10,8 @@ let ( ^/ ) = Filename.concat let source_dirs = - (if clang then ["al"; "clang"; "unit" ^/ "clang"] else ["clang_stubs"; "unit" ^/ "clang_stubs"]) - @ ["integration"; "test_determinator"; "unit"; "unit" ^/ "nullsafe"] + (if clang then ["unit" ^/ "clang"] else ["unit" ^/ "clang_stubs"]) + @ ["integration"; "unit"; "unit" ^/ "nullsafe"] let infer_binaries = ["infer"; "inferunit"] @ if facebook then ["InferCreateTraceViewLinks"] else [] @@ -32,11 +32,6 @@ let env_stanza = lenient_flags lenient_flags strict_flags -let clang_lexer_stanzas = - if clang then ["(ocamllex types_lexer ctl_lexer)"; "(menhir (modules types_parser ctl_parser))"] - else [] - - let infer_cflags = ( [ "-open" ; "Core" @@ -79,8 +74,15 @@ let infer_cflags = ; "-open" ; "Backend" ; "-open" - ; "JavaFrontend" ] - @ if java then [] else ["-open"; "JavaFrontendStubs"] ) + ; "JavaFrontend" + ; "-open" + ; "ClangFrontend" + ; "-open" + ; "ASTLanguage" + ; "-open" + ; "TestDeterminators" ] + @ (if java then [] else ["-open"; "JavaFrontendStubs"]) + @ if clang then [] else ["-open"; "ClangFrontendStubs"] ) |> String.concat " " @@ -113,7 +115,10 @@ let main_lib_stanza = ; "TOPLlib" ; "concurrency" ; "labs" - ; "backend" ] )) + ; "backend" + ; "ClangFrontend" + ; "ASTLanguage" + ; "TestDeterminators" ] )) (String.concat " " infer_binaries) @@ -165,8 +170,7 @@ let flatten_sources_stanzas = (** The build stanzas to be passed to dune *) let stanzas = - (env_stanza :: main_lib_stanza :: infer_exe_stanza :: infertop_stanza :: clang_lexer_stanzas) - @ flatten_sources_stanzas + env_stanza :: main_lib_stanza :: infer_exe_stanza :: infertop_stanza :: flatten_sources_stanzas ;; diff --git a/infer/src/integration/Clang.ml b/infer/src/integration/Clang.ml index 6f6453008..086cb7741 100644 --- a/infer/src/integration/Clang.ml +++ b/infer/src/integration/Clang.ml @@ -10,6 +10,7 @@ module L = Logging type compiler = Clang | Make [@@deriving compare] let capture compiler ~prog ~args = + RegisterCallback.register_frontend_checks () ; match compiler with | Clang -> ClangWrapper.exe ~prog ~args diff --git a/infer/src/test_determinator/dune b/infer/src/test_determinator/dune new file mode 100644 index 000000000..e8b9fa17a --- /dev/null +++ b/infer/src/test_determinator/dune @@ -0,0 +1,15 @@ +; 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. + +(library + (name TestDeterminators) + (public_name infer.TestDeterminators) + (flags + (:standard + -open Core -open InferStdlib -open IStd -open OpenSource -open InferGenerated + -open InferBase -open InferIR -open InferCStubs)) + (libraries core InferStdlib InferGenerated InferBase InferIR InferCStubs) + (preprocess (pps ppx_compare)) +)