[cfe-commits] r120173 - in /cfe/trunk: include/clang/Checker/PathSensitive/MemRegion.h include/clang/Checker/PathSensitive/Store.h lib/Checker/GRExprEngine.cpp lib/Checker/MemRegion.cpp lib/Checker/RegionStore.cpp test/Analysis/derived-to-base.cpp

Zhongxing Xu xuzhongxing at gmail.com
Fri Nov 26 00:21:53 PST 2010


Author: zhongxingxu
Date: Fri Nov 26 02:21:53 2010
New Revision: 120173

URL: http://llvm.org/viewvc/llvm-project?rev=120173&view=rev
Log:
Regionstore: support derived-to-base cast by creating a CXXBaseObjectRegion.

Added:
    cfe/trunk/test/Analysis/derived-to-base.cpp
Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/MemRegion.h
    cfe/trunk/include/clang/Checker/PathSensitive/Store.h
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/Checker/MemRegion.cpp
    cfe/trunk/lib/Checker/RegionStore.cpp

Modified: cfe/trunk/include/clang/Checker/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/MemRegion.h?rev=120173&r1=120172&r2=120173&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/MemRegion.h Fri Nov 26 02:21:53 2010
@@ -93,8 +93,9 @@
     VarRegionKind = BEG_DECL_REGIONS,
     FieldRegionKind,
     ObjCIvarRegionKind,
+    END_DECL_REGIONS = ObjCIvarRegionKind,
     CXXObjectRegionKind,
-    END_DECL_REGIONS = CXXObjectRegionKind,
+    CXXBaseObjectRegionKind,
     END_TYPED_REGIONS = END_DECL_REGIONS
   };
     
@@ -850,6 +851,31 @@
   }
 };
 
+// CXXBaseObjectRegion represents a base object within a C++ object. It is 
+// identified by the base class declaration and the region of its parent object.
+class CXXBaseObjectRegion : public TypedRegion {
+  friend class MemRegionManager;
+
+  const CXXRecordDecl *decl;
+
+  CXXBaseObjectRegion(const CXXRecordDecl *d, const MemRegion *sReg)
+    : TypedRegion(sReg, CXXBaseObjectRegionKind), decl(d) {}
+
+  static void ProfileRegion(llvm::FoldingSetNodeID &ID,
+                            const CXXRecordDecl *decl, const MemRegion *sReg);
+
+public:
+  QualType getValueType() const;
+
+  void dumpToStream(llvm::raw_ostream& os) const;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion *region) {
+    return region->getKind() == CXXBaseObjectRegionKind;
+  }
+};
+
 template<typename RegionTy>
 const RegionTy* MemRegion::getAs() const {
   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
@@ -976,6 +1002,9 @@
   const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex,
                                             LocationContext const *LC);
 
+  const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
+                                                  const MemRegion *superRegion);
+
   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
                                             CanQualType locTy,

Modified: cfe/trunk/include/clang/Checker/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/Store.h?rev=120173&r1=120172&r2=120173&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/Store.h Fri Nov 26 02:21:53 2010
@@ -130,6 +130,11 @@
   ///  conversions between arrays and pointers.
   virtual SVal ArrayToPointer(Loc Array) = 0;
 
+  /// Evaluates DerivedToBase casts.
+  virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType) {
+    return UnknownVal();
+  }
+
   class CastResult {
     const GRState *state;
     const MemRegion *region;

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=120173&r1=120172&r2=120173&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Fri Nov 26 02:21:53 2010
@@ -2688,8 +2688,7 @@
   case CK_IntegralComplexToFloatingComplex:
   case CK_AnyPointerToObjCPointerCast:
   case CK_AnyPointerToBlockPointerCast:
-  case CK_DerivedToBase:
-  case CK_UncheckedDerivedToBase:
+  
   case CK_ObjCObjectLValueCast: {
     // Delegate to SValuator to process.
     for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
@@ -2702,7 +2701,20 @@
     }
     return;
   }
-  
+
+  case CK_DerivedToBase:
+  case CK_UncheckedDerivedToBase:
+    // For DerivedToBase cast, delegate to the store manager.
+    for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) {
+      ExplodedNode *node = *I;
+      const GRState *state = GetState(node);
+      SVal val = state->getSVal(Ex);
+      val = getStoreManager().evalDerivedToBase(val, T);
+      state = state->BindExpr(CastE, val);
+      MakeNode(Dst, CastE, node, state);
+    }
+    return;
+
   // Various C++ casts that are not handled yet.
   case CK_Dynamic:  
   case CK_ToUnion:

Modified: cfe/trunk/lib/Checker/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MemRegion.cpp?rev=120173&r1=120172&r2=120173&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MemRegion.cpp (original)
+++ cfe/trunk/lib/Checker/MemRegion.cpp Fri Nov 26 02:21:53 2010
@@ -218,6 +218,10 @@
   return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy);
 }
 
+QualType CXXBaseObjectRegion::getValueType() const {
+  return QualType(decl->getTypeForDecl(), 0);
+}
+
 //===----------------------------------------------------------------------===//
 // FoldingSet profiling.
 //===----------------------------------------------------------------------===//
@@ -367,6 +371,17 @@
   ProfileRegion(ID, Ex, getSuperRegion());
 }
 
+void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
+                                        const CXXRecordDecl *decl,
+                                        const MemRegion *sReg) {
+  ID.AddPointer(decl);
+  ID.AddPointer(sReg);
+}
+
+void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  ProfileRegion(ID, decl, superRegion);
+}
+
 //===----------------------------------------------------------------------===//
 // Region pretty-printing.
 //===----------------------------------------------------------------------===//
@@ -411,6 +426,10 @@
   os << "temp_object";
 }
 
+void CXXBaseObjectRegion::dumpToStream(llvm::raw_ostream &os) const {
+  os << "base " << decl->getName();
+}
+
 void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
   os << "this";
 }
@@ -687,6 +706,12 @@
   return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
 }
 
+const CXXBaseObjectRegion *
+MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl,
+                                         const MemRegion *superRegion) {
+  return getSubRegion<CXXBaseObjectRegion>(decl, superRegion);
+}
+
 const CXXThisRegion*
 MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
                                    const LocationContext *LC) {

Modified: cfe/trunk/lib/Checker/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/RegionStore.cpp?rev=120173&r1=120172&r2=120173&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/RegionStore.cpp (original)
+++ cfe/trunk/lib/Checker/RegionStore.cpp Fri Nov 26 02:21:53 2010
@@ -224,6 +224,9 @@
   ///  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);
+
   SVal EvalBinOp(BinaryOperator::Opcode Op,Loc L, NonLoc R, QualType resultTy);
 
   Store getInitialStore(const LocationContext *InitLoc) {
@@ -804,6 +807,14 @@
   return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx));
 }
 
+SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType basePtrType) {
+  const CXXRecordDecl *baseDecl = basePtrType->getCXXRecordDeclForPointerType();
+  assert(baseDecl && "not a CXXRecordDecl?");
+  loc::MemRegionVal &derivedRegVal = cast<loc::MemRegionVal>(derived);
+  const MemRegion *baseReg = 
+    MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal.getRegion());
+  return loc::MemRegionVal(baseReg);
+}
 //===----------------------------------------------------------------------===//
 // Pointer arithmetic.
 //===----------------------------------------------------------------------===//
@@ -869,6 +880,7 @@
     case MemRegion::FieldRegionKind:
     case MemRegion::ObjCIvarRegionKind:
     case MemRegion::CXXObjectRegionKind:
+    case MemRegion::CXXBaseObjectRegionKind:
       return UnknownVal();
 
     case MemRegion::FunctionTextRegionKind:

Added: cfe/trunk/test/Analysis/derived-to-base.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/derived-to-base.cpp?rev=120173&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/derived-to-base.cpp (added)
+++ cfe/trunk/test/Analysis/derived-to-base.cpp Fri Nov 26 02:21:53 2010
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region %s
+
+class A {
+protected:
+  int x;
+};
+
+class B : public A {
+public:
+  void f();
+};
+
+void B::f() {
+  x = 3;
+}





More information about the cfe-commits mailing list