[cfe-commits] r133041 - /cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp

Jordy Rose jediknil at belkadan.com
Tue Jun 14 21:55:49 PDT 2011


Author: jrose
Date: Tue Jun 14 23:55:49 2011
New Revision: 133041

URL: http://llvm.org/viewvc/llvm-project?rev=133041&view=rev
Log:
[analyzer] When performing a binary operation on symbolic operands, we convert the symbol values to a common type. But in a relational operation, the result is an 'int' or 'bool', which may not be the appropriate type to convert the operands to. In these cases, use the left-hand operand's type as the conversion type.

There's no associated test for this because fully-constrained symbolic values are evaluated ahead of time in normal expressions. This can only come up in checker-constructed expressions (like the ones in an upcoming patch to CStringChecker).

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=133041&r1=133040&r2=133041&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Tue Jun 14 23:55:49 2011
@@ -415,6 +415,24 @@
     case nonloc::ConcreteIntKind: {
       const nonloc::ConcreteInt& lhsInt = cast<nonloc::ConcreteInt>(lhs);
 
+      // Is the RHS a symbol we can simplify?
+      // FIXME: This was mostly copy/pasted from the LHS-is-a-symbol case.
+      if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
+        SymbolRef RSym = srhs->getSymbol();
+        if (RSym->getType(Context)->isIntegerType()) {
+          if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
+            // The symbol evaluates to a constant.
+            const llvm::APSInt *rhs_I;
+            if (BinaryOperator::isRelationalOp(op))
+              rhs_I = &BasicVals.Convert(lhsInt.getValue(), *Constant);
+            else
+              rhs_I = &BasicVals.Convert(resultTy, *Constant);
+
+            rhs = nonloc::ConcreteInt(*rhs_I);
+          }
+        }
+      }
+
       if (isa<nonloc::ConcreteInt>(rhs)) {
         return lhsInt.evalBinOp(*this, op, cast<nonloc::ConcreteInt>(rhs));
       } else {
@@ -461,13 +479,22 @@
     case nonloc::SymbolValKind: {
       nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
       SymbolRef Sym = slhs->getSymbol();
+      QualType lhsType = Sym->getType(Context);
+
+      // The conversion type is usually the result type, but not in the case
+      // of relational expressions.
+      QualType conversionType = resultTy;
+      if (BinaryOperator::isRelationalOp(op))
+        conversionType = lhsType;
+
       // Does the symbol simplify to a constant?  If so, "fold" the constant
       // by setting 'lhs' to a ConcreteInt and try again.
-      if (Sym->getType(Context)->isIntegerType())
+      if (lhsType->isIntegerType())
         if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
           // The symbol evaluates to a constant. If necessary, promote the
           // folded constant (LHS) to the result type.
-          const llvm::APSInt &lhs_I = BasicVals.Convert(resultTy, *Constant);
+          const llvm::APSInt &lhs_I = BasicVals.Convert(conversionType,
+                                                        *Constant);
           lhs = nonloc::ConcreteInt(lhs_I);
           
           // Also promote the RHS (if necessary).
@@ -479,7 +506,7 @@
           // Other operators: do an implicit conversion.  This shouldn't be
           // necessary once we support truncation/extension of symbolic values.
           if (nonloc::ConcreteInt *rhs_I = dyn_cast<nonloc::ConcreteInt>(&rhs)){
-            rhs = nonloc::ConcreteInt(BasicVals.Convert(resultTy,
+            rhs = nonloc::ConcreteInt(BasicVals.Convert(conversionType,
                                                         rhs_I->getValue()));
           }
           
@@ -492,7 +519,8 @@
         if (RSym->getType(Context)->isIntegerType()) {
           if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
             // The symbol evaluates to a constant.
-            const llvm::APSInt &rhs_I = BasicVals.Convert(resultTy, *Constant);
+            const llvm::APSInt &rhs_I = BasicVals.Convert(conversionType,
+                                                          *Constant);
             rhs = nonloc::ConcreteInt(rhs_I);
           }
         }





More information about the cfe-commits mailing list