[cfe-commits] r155944 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h lib/StaticAnalyzer/Core/SValBuilder.cpp lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp test/Analysis/malloc.c

Anna Zaks ganna at apple.com
Tue May 1 14:10:27 PDT 2012


Author: zaks
Date: Tue May  1 16:10:26 2012
New Revision: 155944

URL: http://llvm.org/viewvc/llvm-project?rev=155944&view=rev
Log:
[analyzer] Construct a SymExpr even when the constraint solver cannot
reason about the expression.

This essentially keeps more history about how symbolic values were
constructed. As an optimization, previous to this commit, we only kept
the history if one of the symbols was tainted, but it's valuable keep
the history around for other purposes as well: it allows us to avoid
constructing conjured symbols.

Specifically, 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);

This change brings 2% slowdown on sqlite. Fixes radar://11329382.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
    cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
    cfe/trunk/test/Analysis/malloc.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h?rev=155944&r1=155943&r2=155944&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h Tue May  1 16:10:26 2012
@@ -107,12 +107,9 @@
   /// that value is returned. Otherwise, returns NULL.
   virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
   
-  /// Handles generation of the value in case the builder is not smart enough to
-  /// handle the given binary expression. Depending on the state, decides to
-  /// either keep the expression or forget the history and generate an
-  /// UnknownVal.
-  SVal makeGenericVal(ProgramStateRef state, BinaryOperator::Opcode op,
-                          NonLoc lhs, NonLoc rhs, QualType resultTy);
+  /// Constructs a symbolic expression for two non-location values.
+  SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op,
+                      NonLoc lhs, NonLoc rhs, QualType resultTy);
 
   SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
                  SVal lhs, SVal rhs, QualType type);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=155944&r1=155943&r2=155944&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp Tue May  1 16:10:26 2012
@@ -195,30 +195,26 @@
 
 //===----------------------------------------------------------------------===//
 
-SVal SValBuilder::makeGenericVal(ProgramStateRef State,
-                                     BinaryOperator::Opcode Op,
-                                     NonLoc LHS, NonLoc RHS,
-                                     QualType ResultTy) {
-  // If operands are tainted, create a symbol to ensure that we propagate taint.
-  if (State->isTainted(RHS) || State->isTainted(LHS)) {
-    const SymExpr *symLHS;
-    const SymExpr *symRHS;
-
-    if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) {
-      symLHS = LHS.getAsSymExpr();
-      return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
-    }
-
-    if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) {
-      symRHS = RHS.getAsSymExpr();
-      return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
-    }
+SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
+                                 BinaryOperator::Opcode Op,
+                                 NonLoc LHS, NonLoc RHS,
+                                 QualType ResultTy) {
+  const SymExpr *symLHS;
+  const SymExpr *symRHS;
 
+  if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) {
     symLHS = LHS.getAsSymExpr();
+    return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
+  }
+
+  if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) {
     symRHS = RHS.getAsSymExpr();
-    return makeNonLoc(symLHS, Op, symRHS, ResultTy);
+    return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
   }
-  return UnknownVal();
+
+  symLHS = LHS.getAsSymExpr();
+  symRHS = RHS.getAsSymExpr();
+  return makeNonLoc(symLHS, Op, symRHS, ResultTy);
 }
 
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=155944&r1=155943&r2=155944&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Tue May  1 16:10:26 2012
@@ -304,7 +304,7 @@
   while (1) {
     switch (lhs.getSubKind()) {
     default:
-      return makeGenericVal(state, op, lhs, rhs, resultTy);
+      return makeSymExprValNN(state, op, lhs, rhs, resultTy);
     case nonloc::LocAsIntegerKind: {
       Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
       switch (rhs.getSubKind()) {
@@ -327,7 +327,7 @@
               return makeTruthVal(true, resultTy);
             default:
               // This case also handles pointer arithmetic.
-              return makeGenericVal(state, op, lhs, rhs, resultTy);
+              return makeSymExprValNN(state, op, lhs, rhs, resultTy);
           }
       }
     }
@@ -389,9 +389,9 @@
             if (lhsValue == 0)
               // At this point lhs and rhs have been swapped.
               return rhs;
-            return makeGenericVal(state, op, rhs, lhs, resultTy);
+            return makeSymExprValNN(state, op, rhs, lhs, resultTy);
           default:
-            return makeGenericVal(state, op, rhs, lhs, resultTy);
+            return makeSymExprValNN(state, op, rhs, lhs, resultTy);
         }
       }
     }
@@ -406,7 +406,7 @@
             dyn_cast<SymIntExpr>(selhs->getSymbol());
 
         if (!symIntExpr)
-          return makeGenericVal(state, op, lhs, rhs, resultTy);
+          return makeSymExprValNN(state, op, lhs, rhs, resultTy);
 
         // Is this a logical not? (!x is represented as x == 0.)
         if (op == BO_EQ && rhs.isZeroConstant()) {
@@ -454,7 +454,7 @@
         // For now, only handle expressions whose RHS is a constant.
         const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
         if (!rhsInt)
-          return makeGenericVal(state, op, lhs, rhs, resultTy);
+          return makeSymExprValNN(state, op, lhs, rhs, resultTy);
 
         // If both the LHS and the current expression are additive,
         // fold their constants.
@@ -539,7 +539,7 @@
               resultTy);
         }
 
-        return makeGenericVal(state, op, lhs, rhs, resultTy);
+        return makeSymExprValNN(state, op, lhs, rhs, resultTy);
       }
     }
     }

Modified: cfe/trunk/test/Analysis/malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=155944&r1=155943&r2=155944&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.c (original)
+++ cfe/trunk/test/Analysis/malloc.c Tue May  1 16:10:26 2012
@@ -776,6 +776,13 @@
   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
+}
+
 // ----------------------------------------------------------------------------
 // Below are the known false positives.
 





More information about the cfe-commits mailing list