From 7ce351db56fbce162a3b650518ce05b5c61ebf36 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Mon, 1 Nov 2010 09:09:44 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117908 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checker/PathSensitive/GRExprEngine.h | 7 +++--- lib/Checker/AggExprVisitor.cpp | 12 +++++----- lib/Checker/GRCXXExprEngine.cpp | 9 +++++-- lib/Checker/GRExprEngine.cpp | 24 +++++++------------ test/Analysis/method-call.cpp | 2 +- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index 193d49baf5..d125befdbe 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -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. diff --git a/lib/Checker/AggExprVisitor.cpp b/lib/Checker/AggExprVisitor.cpp index 6d472f46b4..f31bcec73a 100644 --- a/lib/Checker/AggExprVisitor.cpp +++ b/lib/Checker/AggExprVisitor.cpp @@ -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 { - 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(E)); } diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp index c6be6b681d..890387632f 100644 --- a/lib/Checker/GRCXXExprEngine.cpp +++ b/lib/Checker/GRCXXExprEngine.cpp @@ -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); diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index d542c2c293..1669a353a5 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -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(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(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); diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp index 26b4a2fc13..a766da9aae 100644 --- a/test/Analysis/method-call.cpp +++ b/test/Analysis/method-call.cpp @@ -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; } -- 2.40.0