Now initializer of C++ record type is visited as block-level expr.

Let the destination of AggExprVisitor be an explicit MemRegion. 
Reenable the test case.

llvm-svn: 117908
This commit is contained in:
Zhongxing Xu 2010-11-01 09:09:44 +00:00
parent 0b51d4db8c
commit 627a1868d2
5 changed files with 26 additions and 28 deletions

View File

@ -412,9 +412,8 @@ public:
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
ExplodedNodeSet & Dst);
void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest,
ExplodedNode *Pred, ExplodedNodeSet &Dst);
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@ -425,7 +424,7 @@ public:
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
void VisitAggExpr(const Expr *E, const MemRegion *Dest, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
/// Create a C++ temporary object for an rvalue.

View File

@ -26,15 +26,15 @@ namespace {
/// cast and construct exprs (and others), and at the final point, dispatches
/// back to the GRExprEngine to let the real evaluation logic happen.
class AggExprVisitor : public StmtVisitor<AggExprVisitor> {
SVal DestPtr;
const MemRegion *Dest;
ExplodedNode *Pred;
ExplodedNodeSet &DstSet;
GRExprEngine &Eng;
public:
AggExprVisitor(SVal dest, ExplodedNode *N, ExplodedNodeSet &dst,
AggExprVisitor(const MemRegion *dest, ExplodedNode *N, ExplodedNodeSet &dst,
GRExprEngine &eng)
: DestPtr(dest), Pred(N), DstSet(dst), Eng(eng) {}
: Dest(dest), Pred(N), DstSet(dst), Eng(eng) {}
void VisitCastExpr(CastExpr *E);
void VisitCXXConstructExpr(CXXConstructExpr *E);
@ -53,10 +53,10 @@ void AggExprVisitor::VisitCastExpr(CastExpr *E) {
}
void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) {
Eng.VisitCXXConstructExpr(E, DestPtr, Pred, DstSet);
Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet);
}
void GRExprEngine::VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
void GRExprEngine::VisitAggExpr(const Expr *E, const MemRegion *Dest,
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E));
}

View File

@ -91,9 +91,14 @@ void GRExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
}
}
void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
const MemRegion *Dest,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
if (!Dest)
Dest = ValMgr.getRegionManager().getCXXObjectRegion(E,
Pred->getLocationContext());
if (E->isElidable()) {
VisitAggExpr(E->getArg(0), Dest, Pred, Dst);
return;
@ -124,7 +129,7 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
const GRState *state = GetState(*NI);
// Setup 'this' region, so that the ctor is evaluated on the object pointed
// by 'Dest'.
state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest));
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
if (N)
Dst.Add(N);

View File

@ -679,7 +679,6 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
// C++ stuff we don't support yet.
case Stmt::CXXBindTemporaryExprClass:
case Stmt::CXXCatchStmtClass:
case Stmt::CXXConstructExprClass:
case Stmt::CXXDefaultArgExprClass:
case Stmt::CXXDependentScopeMemberExprClass:
case Stmt::CXXExprWithTemporariesClass:
@ -810,6 +809,14 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
}
case Stmt::CXXConstructExprClass: {
const CXXConstructExpr *C = cast<CXXConstructExpr>(S);
// For block-level CXXConstructExpr, we don't have a destination region.
// Let VisitCXXConstructExpr() create one.
VisitCXXConstructExpr(C, 0, Pred, Dst);
break;
}
case Stmt::CXXMemberCallExprClass: {
const CXXMemberCallExpr *MCE = cast<CXXMemberCallExpr>(S);
VisitCXXMemberCallExpr(MCE, Pred, Dst);
@ -2592,20 +2599,7 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
ExplodedNodeSet Tmp;
if (InitEx) {
QualType InitTy = InitEx->getType();
if (getContext().getLangOptions().CPlusPlus && InitTy->isRecordType()) {
// Delegate expressions of C++ record type evaluation to AggExprVisitor.
VisitAggExpr(InitEx, GetState(Pred)->getLValue(VD,
Pred->getLocationContext()), Pred, Tmp);
// FIXME: remove later when all paths through VisitAggExpr work properly
if (Tmp.empty())
Tmp.Add(Pred);
// Call checkers for initialized aggregates
CheckerVisit(DS, Dst, Tmp, PreVisitStmtCallback);
return;
} else if (VD->getType()->isReferenceType())
if (VD->getType()->isReferenceType())
VisitLValue(InitEx, Pred, Tmp);
else
Visit(InitEx, Pred, Tmp);

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
// XFAIL: *
struct A {
int x;
A(int a) { x = a; }