Skip to content

Commit 9a9d3cd

Browse files
committed
fix unsafe setup_ex.path.to_smt2() access
1 parent d7dddf8 commit 9a9d3cd

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

src/halmos/__main__.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ def setup(ctx: FunctionContext) -> Exec:
318318
)
319319

320320
setup_exs_all = sevm.run(setup_ex)
321-
setup_exs_no_error: list[Exec] = []
321+
setup_exs_no_error: list[tuple[Exec, SMTQuery]] = []
322322

323323
for path_id, setup_ex in enumerate(setup_exs_all):
324324
if args.verbose >= VERBOSITY_TRACE_SETUP:
@@ -339,24 +339,25 @@ def setup(ctx: FunctionContext) -> Exec:
339339
render_trace(setup_ex.context)
340340

341341
else:
342-
setup_exs_no_error.append(setup_ex)
342+
# note: ex.path.to_smt2() needs to be called at this point. The solver object is shared across paths,
343+
# and solver.to_smt2() will return a different query if it is called after a different path is explored.
344+
setup_exs_no_error.append((setup_ex, setup_ex.path.to_smt2(args)))
343345

344346
setup_exs: list[Exec] = []
345347

346348
match setup_exs_no_error:
347349
case []:
348350
pass
349-
case [ex]:
351+
case [(ex, _)]:
350352
setup_exs.append(ex)
351353
case _:
352-
for path_id, ex in enumerate(setup_exs_no_error):
354+
for path_id, (ex, query) in enumerate(setup_exs_no_error):
353355
path_ctx = PathContext(
354356
args=args,
355357
path_id=path_id,
356-
query=ex.path.to_smt2(args),
358+
query=query,
357359
solving_ctx=ctx.solving_ctx,
358360
)
359-
360361
solver_output = solve_low_level(path_ctx)
361362
if solver_output.result != unsat:
362363
setup_exs.append(ex)

src/halmos/solve.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,10 @@ def solve_end_to_end(ctx: PathContext) -> SolverOutput:
445445
refined_ctx = ctx.refine()
446446

447447
if refined_ctx.query.smtlib != query.smtlib:
448-
# recurse with the refined query
449-
return solve_end_to_end(refined_ctx)
448+
# note that check_unsat_cores cannot return true for the refined query, because it relies on only
449+
# constraint ids, which don't change after refinement
450+
# therefore we can skip the unsat core check in solve_end_to_end and go directly to solve_low_level
451+
return solve_low_level(refined_ctx)
450452
else:
451453
verbose(" Refinement did not change the query, no need to solve again")
452454

0 commit comments

Comments
 (0)