[cfe-commits] r165078 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/Store.h lib/StaticAnalyzer/Core/RegionStore.cpp lib/StaticAnalyzer/Core/Store.cpp

Jordan Rose jordan_rose at apple.com
Tue Oct 2 18:08:32 PDT 2012


Author: jrose
Date: Tue Oct  2 20:08:32 2012
New Revision: 165078

URL: http://llvm.org/viewvc/llvm-project?rev=165078&view=rev
Log:
[analyzer] Push evalDynamicCast and evalDerivedToBase up to Store.

These functions are store-agnostic, and would benefit from information in
DynamicTypeInfo but gain nothing from the store type.

No intended functionality change.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=165078&r1=165077&r2=165078&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Tue Oct  2 20:08:32 2012
@@ -25,6 +25,7 @@
 class Stmt;
 class Expr;
 class ObjCIvarDecl;
+class CXXBasePath;
 class StackFrameContext;
 
 namespace ento {
@@ -125,11 +126,15 @@
   ///  conversions between arrays and pointers.
   virtual SVal ArrayToPointer(Loc Array) = 0;
 
-  /// Evaluates DerivedToBase casts.
-  SVal evalDerivedToBase(SVal derived, const CastExpr *Cast);
+  /// Evaluates a chain of derived-to-base casts through the path specified in
+  /// \p Cast.
+  SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast);
+
+  /// Evaluates a chain of derived-to-base casts through the specified path.
+  SVal evalDerivedToBase(SVal Derived, const CXXBasePath &CastPath);
 
   /// Evaluates a derived-to-base cast through a single level of derivation.
-  virtual SVal evalDerivedToBase(SVal derived, QualType derivedPtrType) = 0;
+  SVal evalDerivedToBase(SVal Derived, QualType DerivedPtrType);
 
   /// \brief Evaluates C++ dynamic_cast cast.
   /// The callback may result in the following 3 scenarios:
@@ -139,8 +144,7 @@
   ///    enough info to determine if the cast will succeed at run time).
   /// The function returns an SVal representing the derived class; it's
   /// valid only if Failed flag is set to false.
-  virtual SVal evalDynamicCast(SVal base, QualType derivedPtrType,
-                                 bool &Failed) = 0;
+  SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed);
 
   const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=165078&r1=165077&r2=165078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Tue Oct  2 20:08:32 2012
@@ -15,9 +15,6 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/CXXInheritance.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Basic/TargetInfo.h"
@@ -193,19 +190,6 @@
   ///  casts from arrays to pointers.
   SVal ArrayToPointer(Loc Array);
 
-  /// For DerivedToBase casts, create a CXXBaseObjectRegion and return it.
-  virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType);
-
-  /// \brief Evaluates C++ dynamic_cast cast.
-  /// The callback may result in the following 3 scenarios:
-  ///  - Successful cast (ex: derived is subclass of base).
-  ///  - Failed cast (ex: derived is definitely not a subclass of base).
-  ///  - We don't know (base is a symbolic region and we don't have 
-  ///    enough info to determine if the cast will succeed at run time).
-  /// The function returns an SVal representing the derived class; it's
-  /// valid only if Failed flag is set to false.
-  virtual SVal evalDynamicCast(SVal base, QualType derivedPtrType,bool &Failed);
-
   StoreRef getInitialStore(const LocationContext *InitLoc) {
     return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *this);
   }
@@ -900,88 +884,6 @@
   return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx));
 }
 
-SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType baseType) {
-  loc::MemRegionVal *derivedRegVal = dyn_cast<loc::MemRegionVal>(&derived);
-  if (!derivedRegVal)
-    return derived;
-
-  const CXXRecordDecl *baseDecl = baseType->getPointeeCXXRecordDecl();
-  if (!baseDecl)
-    baseDecl = baseType->getAsCXXRecordDecl();
-  assert(baseDecl && "not a C++ object?");
-
-  const MemRegion *baseReg = 
-    MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion()); 
-
-  return loc::MemRegionVal(baseReg);
-}
-
-SVal RegionStoreManager::evalDynamicCast(SVal base, QualType derivedType,
-                                         bool &Failed) {
-  Failed = false;
-
-  loc::MemRegionVal *baseRegVal = dyn_cast<loc::MemRegionVal>(&base);
-  if (!baseRegVal)
-    return UnknownVal();
-  const MemRegion *BaseRegion = baseRegVal->stripCasts(/*StripBases=*/false);
-
-  // Assume the derived class is a pointer or a reference to a CXX record.
-  derivedType = derivedType->getPointeeType();
-  assert(!derivedType.isNull());
-  const CXXRecordDecl *DerivedDecl = derivedType->getAsCXXRecordDecl();
-  if (!DerivedDecl && !derivedType->isVoidType())
-    return UnknownVal();
-
-  // Drill down the CXXBaseObject chains, which represent upcasts (casts from
-  // derived to base).
-  const MemRegion *SR = BaseRegion;
-  while (const TypedRegion *TSR = dyn_cast_or_null<TypedRegion>(SR)) {
-    QualType BaseType = TSR->getLocationType()->getPointeeType();
-    assert(!BaseType.isNull());
-    const CXXRecordDecl *SRDecl = BaseType->getAsCXXRecordDecl();
-    if (!SRDecl)
-      return UnknownVal();
-
-    // If found the derived class, the cast succeeds.
-    if (SRDecl == DerivedDecl)
-      return loc::MemRegionVal(TSR);
-
-    if (!derivedType->isVoidType()) {
-      // Static upcasts are marked as DerivedToBase casts by Sema, so this will
-      // only happen when multiple or virtual inheritance is involved.
-      CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
-                         /*DetectVirtual=*/false);
-      if (SRDecl->isDerivedFrom(DerivedDecl, Paths)) {
-        SVal Result = loc::MemRegionVal(TSR);
-        const CXXBasePath &Path = *Paths.begin();
-        for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end();
-             I != E; ++I) {
-          Result = evalDerivedToBase(Result, I->Base->getType());
-        }
-        return Result;
-      }
-    }
-
-    if (const CXXBaseObjectRegion *R = dyn_cast<CXXBaseObjectRegion>(TSR))
-      // Drill down the chain to get the derived classes.
-      SR = R->getSuperRegion();
-    else {
-      // We reached the bottom of the hierarchy.
-
-      // If this is a cast to void*, return the region.
-      if (derivedType->isVoidType())
-        return loc::MemRegionVal(TSR);
-
-      // We did not find the derived class. We we must be casting the base to
-      // derived, so the cast should fail.
-      Failed = true;
-      return UnknownVal();
-    }
-  }
-
-  return UnknownVal();
-}
-
 //===----------------------------------------------------------------------===//
 // Loading values from regions.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp?rev=165078&r1=165077&r2=165078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp Tue Oct  2 20:08:32 2012
@@ -15,6 +15,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
 
 using namespace clang;
@@ -233,6 +234,91 @@
   return Result;
 }
 
+SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
+  // Walk through the path to create nested CXXBaseRegions.
+  SVal Result = Derived;
+  for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end();
+       I != E; ++I) {
+    Result = evalDerivedToBase(Result, I->Base->getType());
+  }
+  return Result;
+}
+
+SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType) {
+  loc::MemRegionVal *DerivedRegVal = dyn_cast<loc::MemRegionVal>(&Derived);
+  if (!DerivedRegVal)
+    return Derived;
+
+  const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
+  if (!BaseDecl)
+    BaseDecl = BaseType->getAsCXXRecordDecl();
+  assert(BaseDecl && "not a C++ object?");
+
+  const MemRegion *BaseReg =
+    MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion());
+
+  return loc::MemRegionVal(BaseReg);
+}
+
+SVal StoreManager::evalDynamicCast(SVal Base, QualType DerivedType,
+                                   bool &Failed) {
+  Failed = false;
+
+  loc::MemRegionVal *BaseRegVal = dyn_cast<loc::MemRegionVal>(&Base);
+  if (!BaseRegVal)
+    return UnknownVal();
+  const MemRegion *BaseRegion = BaseRegVal->stripCasts(/*StripBases=*/false);
+
+  // Assume the derived class is a pointer or a reference to a CXX record.
+  DerivedType = DerivedType->getPointeeType();
+  assert(!DerivedType.isNull());
+  const CXXRecordDecl *DerivedDecl = DerivedType->getAsCXXRecordDecl();
+  if (!DerivedDecl && !DerivedType->isVoidType())
+    return UnknownVal();
+
+  // Drill down the CXXBaseObject chains, which represent upcasts (casts from
+  // derived to base).
+  const MemRegion *SR = BaseRegion;
+  while (const TypedRegion *TSR = dyn_cast_or_null<TypedRegion>(SR)) {
+    QualType BaseType = TSR->getLocationType()->getPointeeType();
+    assert(!BaseType.isNull());
+    const CXXRecordDecl *SRDecl = BaseType->getAsCXXRecordDecl();
+    if (!SRDecl)
+      return UnknownVal();
+
+    // If found the derived class, the cast succeeds.
+    if (SRDecl == DerivedDecl)
+      return loc::MemRegionVal(TSR);
+
+    if (!DerivedType->isVoidType()) {
+      // Static upcasts are marked as DerivedToBase casts by Sema, so this will
+      // only happen when multiple or virtual inheritance is involved.
+      CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
+                         /*DetectVirtual=*/false);
+      if (SRDecl->isDerivedFrom(DerivedDecl, Paths))
+        return evalDerivedToBase(loc::MemRegionVal(TSR), Paths.front());
+    }
+
+    if (const CXXBaseObjectRegion *R = dyn_cast<CXXBaseObjectRegion>(TSR))
+      // Drill down the chain to get the derived classes.
+      SR = R->getSuperRegion();
+    else {
+      // We reached the bottom of the hierarchy.
+
+      // If this is a cast to void*, return the region.
+      if (DerivedType->isVoidType())
+        return loc::MemRegionVal(TSR);
+
+      // We did not find the derived class. We we must be casting the base to
+      // derived, so the cast should fail.
+      Failed = true;
+      return UnknownVal();
+    }
+  }
+  
+  return UnknownVal();
+}
+
 
 /// CastRetrievedVal - Used by subclasses of StoreManager to implement
 ///  implicit casts that arise from loads from regions that are reinterpreted





More information about the cfe-commits mailing list