aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-05-03 02:13:56 +0000
committerAnna Zaks <ganna@apple.com>2012-05-03 02:13:56 +0000
commite55a14a025c38800d07f1ab0db7dbbe4a2fe1605 (patch)
tree20b0fffd25d47c5636f9cd8c39911820ffcb59bd
parentda3960347a5d563d6746cb363b25466282a09ce3 (diff)
[analyzer] Conjure a symbol to ensure we can identify pointer arithmetic
We need to identify the value of ptr as ElementRegion (result of pointer arithmetic) in the following code. However, before this commit '(2-x)' evaluated to Unknown value, and as the result, 'p + (2-x)' evaluated to Unknown value as well. int *p = malloc(sizeof(int)); ptr = p + (2-x); git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156052 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp20
-rw-r--r--test/Analysis/malloc.c7
2 files changed, 27 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 93e598a273..d5555daecd 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -58,6 +58,26 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
if (!B->isAssignmentOp()) {
StmtNodeBuilder Bldr(*it, Tmp2, *currentBuilderContext);
+
+ if (B->isAdditiveOp()) {
+ // If one of the operands is a location, conjure a symbol for the other
+ // one (offset) if it's unknown so that memory arithmetic always
+ // results in an ElementRegion.
+ // TODO: This can be removed after we enable history tracking with
+ // SymSymExpr.
+ unsigned Count = currentBuilderContext->getCurrentBlockCount();
+ if (isa<Loc>(LeftV) &&
+ RHS->getType()->isIntegerType() && RightV.isUnknown()) {
+ RightV = svalBuilder.getConjuredSymbolVal(RHS, LCtx,
+ RHS->getType(), Count);
+ }
+ if (isa<Loc>(RightV) &&
+ LHS->getType()->isIntegerType() && LeftV.isUnknown()) {
+ LeftV = svalBuilder.getConjuredSymbolVal(LHS, LCtx,
+ LHS->getType(), Count);
+ }
+ }
+
// Process non-assignments except commas or short-circuited
// logical expressions (LAnd and LOr).
SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 27e34e9039..9c09051c31 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -776,6 +776,13 @@ int rdar11269741(struct rdar11269741_b_t o)
return p->n.m; // expected-warning {{leak}}
}
+// Pointer arithmetic, returning an ElementRegion.
+void *radar11329382(unsigned bl) {
+ void *ptr = malloc (16);
+ ptr = ptr + (2 - bl);
+ return ptr; // no warning
+}
+
void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
int strcmp(const char *, const char *);
char *a (void);