[cfe-commits] r162494 - in /cfe/trunk: lib/StaticAnalyzer/Core/ExprEngineC.cpp test/Analysis/operator-calls.cpp

Jordan Rose jordan_rose at apple.com
Thu Aug 23 16:01:39 PDT 2012


Author: jrose
Date: Thu Aug 23 18:01:39 2012
New Revision: 162494

URL: http://llvm.org/viewvc/llvm-project?rev=162494&view=rev
Log:
[analyzer] Handle UserDefinedConversion casts in C++.

This is trivial; the UserDefinedConversion always wraps a CXXMemberCallExpr
for the appropriate conversion function, so it's just a matter of
propagating that value to the CastExpr itself.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    cfe/trunk/test/Analysis/operator-calls.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=162494&r1=162493&r2=162494&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Thu Aug 23 18:01:39 2012
@@ -242,7 +242,9 @@
        I != E; ++I) {
     
     Pred = *I;
-    
+    ProgramStateRef state = Pred->getState();
+    const LocationContext *LCtx = Pred->getLocationContext();
+
     switch (CastE->getCastKind()) {
       case CK_LValueToRValue:
         llvm_unreachable("LValueToRValue casts handled earlier.");
@@ -262,6 +264,7 @@
       case CK_NonAtomicToAtomic:
         // True no-ops.
       case CK_NoOp:
+      case CK_UserDefinedConversion:
       case CK_FunctionToPointerDecay: {
         // Copy the SVal of Ex to CastE.
         ProgramStateRef state = Pred->getState();
@@ -299,8 +302,6 @@
       case CK_AnyPointerToBlockPointerCast:  
       case CK_ObjCObjectLValueCast: {
         // Delegate to SValBuilder to process.
-        ProgramStateRef state = Pred->getState();
-        const LocationContext *LCtx = Pred->getLocationContext();
         SVal V = state->getSVal(Ex, LCtx);
         V = svalBuilder.evalCast(V, T, ExTy);
         state = state->BindExpr(CastE, LCtx, V);
@@ -310,8 +311,6 @@
       case CK_DerivedToBase:
       case CK_UncheckedDerivedToBase: {
         // For DerivedToBase cast, delegate to the store manager.
-        ProgramStateRef state = Pred->getState();
-        const LocationContext *LCtx = Pred->getLocationContext();
         SVal val = state->getSVal(Ex, LCtx);
         val = getStoreManager().evalDerivedToBase(val, CastE);
         state = state->BindExpr(CastE, LCtx, val);
@@ -320,8 +319,6 @@
       }
       // Handle C++ dyn_cast.
       case CK_Dynamic: {
-        ProgramStateRef state = Pred->getState();
-        const LocationContext *LCtx = Pred->getLocationContext();
         SVal val = state->getSVal(Ex, LCtx);
 
         // Compute the type of the result.
@@ -369,7 +366,6 @@
       case CK_BaseToDerivedMemberPointer:
       case CK_DerivedToBaseMemberPointer:
       case CK_ReinterpretMemberPointer:
-      case CK_UserDefinedConversion:
       case CK_ConstructorConversion:
       case CK_VectorSplat:
       case CK_MemberPointerToBoolean:
@@ -378,12 +374,10 @@
         QualType resultType = CastE->getType();
         if (CastE->isGLValue())
           resultType = getContext().getPointerType(resultType);
-        const LocationContext *LCtx = Pred->getLocationContext();
         SVal result = svalBuilder.conjureSymbolVal(0, CastE, LCtx,
                                                    resultType,
                                                    currBldrCtx->blockCount());
-        ProgramStateRef state = Pred->getState()->BindExpr(CastE, LCtx,
-                                                               result);
+        state = state->BindExpr(CastE, LCtx, result);
         Bldr.generateNode(CastE, Pred, state);
         continue;
       }

Modified: cfe/trunk/test/Analysis/operator-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/operator-calls.cpp?rev=162494&r1=162493&r2=162494&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/operator-calls.cpp (original)
+++ cfe/trunk/test/Analysis/operator-calls.cpp Thu Aug 23 18:01:39 2012
@@ -30,3 +30,22 @@
 void testMemberOperator(IntComparable B) {
   clang_analyzer_eval(B == 0); // expected-warning{{TRUE}}
 }
+
+
+
+namespace UserDefinedConversions {
+  class Convertible {
+  public:
+    operator int() const {
+      return 42;
+    }
+    operator bool() const {
+      return true;
+    }
+  };
+
+  void test(const Convertible &obj) {
+    clang_analyzer_eval((int)obj == 42); // expected-warning{{TRUE}}
+    clang_analyzer_eval(obj); // expected-warning{{TRUE}}
+  }
+}





More information about the cfe-commits mailing list