Skip to content

Commit 2e60608

Browse files
committed
Properly extend path condition for llvm_conditional_points_to
This leverages the newly introduced `withConditionalPred` function (see the parent commit) to make `llvm_conditional_points_to cond ptr val` properly extend the path condition with `cond` before matching `val` against the value that `ptr` points to. Fixes #1945.
1 parent cac3dae commit 2e60608

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

intTests/test1945/Makefile

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CC = clang
2+
CFLAGS = -g -frecord-command-line -O0
3+
4+
all: test.bc
5+
6+
test.bc: test.c
7+
$(CC) $(CFLAGS) -c -emit-llvm $< -o $@
8+
9+
.PHONY: clean
10+
clean:
11+
rm -f test.bc

intTests/test1945/test.bc

2.7 KB
Binary file not shown.

intTests/test1945/test.c

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include <stdint.h>
2+
3+
void test(uint8_t *x) {}

intTests/test1945/test.saw

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Test a use of `llvm_conditional_points_to` where the value that the pointer
2+
// points to will fail to match against the right-hand side value unless the
3+
// condition is properly incorporated into the path condition. This serves as
4+
// a regression test for https://github.com/GaloisInc/saw-script/issues/1945.
5+
6+
let test_spec = do {
7+
p <- llvm_alloc (llvm_int 8);
8+
x <- llvm_fresh_var "x" (llvm_int 8);
9+
llvm_points_to p (llvm_term x);
10+
11+
llvm_execute_func [p];
12+
13+
llvm_conditional_points_to {{ x == 1 }} p (llvm_term {{ 1 : [8] }});
14+
};
15+
16+
m <- llvm_load_module "test.bc";
17+
llvm_verify m "test" [] false test_spec z3;

intTests/test1945/test.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set -e
2+
3+
$SAW test.saw

src/SAWScript/Crucible/LLVM/Override.hs

+20-6
Original file line numberDiff line numberDiff line change
@@ -1410,14 +1410,28 @@ matchPointsToValue opts sc cc spec prepost md maybe_cond ptr val =
14101410
let badLoadSummary = summarizeBadLoad cc memTy prepost ptr
14111411
case res of
14121412
Crucible.NoErr pred_ res_val -> do
1413-
pred_' <- case maybe_cond of
1414-
Just cond -> do
1415-
cond' <- instantiateExtResolveSAWPred sc cc (ttTerm cond)
1416-
liftIO $ W4.impliesPred sym cond' pred_
1417-
Nothing -> return pred_
1413+
-- If dealing with an `llvm_conditional_points_to` statement,
1414+
-- convert the condition to a `Pred`. If dealing with an
1415+
-- ordinary `llvm_points_to` statement, this condition will
1416+
-- simply be `True`.
1417+
cond' <- case maybe_cond of
1418+
Just cond ->
1419+
instantiateExtResolveSAWPred sc cc (ttTerm cond)
1420+
Nothing ->
1421+
pure $ W4.truePred sym
1422+
-- Next, construct an implication involving the condition and
1423+
-- assert it.
1424+
pred_' <- liftIO $ W4.impliesPred sym cond' pred_
14181425
addAssert pred_' md $ Crucible.SimError loc $
14191426
Crucible.AssertFailureSimError (show $ PP.vcat badLoadSummary) ""
1420-
pure Nothing <* matchArg opts sc cc spec prepost md res_val memTy val'
1427+
1428+
-- Finally, match the value that the pointer points to against
1429+
-- the right-hand side value in the points_to statement. Make
1430+
-- sure to execute this match with an extended path condition
1431+
-- that takes the condition above into account. See also
1432+
-- Note [oeConditionalPred] in SAWScript.Crucible.Common.Override.
1433+
withConditionalPred cond' $
1434+
pure Nothing <* matchArg opts sc cc spec prepost md res_val memTy val'
14211435
_ -> do
14221436
pure $ Just $ describeConcreteMemoryLoadFailure mem badLoadSummary ptr
14231437

0 commit comments

Comments
 (0)