]> granicus.if.org Git - clang/commitdiff
[analyzer] Introduce IntSymExpr, where the integer is on the lhs.
authorAnna Zaks <ganna@apple.com>
Sat, 10 Dec 2011 23:36:51 +0000 (23:36 +0000)
committerAnna Zaks <ganna@apple.com>
Sat, 10 Dec 2011 23:36:51 +0000 (23:36 +0000)
Fix a bug in SimpleSValBuilder, where we should swap lhs and rhs when calling generateUnknownVal(), - the function which creates symbolic expressions when data is tainted. The issue is not visible when we only create the expressions for taint since all expressions are commutative from taint perspective.

Refactor SymExpr::symbol_iterator::expand() to use a switch instead of a chain of ifs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146336 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ProgramState.cpp
lib/StaticAnalyzer/Core/SValBuilder.cpp
lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
lib/StaticAnalyzer/Core/SymbolManager.cpp

index 807def26ff2c16e140848706e2fbe18a4f818e6c..43b0b3e9423bb099a38cce1c8a30157bd1f16b55 100644 (file)
@@ -565,6 +565,8 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) {
       return scan(cast<SymbolCast>(sym)->getOperand());
     case SymExpr::SymIntKind:
       return scan(cast<SymIntExpr>(sym)->getLHS());
+    case SymExpr::IntSymKind:
+      return scan(cast<IntSymExpr>(sym)->getRHS());
     case SymExpr::SymSymKind: {
       const SymSymExpr *x = cast<SymSymExpr>(sym);
       return scan(x->getLHS()) && scan(x->getRHS());
index f381f1a5ad9b6da4a6637cfd3bad036a42ba6fc9..81f84f90ae8d1f5c84ba6eee1d2b4899da7b4ff3 100644 (file)
@@ -47,6 +47,14 @@ NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
   return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
 }
 
+NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs,
+                               BinaryOperator::Opcode op, const SymExpr *rhs,
+                               QualType type) {
+  assert(rhs);
+  assert(!Loc::isLocType(type));
+  return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type));
+}
+
 NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const SymExpr *rhs, QualType type) {
   assert(lhs && rhs);
@@ -173,6 +181,11 @@ SVal SValBuilder::generateUnknownVal(const ProgramState *State,
       return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
     }
 
+    if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS)) {
+      symRHS = RHS.getAsSymExpr();
+      return makeNonLoc(symRHS, Op, lInt->getValue(), ResultTy);
+    }
+
     symLHS = LHS.getAsSymExpr();
     symRHS = RHS.getAsSymExpr();
     return makeNonLoc(symLHS, Op, symRHS, ResultTy);
index a7b67fbe8a50b2ddd3abc56d2d88c546810e564e..70901aa60892e9b75798dad37f325fcfc72bf576 100644 (file)
@@ -388,9 +388,9 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
             if (lhsValue == 0)
               // At this point lhs and rhs have been swapped.
               return rhs;
-            return generateUnknownVal(state, op, lhs, rhs, resultTy);
+            return generateUnknownVal(state, op, rhs, lhs, resultTy);
           default:
-            return generateUnknownVal(state, op, lhs, rhs, resultTy);
+            return generateUnknownVal(state, op, rhs, lhs, resultTy);
         }
       }
     }
index e79075f4121e9793e50b02571f85f0beedb39bf4..6f5d8f90bbdbd9d41cd9fbe2dc0feae7878dcf91 100644 (file)
@@ -57,6 +57,15 @@ void SymIntExpr::dumpToStream(raw_ostream &os) const {
   if (getRHS().isUnsigned()) os << 'U';
 }
 
+void IntSymExpr::dumpToStream(raw_ostream &os) const {
+  os << ' ' << getLHS().getZExtValue();
+  if (getLHS().isUnsigned()) os << 'U';
+  print(os, getOpcode());
+  os << '(';
+  getRHS()->dumpToStream(os);
+  os << ") ";
+}
+
 void SymSymExpr::dumpToStream(raw_ostream &os) const {
   os << '(';
   getLHS()->dumpToStream(os);
@@ -125,20 +134,29 @@ void SymExpr::symbol_iterator::expand() {
   const SymExpr *SE = itr.back();
   itr.pop_back();
 
-  if (const SymbolCast *SC = dyn_cast<SymbolCast>(SE)) {
-    itr.push_back(SC->getOperand());
-    return;
-  }
-  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
-    itr.push_back(SIE->getLHS());
-    return;
-  }
-  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
-    itr.push_back(SSE->getLHS());
-    itr.push_back(SSE->getRHS());
-    return;
+  switch (SE->getKind()) {
+    case SymExpr::RegionValueKind:
+    case SymExpr::ConjuredKind:
+    case SymExpr::DerivedKind:
+    case SymExpr::ExtentKind:
+    case SymExpr::MetadataKind:
+      return;
+    case SymExpr::CastSymbolKind:
+      itr.push_back(cast<SymbolCast>(SE)->getOperand());
+      return;
+    case SymExpr::SymIntKind:
+      itr.push_back(cast<SymIntExpr>(SE)->getLHS());
+      return;
+    case SymExpr::IntSymKind:
+      itr.push_back(cast<IntSymExpr>(SE)->getRHS());
+      return;
+    case SymExpr::SymSymKind: {
+      const SymSymExpr *x = cast<SymSymExpr>(SE);
+      itr.push_back(x->getLHS());
+      itr.push_back(x->getRHS());
+      return;
+    }
   }
-
   llvm_unreachable("unhandled expansion case");
 }
 
@@ -262,6 +280,24 @@ const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
   return cast<SymIntExpr>(data);
 }
 
+const IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs,
+                                               BinaryOperator::Opcode op,
+                                               const SymExpr *rhs,
+                                               QualType t) {
+  llvm::FoldingSetNodeID ID;
+  IntSymExpr::Profile(ID, lhs, op, rhs, t);
+  void *InsertPos;
+  SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (!data) {
+    data = (IntSymExpr*) BPAlloc.Allocate<IntSymExpr>();
+    new (data) IntSymExpr(lhs, op, rhs, t);
+    DataSet.InsertNode(data, InsertPos);
+  }
+
+  return cast<IntSymExpr>(data);
+}
+
 const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
                                                BinaryOperator::Opcode op,
                                                const SymExpr *rhs,