[cfe-commits] r123374 - in /cfe/trunk: include/clang/StaticAnalyzer/PathSensitive/MemRegion.h lib/StaticAnalyzer/Checkers/ExprEngine.cpp lib/StaticAnalyzer/RegionStore.cpp test/Analysis/base-init.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Thu Jan 13 04:30:12 PST 2011
Author: zhongxingxu
Date: Thu Jan 13 06:30:12 2011
New Revision: 123374
URL: http://llvm.org/viewvc/llvm-project?rev=123374&view=rev
Log:
Support inlining base initializers. We still haven't got it completely right,
since the bindings are purged after they are set up. Need to investigate
RemoveDeadBindings algorithm.
Added:
cfe/trunk/test/Analysis/base-init.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/MemRegion.h
cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/RegionStore.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/MemRegion.h?rev=123374&r1=123373&r2=123374&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/MemRegion.h Thu Jan 13 06:30:12 2011
@@ -872,6 +872,8 @@
const CXXRecordDecl *decl, const MemRegion *sReg);
public:
+ const CXXRecordDecl *getDecl() const { return decl; }
+
QualType getValueType() const;
void dumpToStream(llvm::raw_ostream& os) const;
@@ -1012,6 +1014,14 @@
const CXXBaseObjectRegion *getCXXBaseObjectRegion(const CXXRecordDecl *decl,
const MemRegion *superRegion);
+ /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
+ /// super region.
+ const CXXBaseObjectRegion *
+ getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg,
+ const MemRegion *superRegion) {
+ return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion);
+ }
+
const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
CanQualType locTy,
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp?rev=123374&r1=123373&r2=123374&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp Thu Jan 13 06:30:12 2011
@@ -643,36 +643,52 @@
// We don't set EntryNode and currentStmt. And we don't clean up state.
const CXXCtorInitializer *BMI = Init.getInitializer();
- ExplodedNode *Pred = builder.getPredecessor();
- const LocationContext *LC = Pred->getLocationContext();
+ ExplodedNode *pred = builder.getPredecessor();
+
+ const StackFrameContext *stackFrame = cast<StackFrameContext>(pred->getLocationContext());
+ const CXXConstructorDecl *decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
+ const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
+
+ SVal thisVal = pred->getState()->getSVal(thisReg);
if (BMI->isAnyMemberInitializer()) {
ExplodedNodeSet Dst;
// Evaluate the initializer.
- Visit(BMI->getInit(), Pred, Dst);
+ Visit(BMI->getInit(), pred, Dst);
for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); I != E; ++I){
ExplodedNode *Pred = *I;
const GRState *state = Pred->getState();
const FieldDecl *FD = BMI->getAnyMember();
- const RecordDecl *RD = FD->getParent();
- const CXXThisRegion *ThisR = getCXXThisRegion(cast<CXXRecordDecl>(RD),
- cast<StackFrameContext>(LC));
- SVal ThisV = state->getSVal(ThisR);
- SVal FieldLoc = state->getLValue(FD, ThisV);
+ SVal FieldLoc = state->getLValue(FD, thisVal);
SVal InitVal = state->getSVal(BMI->getInit());
state = state->bindLoc(FieldLoc, InitVal);
// Use a custom node building process.
- PostInitializer PP(BMI, LC);
+ PostInitializer PP(BMI, stackFrame);
// Builder automatically add the generated node to the deferred set,
// which are processed in the builder's dtor.
builder.generateNode(PP, state, Pred);
}
+ return;
}
+
+ assert(BMI->isBaseInitializer());
+
+ // Get the base class declaration.
+ const CXXConstructExpr *ctorExpr = cast<CXXConstructExpr>(BMI->getInit());
+
+ // Create the base object region.
+ SVal baseVal =
+ getStoreManager().evalDerivedToBase(thisVal, ctorExpr->getType());
+ const MemRegion *baseReg = baseVal.getAsRegion();
+ assert(baseReg);
+ Builder = &builder;
+ ExplodedNodeSet dst;
+ VisitCXXConstructExpr(ctorExpr, baseReg, pred, dst);
}
void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
Modified: cfe/trunk/lib/StaticAnalyzer/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/RegionStore.cpp?rev=123374&r1=123373&r2=123374&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/RegionStore.cpp Thu Jan 13 06:30:12 2011
@@ -822,7 +822,8 @@
return derived;
const MemRegion *baseReg =
- MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion());
+ MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion());
+
return loc::MemRegionVal(baseReg);
}
//===----------------------------------------------------------------------===//
@@ -1105,6 +1106,17 @@
return std::make_pair(X.first,
MRMgr.getFieldRegionWithSuper(FR, X.second));
}
+ // C++ base object region is another kind of region that we should blast
+ // through to look for lazy compound value. It is like a field region.
+ else if (const CXXBaseObjectRegion *baseReg =
+ dyn_cast<CXXBaseObjectRegion>(R)) {
+ const std::pair<Store, const MemRegion *> &X =
+ GetLazyBinding(B, baseReg->getSuperRegion());
+
+ if (X.second)
+ return std::make_pair(X.first,
+ MRMgr.getCXXBaseObjectRegionWithSuper(baseReg, X.second));
+ }
// The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is
// possible for a valid lazy binding.
return std::make_pair((Store) 0, (const MemRegion *) 0);
@@ -1572,7 +1584,6 @@
Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R,
SVal DefaultVal) {
-
BindingKey key = BindingKey::Make(R, BindingKey::Default);
// The BindingKey may be "invalid" if we cannot handle the region binding
@@ -1582,7 +1593,7 @@
// the case of nested symbolic indices, we need to march up the region
// hierarchy untile we reach a region whose binding we can reason about.
const SubRegion *subReg = R;
-
+
while (!key.isValid()) {
if (const SubRegion *tmp = dyn_cast<SubRegion>(subReg->getSuperRegion())) {
subReg = tmp;
Added: cfe/trunk/test/Analysis/base-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/base-init.cpp?rev=123374&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/base-init.cpp (added)
+++ cfe/trunk/test/Analysis/base-init.cpp Thu Jan 13 06:30:12 2011
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store region -analyzer-inline-call -cfg-add-initializers -verify -analyzer-no-purge-dead %s
+
+class A {
+ int x;
+public:
+ A();
+ int getx() const {
+ return x;
+ }
+};
+
+A::A() : x(0) {
+}
+
+class B : public A {
+ int y;
+public:
+ B();
+};
+
+B::B() {
+}
+
+void f() {
+ B b;
+ if (b.getx() != 0) {
+ int *p = 0;
+ *p = 0; // no-warning
+ }
+}
More information about the cfe-commits
mailing list