diff options
-rw-r--r-- | include/clang/Checker/PathSensitive/GRExprEngine.h | 5 | ||||
-rw-r--r-- | lib/Checker/AggExprVisitor.cpp | 54 | ||||
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 4 |
3 files changed, 62 insertions, 1 deletions
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h index dd8e71ed9b..d95f3c2454 100644 --- a/include/clang/Checker/PathSensitive/GRExprEngine.h +++ b/include/clang/Checker/PathSensitive/GRExprEngine.h @@ -216,7 +216,7 @@ public: const GRState* St, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, const void *tag = 0); -protected: + /// CheckerVisit - Dispatcher for performing checker-specific logic /// at specific statements. void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, @@ -351,6 +351,9 @@ protected: void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + /// Create a C++ temporary object for an rvalue. void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); diff --git a/lib/Checker/AggExprVisitor.cpp b/lib/Checker/AggExprVisitor.cpp new file mode 100644 index 0000000000..5f55ab869c --- /dev/null +++ b/lib/Checker/AggExprVisitor.cpp @@ -0,0 +1,54 @@ +//=-- AggExprVisitor.cpp - evaluating expressions of C++ class type -*- C++ -*-= +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines AggExprVisitor class, which contains lots of boiler +// plate code for evaluating expressions of C++ class type. +// +//===----------------------------------------------------------------------===// + +#include "clang/Checker/PathSensitive/GRExprEngine.h" +#include "clang/AST/StmtVisitor.h" + +using namespace clang; + +namespace { +class AggExprVisitor : public StmtVisitor<AggExprVisitor> { + SVal DestPtr; + ExplodedNode *Pred; + ExplodedNodeSet &DstSet; + GRExprEngine &Eng; + +public: + AggExprVisitor(SVal dest, ExplodedNode *N, ExplodedNodeSet &dst, + GRExprEngine &eng) + : DestPtr(dest), Pred(N), DstSet(dst), Eng(eng) {} + + void VisitCastExpr(CastExpr *E); + void VisitCXXConstructExpr(CXXConstructExpr *E); +}; +} + +void AggExprVisitor::VisitCastExpr(CastExpr *E) { + switch (E->getCastKind()) { + default: + assert(0 && "Unhandled cast kind"); + case CastExpr::CK_ConstructorConversion: + Visit(E->getSubExpr()); + break; + } +} + +void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) { + Eng.VisitCXXConstructExpr(E, DestPtr, Pred, DstSet); +} + +void GRExprEngine::VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred, + ExplodedNodeSet &Dst) { + AggExprVisitor(Dest, Pred, Dst, *this).Visit(const_cast<Expr *>(E)); +} diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 0604f8a4e5..553f949d87 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -3138,6 +3138,10 @@ void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest, ExplodedNode *Pred, ExplodedNodeSet &Dst) { + if (E->isElidable()) { + VisitAggExpr(E->getArg(0), Dest, Pred, Dst); + return; + } const CXXConstructorDecl *CD = E->getConstructor(); assert(CD); |