]> granicus.if.org Git - clang/commitdiff
[analyzer] Conjure a symbol to ensure we can identify pointer arithmetic
authorAnna Zaks <ganna@apple.com>
Thu, 3 May 2012 02:13:56 +0000 (02:13 +0000)
committerAnna Zaks <ganna@apple.com>
Thu, 3 May 2012 02:13:56 +0000 (02:13 +0000)
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

lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/Analysis/malloc.c

index 93e598a273756a2cc0536d8d0e9b0ab3d6c81cb8..d5555daecdca7f36912dc6f8575a1e5599bc309c 100644 (file)
@@ -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());      
index 27e34e9039c1ace2929134ca8e9a1e9dd4ce5031..9c09051c31b49b17e7f53bd90c1b97a8946dae0d 100644 (file)
@@ -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);