From 81c68a34cdab2a6679290801e6d096c5b150ee4c Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Fri, 1 Sep 2017 14:16:55 -0700 Subject: [PATCH] [infer] python integration: parser, cfg support Reviewed By: jvillard Differential Revision: D5657644 fbshipit-source-id: 3c7d231 --- Makefile.autoconf.in | 1 + configure.ac | 9 +++++++++ infer/src/Makefile | 1 + infer/src/backend/interproc.ml | 2 ++ infer/src/backend/prover.ml | 4 ++++ infer/src/backend/rearrange.ml | 2 ++ infer/src/base/Config.ml | 4 ++-- infer/src/base/Config.mli | 2 +- infer/src/base/Version.ml.in | 2 ++ infer/src/base/Version.mli | 2 ++ infer/src/integration/Driver.ml | 15 +++++++++++++++ infer/src/integration/Driver.mli | 1 + infer/src/jbuild.common.in | 2 ++ infer/src/jbuild.in | 7 +++++-- infer/src/python_stubs/pythonMain.ml | 10 ++++++++++ infer/src/python_stubs/pythonMain.mli | 10 ++++++++++ 16 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 infer/src/python_stubs/pythonMain.ml create mode 100644 infer/src/python_stubs/pythonMain.mli diff --git a/Makefile.autoconf.in b/Makefile.autoconf.in index da2aa8544..422d95f75 100644 --- a/Makefile.autoconf.in +++ b/Makefile.autoconf.in @@ -13,6 +13,7 @@ bindir = @bindir@ BUCK = @BUCK@ BUILD_C_ANALYZERS = @BUILD_C_ANALYZERS@ BUILD_JAVA_ANALYZERS = @BUILD_JAVA_ANALYZERS@ +BUILD_PYTHON_ANALYZERS = @BUILD_PYTHON_ANALYZERS@ CAML_LD_LIBRARY_PATH = @CAML_LD_LIBRARY_PATH@ CC = @CC@ CFLAGS = @CFLAGS@ diff --git a/configure.ac b/configure.ac index 4b7e41599..2c63dfdf3 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,15 @@ AC_ARG_ENABLE(java-analyzers, BUILD_JAVA_ANALYZERS=$enable_java_analyzers AC_SUBST([BUILD_JAVA_ANALYZERS]) +AC_ARG_ENABLE(python-analyzers, + AS_HELP_STRING([--disable-python-analyzers], + [do not build the Python analyzers (default is to build them)]), + , + enable_python_analyzers=yes) + +BUILD_PYTHON_ANALYZERS=$enable_python_analyzers +AC_SUBST([BUILD_PYTHON_ANALYZERS]) + AC_ARG_WITH(fcp-clang, AS_HELP_STRING([--without-fcp-clang], [do not use $CLANG_PREFIX/bin/clang to override the default compiler (default is to override if in an infer release)]), diff --git a/infer/src/Makefile b/infer/src/Makefile index 0dd80b88e..f97362fe4 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -255,6 +255,7 @@ $(GENERATED_FROM_AUTOCONF): $(MAKEFILE_LIST) -e "s|@INFER_GIT_BRANCH[@]|$$INFER_GIT_BRANCH|g" \ -e "s|@BUILD_C_ANALYZERS[@]|$(BUILD_C_ANALYZERS)|g" \ -e "s|@BUILD_JAVA_ANALYZERS[@]|$(BUILD_JAVA_ANALYZERS)|g" \ + -e "s|@BUILD_PYTHON_ANALYZERS[@]|$(BUILD_PYTHON_ANALYZERS)|g" \ -e "s|@OPAMSWITCH[@]|$(OPAMSWITCH)|g" \ -e "s|@XCODE_SELECT[@]|$(XCODE_SELECT)|g" \ -e "s|@INFER_MAN_LAST_MODIFIED[@]|$(INFER_MAN_LAST_MODIFIED)|g" \ diff --git a/infer/src/backend/interproc.ml b/infer/src/backend/interproc.ml index 6c1638f86..89c4d7145 100644 --- a/infer/src/backend/interproc.ml +++ b/infer/src/backend/interproc.ml @@ -757,6 +757,8 @@ let prop_init_formals_seed tenv new_formals (prop: 'a Prop.t) : Prop.exposed Pro -> Exp.Sizeof {typ; nbytes= None; dynamic_length= None; subtype= Subtype.exact} | Config.Java -> Exp.Sizeof {typ; nbytes= None; dynamic_length= None; subtype= Subtype.subtypes} + | Config.Python + -> L.die InternalError "prop_init_formals_seed not implemented for Python" in Prop.mk_ptsto_lvar tenv Prop.Fld_init Sil.inst_formal (pv, texp, None) in diff --git a/infer/src/backend/prover.ml b/infer/src/backend/prover.ml index 0d703808c..70bb50bb7 100644 --- a/infer/src/backend/prover.ml +++ b/infer/src/backend/prover.ml @@ -2306,6 +2306,8 @@ and sigma_imply tenv calc_index_frame calc_missing subs prop1 sigma2 : subst2 * ; "java.lang.String.value" ] in Sil.Estruct (List.map ~f:mk_fld_sexp fields, Sil.inst_none) + | Config.Python + -> L.die InternalError "mk_constant_string_hpred not implemented for Python" in let const_string_texp = match !Config.curr_language with @@ -2322,6 +2324,8 @@ and sigma_imply tenv calc_index_frame calc_missing subs prop1 sigma2 : subst2 * ; nbytes= None ; dynamic_length= None ; subtype= Subtype.exact } + | Config.Python + -> L.die InternalError "const_string_texp not implemented for Python" in Sil.Hpointsto (root, sexp, const_string_texp) in diff --git a/infer/src/backend/rearrange.ml b/infer/src/backend/rearrange.ml index be45c0342..54b54a17f 100644 --- a/infer/src/backend/rearrange.ml +++ b/infer/src/backend/rearrange.ml @@ -462,6 +462,8 @@ let mk_ptsto_exp_footprint pname tenv orig_prop (lexp, typ) max_stamp inst -> Subtype.exact | Config.Java -> Subtype.subtypes + | Config.Python + -> L.die InternalError "Subtypes for Python not implemented" in let create_ptsto footprint_part off0 = match (root, off0, typ.Typ.desc) with diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 2453c2bf9..f019dbde6 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -43,11 +43,11 @@ let string_of_analyzer a = let clang_frontend_action_symbols = [("lint", `Lint); ("capture", `Capture); ("lint_and_capture", `Lint_and_capture)] -type language = Clang | Java [@@deriving compare] +type language = Clang | Java | Python [@@deriving compare] let equal_language = [%compare.equal : language] -let string_of_language = function Java -> "Java" | Clang -> "C_CPP" +let string_of_language = function Java -> "Java" | Clang -> "C_CPP" | Python -> "python" let ml_bucket_symbols = [ ("all", `MLeak_all) diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 1537f956c..03833c9b3 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -30,7 +30,7 @@ val string_to_analyzer : (string * analyzer) list val string_of_analyzer : analyzer -> string -type language = Clang | Java [@@deriving compare] +type language = Clang | Java | Python [@@deriving compare] val equal_language : language -> language -> bool diff --git a/infer/src/base/Version.ml.in b/infer/src/base/Version.ml.in index 37f09d9f9..a11ad5d03 100644 --- a/infer/src/base/Version.ml.in +++ b/infer/src/base/Version.ml.in @@ -45,6 +45,8 @@ let clang_enabled = is_yes "@BUILD_C_ANALYZERS@" let java_enabled = is_yes "@BUILD_JAVA_ANALYZERS@" +let python_enabled = is_yes "@BUILD_PYTHON_ANALYZERS@" + let xcode_enabled = is_not_no "@XCODE_SELECT@" let man_pages_last_modify_date = "@INFER_MAN_LAST_MODIFIED@" diff --git a/infer/src/base/Version.mli b/infer/src/base/Version.mli index 0cd024615..9e210f210 100644 --- a/infer/src/base/Version.mli +++ b/infer/src/base/Version.mli @@ -19,6 +19,8 @@ val clang_enabled : bool val java_enabled : bool +val python_enabled : bool + val xcode_enabled : bool val man_pages_last_modify_date : string diff --git a/infer/src/integration/Driver.ml b/infer/src/integration/Driver.ml index 9c8441b39..1cded1314 100644 --- a/infer/src/integration/Driver.ml +++ b/infer/src/integration/Driver.ml @@ -26,6 +26,7 @@ type build_system = | BMake | BMvn | BNdk + | BPython | BXcode [@@deriving compare] @@ -55,6 +56,7 @@ let build_system_exe_assoc = ; (BMvn, "mvn") ; (BMvn, "mvnw") ; (BNdk, "ndk-build") + ; (BPython, "python") ; (BXcode, "xcodebuild") ] let build_system_of_exe_name name = @@ -73,6 +75,7 @@ type mode = | ClangCompilationDB of [`Escaped of string | `Raw of string] list | Javac of Javac.compiler * string * string list | Maven of string * string list + | Python of string list | PythonCapture of build_system * string list | XcodeXcpretty of string * string list [@@deriving compare] @@ -92,6 +95,7 @@ let pp_mode fmt mode = | BuckGenrule _ | BuckCompilationDB _ | ClangCompilationDB _ + | Python _ | PythonCapture (_, _) | XcodeXcpretty _ -> (* these are pretty boring, do not log anything *) @@ -268,6 +272,9 @@ let capture ~changed_files = function -> L.progress "Capturing in javac mode...@." ; Javac.capture compiler ~prog ~args | Maven (prog, args) -> L.progress "Capturing in maven mode...@." ; Maven.capture ~prog ~args + | Python args + -> (* pretend prog is the root directory of the project *) + PythonMain.go args | PythonCapture (build_system, build_cmd) -> L.progress "Capturing in %s mode...@." (string_of_build_system build_system) ; let in_buck_mode = equal_build_system build_system BBuck in @@ -461,6 +468,8 @@ let assert_supported_mode required_analyzer requested_mode_string = -> Version.clang_enabled | `Java -> Version.java_enabled + | `Python + -> Version.python_enabled | `Xcode -> Version.clang_enabled && Version.xcode_enabled in @@ -471,6 +480,8 @@ let assert_supported_mode required_analyzer requested_mode_string = -> "clang" | `Java -> "java" + | `Python + -> "python" | `Xcode -> "clang and xcode" in @@ -484,6 +495,8 @@ let assert_supported_build_system build_system = -> string_of_build_system build_system |> assert_supported_mode `Java | BClang | BMake | BNdk -> string_of_build_system build_system |> assert_supported_mode `Clang + | BPython + -> string_of_build_system build_system |> assert_supported_mode `Python | BXcode -> string_of_build_system build_system |> assert_supported_mode `Xcode | BBuck @@ -528,6 +541,8 @@ let mode_of_build_command build_cmd = -> Javac (Javac.Javac, prog, args) | BMvn -> Maven (prog, args) + | BPython + -> Python args | BXcode when Config.xcpretty -> XcodeXcpretty (prog, args) | BAnt | BBuck | BGradle | BNdk | BXcode as build_system diff --git a/infer/src/integration/Driver.mli b/infer/src/integration/Driver.mli index 786b31dbb..b6add8eee 100644 --- a/infer/src/integration/Driver.mli +++ b/infer/src/integration/Driver.mli @@ -23,6 +23,7 @@ type mode = | ClangCompilationDB of [`Escaped of string | `Raw of string] list | Javac of Javac.compiler * string * string list | Maven of string * string list + | Python of string list | PythonCapture of build_system * string list | XcodeXcpretty of string * string list [@@deriving compare] diff --git a/infer/src/jbuild.common.in b/infer/src/jbuild.common.in index 7c0232303..2d79e59c4 100644 --- a/infer/src/jbuild.common.in +++ b/infer/src/jbuild.common.in @@ -7,6 +7,8 @@ let clang = is_yes "@BUILD_C_ANALYZERS@" let java = is_yes "@BUILD_JAVA_ANALYZERS@" +let python = is_yes "@BUILD_PYTHON_ANALYZERS@" + let facebook = is_yes "@IS_FACEBOOK_TREE@" let extra_cflags = if "@EXTRA_CFLAGS" = "" then [] else ["@EXTRA_CFLAGS@"] diff --git a/infer/src/jbuild.in b/infer/src/jbuild.in index b5e5ff707..f24cc418d 100644 --- a/infer/src/jbuild.in +++ b/infer/src/jbuild.in @@ -17,6 +17,7 @@ let sources = :: ( ( if clang then ["clang"; ("unit" ^/ "clang")] else ["clang_stubs"; ("unit" ^/ "clang_stubs")] ) @ [ (if java then "java" else "java_stubs") + ; (if python && facebook then "python" else "python_stubs") ; "absint" ; "backend" ; "base" @@ -66,6 +67,8 @@ let stanzas = ( if clang then ["(ocamllex (types_lexer ctl_lexer))"; "(menhir ((modules (types_parser ctl_parser))))"] else [] ) + @ ( if python && facebook then ["(ocamllex (pythonLexer))"; "(menhir ((modules (pythonParser))))"] + else [] ) @ [ Format.sprintf {| (library @@ -73,7 +76,7 @@ let stanzas = (flags (%s)) (libraries (%s)) (modules (:standard \ %s infertop)) - (preprocess (pps (ppx_compare))) + (preprocess (pps (ppx_compare ppx_sexp_conv -no-check))) )) |} (String.concat " " infer_cflags) (String.concat " " infer_libraries) @@ -85,7 +88,7 @@ let stanzas = (flags (%s -open InferModules)) (libraries (InferModules)) (modules (%s)) - (preprocess (pps (ppx_compare))) + (preprocess (pps (ppx_compare ppx_sexp_conv -no-check))) )) |} (String.concat " " infer_binaries) (String.concat " " infer_cflags) diff --git a/infer/src/python_stubs/pythonMain.ml b/infer/src/python_stubs/pythonMain.ml new file mode 100644 index 000000000..dca765d38 --- /dev/null +++ b/infer/src/python_stubs/pythonMain.ml @@ -0,0 +1,10 @@ +(* + * 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. + *) + +let go _ = () diff --git a/infer/src/python_stubs/pythonMain.mli b/infer/src/python_stubs/pythonMain.mli new file mode 100644 index 000000000..f5f1342e8 --- /dev/null +++ b/infer/src/python_stubs/pythonMain.mli @@ -0,0 +1,10 @@ +(* + * 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. + *) + +val go : string list -> unit