forked from OSchip/llvm-project
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:
parent
0b51d4db8c
commit
627a1868d2
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Reference in New Issue