[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