@@ -1109,38 +1109,6 @@ def freeVar (name: String) := mkStmtExprMd (.Identifier name)
11091109def maybeExceptVar := freeVar "maybe_except"
11101110def nullcall_var := freeVar "nullcall_ret"
11111111
1112- -- Invariant: if `callExpr` is not `.Call`, returns `[]`.
1113- -- Otherwise the returned block always havocs `maybe_except`;
1114- -- additionally havocs callee (if non-composite instance call)
1115- -- and `$heap` (if any argument — or the implicit receiver — is composite).
1116- private def mkHavocStmtsForUnmodeledCall (ctx : TranslationContext)
1117- (callExpr : Python.expr SourceRange)
1118- (md : Imperative.MetaData Core.Expression) : List StmtExprMd :=
1119- if let .Call _ funccall args kwords := callExpr then
1120- let holeExceptHavoc := [mkStmtExprMdWithLoc (StmtExpr.Assign [maybeExceptVar] (mkStmtExprMd (.Hole false none))) md]
1121- let (calleeHavoc, calleeIsComposite) :=
1122- if let (.Attribute _ callee _ _) := funccall then
1123- let (base, _) := getListAttributes callee
1124- if let .Name _ n _ := base then
1125- match ctx.variableTypes.find? (λ v => Prod.fst v == n.val) with
1126- | some (varName, ty) =>
1127- if isCompositeType ctx ty then ([], true )
1128- else
1129- ([mkStmtExprMdWithLoc (StmtExpr.Assign [freeVar varName] (mkStmtExprMd (.Hole false none))) md], false )
1130- | _ => ([], false )
1131- else ([], false )
1132- else ([], false )
1133- let inputExprs:= args.val.toList ++ kwords.val.toList.map (λ kw => match kw with
1134- | keyword.mk_keyword _ _ expr => expr)
1135- let involveHeap := calleeIsComposite || (inputExprs.any fun inputExpr =>
1136- match inferExprType ctx inputExpr with
1137- | .ok ty => isCompositeType ctx ty
1138- | _ => false )
1139- let heapHavoc := if !involveHeap then [] else
1140- [mkStmtExprMdWithLoc (StmtExpr.Assign [freeVar "$heap" ] (mkStmtExprMd (.Hole false none))) md]
1141- [mkStmtExprMd $ .Block (holeExceptHavoc ++ calleeHavoc ++ heapHavoc) none]
1142- else []
1143-
11441112partial def translateAssign (ctx : TranslationContext)
11451113 (lhs: Python.expr SourceRange)
11461114 (annotation: Option (Python.expr SourceRange) )
@@ -1175,12 +1143,15 @@ partial def translateAssign (ctx : TranslationContext)
11751143 let rhsIsCall := match rhs with | .Call _ _ _ _ => true | _ => false
11761144 if let .Hole := rhs_trans.val then
11771145 {
1178- let havocStmts := mkHavocStmtsForUnmodeledCall ctx rhs md
1146+ let exceptHavoc :=
1147+ if rhsIsCall then
1148+ [mkStmtExprMdWithLoc (StmtExpr.Assign [maybeExceptVar] (mkStmtExprMd (.Hole false none))) md]
1149+ else []
11791150 match lhs with
11801151 | .Name _ n _ =>
11811152 if n.val ∈ ctx.variableTypes.unzip.1 then
11821153 let targetExpr := mkStmtExprMd (StmtExpr.Identifier n.val)
1183- return (ctx, [mkStmtExprMd (StmtExpr.Assign [targetExpr] rhs_trans)] ++ havocStmts , true )
1154+ return (ctx, [mkStmtExprMd (StmtExpr.Assign [targetExpr] rhs_trans)] ++ exceptHavoc , true )
11841155 else
11851156 -- Use type annotation if it matches a known composite type
11861157 let annType := annotation.map (fun a => pyExprToString a) |>.getD "Any"
@@ -1192,8 +1163,8 @@ partial def translateAssign (ctx : TranslationContext)
11921163 | _ => pure (AnyTy, "Any" )
11931164 let initStmt := mkStmtExprMd (StmtExpr.LocalVariable n.val varTy (mkStmtExprMd .Hole))
11941165 let newctx := {ctx with variableTypes:=(n.val, trackType)::ctx.variableTypes}
1195- return (newctx, [initStmt] ++ havocStmts , true )
1196- | _ => return (ctx, [mkStmtExprMd .Hole] ++ havocStmts , false )
1166+ return (newctx, [initStmt] ++ exceptHavoc , true )
1167+ | _ => return (ctx, [mkStmtExprMd .Hole] ++ exceptHavoc , false )
11971168 }
11981169 let mut newctx := ctx
11991170 match lhs with
@@ -1528,8 +1499,10 @@ partial def translateStmt (ctx : TranslationContext) (s : Python.stmt SourceRang
15281499
15291500 -- When a call has no model (translates to Hole), also havoc maybe_except
15301501 -- since an unmodeled call is a black box that could throw any exception.
1531- let havocStmts := mkHavocStmtsForUnmodeledCall ctx value md
1532-
1502+ let holeExceptHavoc :=
1503+ if let .Call _ _ _ _ := value then
1504+ [mkStmtExprMdWithLoc (StmtExpr.Assign [maybeExceptVar] (mkStmtExprMd (.Hole false none))) md]
1505+ else []
15331506 match expr.val with
15341507 | .StaticCall fnname _ =>
15351508 match ctx.functionSignatures.find? (λ funsig => funsig.name == fnname) with
@@ -1543,7 +1516,7 @@ partial def translateStmt (ctx : TranslationContext) (s : Python.stmt SourceRang
15431516 | _ => return (ctx, exceptionCheck ++ [expr])
15441517 -- Unmodeled call: skip exception checks (no model to check against),
15451518 -- but havoc maybe_except since the call could throw.
1546- | .Hole => return (ctx, [expr] ++ havocStmts )
1519+ | .Hole => return (ctx, [expr] ++ holeExceptHavoc )
15471520 | _ => return (ctx, exceptionCheck ++ [expr])
15481521
15491522 | .Import _ _ | .ImportFrom _ _ _ _ |.Pass _ => return (ctx, [])
0 commit comments