From 324d44499066af0f600fcdfb4705b5969ea1b8c0 Mon Sep 17 00:00:00 2001 From: David Pichardie Date: Tue, 29 Oct 2024 09:57:52 -0700 Subject: [PATCH] [inferpython] bugfix IMPORT_STAR Summary: this opcode does not push anything on the stack. Reviewed By: skcho Differential Revision: D65056888 Privacy Context Container: L1208441 fbshipit-source-id: b0cd09806c1a180ddf9641769c92c958ca99892a --- infer/src/python/PyIR.ml | 9 +++---- infer/src/python/PyIR.mli | 2 +- infer/src/python/PyIR2Textual.ml | 4 +-- infer/src/python/PyIRExec.ml | 1 + infer/src/python/unit/PyIRTestImport.ml | 33 ++++++++++++++++++++++++- 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/infer/src/python/PyIR.ml b/infer/src/python/PyIR.ml index b33ff8e313..f0793a5b78 100644 --- a/infer/src/python/PyIR.ml +++ b/infer/src/python/PyIR.ml @@ -297,7 +297,6 @@ module BuiltinCaller = struct | FormatFn of FormatFunction.t | CallFunctionEx (** [CALL_FUNCTION_EX] *) | Inplace of BinaryOp.t - | ImportStar | Binary of BinaryOp.t | Unary of UnaryOp.t | Compare of CompareOp.t @@ -333,8 +332,6 @@ module BuiltinCaller = struct sprintf "$FormatFn.%s" (FormatFunction.to_string fn) | CallFunctionEx -> "$CallFunctionEx" - | ImportStar -> - sprintf "$ImportStar" | Binary op -> let op = BinaryOp.to_string op in sprintf "$Binary.%s" op @@ -646,6 +643,7 @@ module Stmt = struct | Delete of ScopedIdent.t (** [DELETE_FAST] & cie *) | DeleteDeref of {name: Ident.t; slot: int} (** [DELETE_DEREF] *) | DeleteAttr of {exp: Exp.t; attr: Ident.t} + | ImportStar of Exp.t | GenStart of {kind: gen_kind} | SetupAnnotations @@ -676,6 +674,8 @@ module Stmt = struct F.fprintf fmt "$DeleteDeref[%d,\"%a\")" slot Ident.pp name | DeleteAttr {exp; attr} -> F.fprintf fmt "$DeleteAttr(%a, %a)" Exp.pp exp Ident.pp attr + | ImportStar exp -> + F.fprintf fmt "$ImportStart(%a)" Exp.pp exp | GenStart {kind} -> let kind = match kind with @@ -1805,8 +1805,7 @@ let parse_bytecode st ({FFI.Code.co_consts; co_names; co_varnames} as code) Ok (st, None) | "IMPORT_STAR" -> let* module_object, st = State.pop_and_cast st in - let* id, st = call_builtin_function st ImportStar [module_object] in - let st = State.push st (Exp.Temp id) in + let st = State.push_stmt st (ImportStar module_object) in Ok (st, None) | "IMPORT_FROM" -> let name = co_names.(arg) |> Ident.mk in diff --git a/infer/src/python/PyIR.mli b/infer/src/python/PyIR.mli index 0f9798f5a2..1d7c3d08d2 100644 --- a/infer/src/python/PyIR.mli +++ b/infer/src/python/PyIR.mli @@ -107,7 +107,6 @@ module BuiltinCaller : sig | FormatFn of FormatFunction.t | CallFunctionEx (** [CALL_FUNCTION_EX] *) | Inplace of BinaryOp.t - | ImportStar | Binary of BinaryOp.t | Unary of UnaryOp.t | Compare of CompareOp.t @@ -196,6 +195,7 @@ module Stmt : sig | Delete of ScopedIdent.t | DeleteDeref of {name: Ident.t; slot: int} (** [DELETE_DEREF] *) | DeleteAttr of {exp: Exp.t; attr: Ident.t} + | ImportStar of Exp.t | GenStart of {kind: gen_kind} | SetupAnnotations end diff --git a/infer/src/python/PyIR2Textual.ml b/infer/src/python/PyIR2Textual.ml index 05efbdd825..a89e0c1e80 100644 --- a/infer/src/python/PyIR2Textual.ml +++ b/infer/src/python/PyIR2Textual.ml @@ -276,8 +276,6 @@ let builtin_name builtin = "py_call_function_ex" | Inplace op -> F.asprintf "py_inplace_%s" (binary_op_name op) - | ImportStar -> - "py_import_star" | Binary op -> F.asprintf "py_binary_%s" (binary_op_name op) | Unary op -> @@ -396,6 +394,8 @@ let of_stmt loc stmt : Textual.Instr.t = Let {id= None; exp= call_builtin "py_delete_attr" [of_exp exp; exp_of_ident_str attr]; loc} | SetupAnnotations -> Let {id= None; exp= call_builtin "py_setup_annotations" []; loc} + | ImportStar exp -> + Let {id= None; exp= call_builtin "py_import_star" [of_exp exp]; loc} | GenStart {kind} -> let kind = match kind with diff --git a/infer/src/python/PyIRExec.ml b/infer/src/python/PyIRExec.ml index f78ce23fa4..6d57eebc1b 100644 --- a/infer/src/python/PyIRExec.ml +++ b/infer/src/python/PyIRExec.ml @@ -431,6 +431,7 @@ let run_files modules = | DeleteAttr _ | StoreDeref _ | SetupAnnotations + | ImportStar _ | GenStart _ -> todo "exec_stmt" in diff --git a/infer/src/python/unit/PyIRTestImport.ml b/infer/src/python/unit/PyIRTestImport.ml index 0d198506a6..e219f8a410 100644 --- a/infer/src/python/unit/PyIRTestImport.ml +++ b/infer/src/python/unit/PyIRTestImport.ml @@ -609,5 +609,36 @@ from foo import * function toplevel(): b0: n0 <- $ImportName(foo, $BuildTuple("*"), 0) - n1 <- $ImportStar(n0, None) + $ImportStart(n0) + return None |}] + + +let%expect_test _ = + let source = + {| +if test(): + from mod import * +try: + pass +except Exception as error: + pass +|} + in + PyIR.test source ; + [%expect + {| + module dummy: + + function toplevel(): + b0: + n0 <- TOPLEVEL[test] + n1 <- $Call(n0, None) + if n1 then jmp b1 else jmp b2 + + b1: + n2 <- $ImportName(mod, $BuildTuple("*"), 0) + $ImportStart(n2) + jmp b2 + + b2: return None |}]