aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/AnalysisContext.cpp9
-rw-r--r--lib/Analysis/CFG.cpp131
-rw-r--r--lib/Analysis/PseudoConstantAnalysis.cpp7
-rw-r--r--lib/Analysis/ReachableCode.cpp6
-rw-r--r--lib/Checker/AggExprVisitor.cpp2
-rw-r--r--lib/Checker/BugReporterVisitors.cpp5
-rw-r--r--lib/Checker/DereferenceChecker.cpp5
-rw-r--r--lib/Checker/Environment.cpp3
-rw-r--r--lib/Checker/GRCXXExprEngine.cpp20
-rw-r--r--lib/Checker/GRCoreEngine.cpp2
-rw-r--r--lib/Checker/GRExprEngine.cpp571
11 files changed, 206 insertions, 555 deletions
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index 5307074dce..4305507c9c 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -152,8 +152,7 @@ void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
}
void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAnalysisContext(), getParent(), CallSite.getPointer(),
- CallSite.getInt(), Block, Index);
+ Profile(ID, getAnalysisContext(), getParent(), CallSite, Block, Index);
}
void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
@@ -189,15 +188,15 @@ LocationContextManager::getLocationContext(AnalysisContext *ctx,
const StackFrameContext*
LocationContextManager::getStackFrame(AnalysisContext *ctx,
const LocationContext *parent,
- const Stmt *s, bool asLValue,
+ const Stmt *s,
const CFGBlock *blk, unsigned idx) {
llvm::FoldingSetNodeID ID;
- StackFrameContext::Profile(ID, ctx, parent, s, asLValue, blk, idx);
+ StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
void *InsertPos;
StackFrameContext *L =
cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
if (!L) {
- L = new StackFrameContext(ctx, parent, s, asLValue, blk, idx);
+ L = new StackFrameContext(ctx, parent, s, blk, idx);
Contexts.InsertNode(L, InsertPos);
}
return L;
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 35d93867c1..0f32614d2b 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -32,7 +32,6 @@ static SourceLocation GetEndLoc(Decl* D) {
if (VarDecl* VD = dyn_cast<VarDecl>(D))
if (Expr* Ex = VD->getInit())
return Ex->getSourceRange().getEnd();
-
return D->getLocation();
}
@@ -49,22 +48,13 @@ static SourceLocation GetEndLoc(Decl* D) {
/// the builder has an option not to add a subexpression as a
/// block-level expression.
///
-/// The lvalue bit captures whether or not a subexpression needs to
-/// be processed as an lvalue. That information needs to be recorded
-/// in the CFG for block-level expressions so that analyses do the
-/// right thing when traversing the CFG (since such subexpressions
-/// will be seen before their parent expression is processed).
class AddStmtChoice {
public:
- enum Kind { NotAlwaysAdd = 0,
- AlwaysAdd = 1,
- AsLValueNotAlwaysAdd = 2,
- AsLValueAlwaysAdd = 3 };
+ enum Kind { NotAlwaysAdd = 0, AlwaysAdd = 1 };
AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {}
bool alwaysAdd() const { return kind & AlwaysAdd; }
- bool asLValue() const { return kind >= AsLValueNotAlwaysAdd; }
/// Return a copy of this object, except with the 'always-add' bit
/// set as specified.
@@ -73,13 +63,6 @@ public:
Kind(kind & ~AlwaysAdd));
}
- /// Return a copy of this object, except with the 'as-lvalue' bit
- /// set as specified.
- AddStmtChoice withAsLValue(bool asLVal) const {
- return AddStmtChoice(asLVal ? Kind(kind | AsLValueNotAlwaysAdd) :
- Kind(kind & ~AsLValueNotAlwaysAdd));
- }
-
private:
Kind kind;
};
@@ -372,9 +355,9 @@ private:
void addLocalScopeAndDtors(Stmt* S);
// Interface to CFGBlock - adding CFGElements.
- void AppendStmt(CFGBlock *B, Stmt *S,
+ void appendStmt(CFGBlock *B, Stmt *S,
AddStmtChoice asc = AddStmtChoice::AlwaysAdd) {
- B->appendStmt(S, cfg->getBumpVectorContext(), asc.asLValue());
+ B->appendStmt(S, cfg->getBumpVectorContext());
}
void appendInitializer(CFGBlock *B, CXXBaseOrMemberInitializer *I) {
B->appendInitializer(I, cfg->getBumpVectorContext());
@@ -568,12 +551,12 @@ CFGBlock *CFGBuilder::addInitializer(CXXBaseOrMemberInitializer *I) {
appendInitializer(Block, I);
if (Init) {
- AddStmtChoice asc = AddStmtChoice().withAsLValue(IsReference);
- if (HasTemporaries)
+ if (HasTemporaries) {
// For expression with temporaries go directly to subexpression to omit
// generating destructors for the second time.
- return Visit(cast<ExprWithCleanups>(Init)->getSubExpr(), asc);
- return Visit(Init, asc);
+ return Visit(cast<ExprWithCleanups>(Init)->getSubExpr());
+ }
+ return Visit(Init);
}
return Block;
@@ -825,16 +808,6 @@ tryAgain:
case Stmt::ContinueStmtClass:
return VisitContinueStmt(cast<ContinueStmt>(S));
-
- case Stmt::CStyleCastExprClass: {
- CastExpr *castExpr = cast<CastExpr>(S);
- if (castExpr->getCastKind() == CK_LValueToRValue) {
- // temporary workaround
- S = castExpr->getSubExpr();
- goto tryAgain;
- }
- return VisitStmt(S, asc);
- }
case Stmt::CXXCatchStmtClass:
return VisitCXXCatchStmt(cast<CXXCatchStmt>(S));
@@ -881,15 +854,8 @@ tryAgain:
case Stmt::IfStmtClass:
return VisitIfStmt(cast<IfStmt>(S));
- case Stmt::ImplicitCastExprClass: {
- ImplicitCastExpr *castExpr = cast<ImplicitCastExpr>(S);
- if (castExpr->getCastKind() == CK_LValueToRValue) {
- // temporary workaround
- S = castExpr->getSubExpr();
- goto tryAgain;
- }
- return VisitImplicitCastExpr(castExpr, asc);
- }
+ case Stmt::ImplicitCastExprClass:
+ return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc);
case Stmt::IndirectGotoStmtClass:
return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S));
@@ -945,7 +911,7 @@ tryAgain:
CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, S, asc);
+ appendStmt(Block, S, asc);
}
return VisitChildren(S);
@@ -967,28 +933,27 @@ CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, A, asc);
+ appendStmt(Block, A, asc);
}
return Block;
}
CFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U,
- AddStmtChoice asc) {
+ AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, U, asc);
+ appendStmt(Block, U, asc);
}
- bool asLVal = U->isIncrementDecrementOp();
- return Visit(U->getSubExpr(), AddStmtChoice().withAsLValue(asLVal));
+ return Visit(U->getSubExpr(), AddStmtChoice());
}
CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
AddStmtChoice asc) {
if (B->isLogicalOp()) { // && or ||
CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
- AppendStmt(ConfluenceBlock, B, asc);
+ appendStmt(ConfluenceBlock, B, asc);
if (badCFG)
return 0;
@@ -1033,7 +998,7 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
if (B->getOpcode() == BO_Comma) { // ,
autoCreateBlock();
- AppendStmt(Block, B, asc);
+ appendStmt(Block, B, asc);
addStmt(B->getRHS());
return addStmt(B->getLHS());
}
@@ -1041,16 +1006,15 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
if (B->isAssignmentOp()) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, B, asc);
+ appendStmt(Block, B, asc);
}
-
- Visit(B->getLHS(), AddStmtChoice::AsLValueNotAlwaysAdd);
+ Visit(B->getLHS());
return Visit(B->getRHS());
}
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, B, asc);
+ appendStmt(Block, B, asc);
}
CFGBlock *RBlock = Visit(B->getRHS());
@@ -1064,7 +1028,7 @@ CFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B,
CFGBlock *CFGBuilder::VisitBlockExpr(BlockExpr *E, AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, E, asc);
+ appendStmt(Block, E, asc);
}
return Block;
}
@@ -1142,7 +1106,7 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
}
Block = createBlock(!NoReturn);
- AppendStmt(Block, C, asc);
+ appendStmt(Block, C, asc);
if (NoReturn) {
// Wire this to the exit block directly.
@@ -1162,7 +1126,7 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C,
AddStmtChoice asc) {
CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
- AppendStmt(ConfluenceBlock, C, asc);
+ appendStmt(ConfluenceBlock, C, asc);
if (badCFG)
return 0;
@@ -1212,7 +1176,7 @@ CFGBlock *CFGBuilder::VisitConditionalOperator(ConditionalOperator *C,
// Create the confluence block that will "merge" the results of the ternary
// expression.
CFGBlock* ConfluenceBlock = Block ? Block : createBlock();
- AppendStmt(ConfluenceBlock, C, asc);
+ appendStmt(ConfluenceBlock, C, asc);
if (badCFG)
return 0;
@@ -1310,7 +1274,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt* DS) {
if (!VD) {
autoCreateBlock();
- AppendStmt(Block, DS);
+ appendStmt(Block, DS);
return Block;
}
@@ -1332,16 +1296,15 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt* DS) {
}
autoCreateBlock();
- AppendStmt(Block, DS);
+ appendStmt(Block, DS);
if (Init) {
- AddStmtChoice asc = AddStmtChoice().withAsLValue(IsReference);
if (HasTemporaries)
// For expression with temporaries go directly to subexpression to omit
// generating destructors for the second time.
- Visit(cast<ExprWithCleanups>(Init)->getSubExpr(), asc);
+ Visit(cast<ExprWithCleanups>(Init)->getSubExpr());
else
- Visit(Init, asc);
+ Visit(Init);
}
// If the type of VD is a VLA, then we must process its size expressions.
@@ -1459,7 +1422,7 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
if (VarDecl *VD = I->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- AppendStmt(Block, I, AddStmtChoice::AlwaysAdd);
+ appendStmt(Block, I, AddStmtChoice::AlwaysAdd);
addStmt(Init);
}
}
@@ -1594,7 +1557,7 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
if (VarDecl *VD = F->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- AppendStmt(Block, F, AddStmtChoice::AlwaysAdd);
+ appendStmt(Block, F, AddStmtChoice::AlwaysAdd);
EntryConditionBlock = addStmt(Init);
assert(Block == EntryConditionBlock);
}
@@ -1694,10 +1657,9 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
CFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, M, asc);
+ appendStmt(Block, M, asc);
}
- return Visit(M->getBase(),
- AddStmtChoice().withAsLValue(!M->isArrow()));
+ return Visit(M->getBase());
}
CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
@@ -1753,7 +1715,7 @@ CFGBlock* CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
// The last statement in the block should be the ObjCForCollectionStmt, which
// performs the actual binding to 'element' and determines if there are any
// more items in the collection.
- AppendStmt(ExitConditionBlock, S);
+ appendStmt(ExitConditionBlock, S);
Block = ExitConditionBlock;
// Walk the 'element' expression to see if there are any side-effects. We
@@ -1820,7 +1782,7 @@ CFGBlock* CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt* S) {
// Add the @synchronized to the CFG.
autoCreateBlock();
- AppendStmt(Block, S, AddStmtChoice::AlwaysAdd);
+ appendStmt(Block, S, AddStmtChoice::AlwaysAdd);
// Inline the sync expression.
return addStmt(S->getSynchExpr());
@@ -1878,7 +1840,7 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
if (VarDecl *VD = W->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- AppendStmt(Block, W, AddStmtChoice::AlwaysAdd);
+ appendStmt(Block, W, AddStmtChoice::AlwaysAdd);
EntryConditionBlock = addStmt(Init);
assert(Block == EntryConditionBlock);
}
@@ -2130,7 +2092,7 @@ CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, E);
+ appendStmt(Block, E);
}
// VLA types have expressions that must be evaluated.
@@ -2148,7 +2110,7 @@ CFGBlock *CFGBuilder::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
CFGBlock* CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, SE);
+ appendStmt(Block, SE);
}
return VisitCompoundStmt(SE->getSubStmt());
}
@@ -2226,7 +2188,7 @@ CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* Terminator) {
if (VarDecl *VD = Terminator->getConditionVariable()) {
if (Expr *Init = VD->getInit()) {
autoCreateBlock();
- AppendStmt(Block, Terminator, AddStmtChoice::AlwaysAdd);
+ appendStmt(Block, Terminator, AddStmtChoice::AlwaysAdd);
addStmt(Init);
}
}
@@ -2429,7 +2391,7 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, E, asc);
+ appendStmt(Block, E, asc);
// We do not want to propagate the AlwaysAdd property.
asc = asc.withAlwaysAdd(false);
@@ -2441,7 +2403,7 @@ CFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C,
AddStmtChoice asc) {
autoCreateBlock();
if (!C->isElidable())
- AppendStmt(Block, C, asc.withAlwaysAdd(true));
+ appendStmt(Block, C, asc.withAlwaysAdd(true));
return VisitChildren(C);
}
@@ -2450,7 +2412,7 @@ CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, E, asc);
+ appendStmt(Block, E, asc);
// We do not want to propagate the AlwaysAdd property.
asc = asc.withAlwaysAdd(false);
}
@@ -2460,14 +2422,14 @@ CFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
CFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C,
AddStmtChoice asc) {
autoCreateBlock();
- AppendStmt(Block, C, asc.withAlwaysAdd(true));
+ appendStmt(Block, C, asc.withAlwaysAdd(true));
return VisitChildren(C);
}
CFGBlock *CFGBuilder::VisitCXXMemberCallExpr(CXXMemberCallExpr *C,
AddStmtChoice asc) {
autoCreateBlock();
- AppendStmt(Block, C, asc.withAlwaysAdd(true));
+ appendStmt(Block, C, asc.withAlwaysAdd(true));
return VisitChildren(C);
}
@@ -2475,11 +2437,9 @@ CFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E,
AddStmtChoice asc) {
if (asc.alwaysAdd()) {
autoCreateBlock();
- AppendStmt(Block, E, asc);
- // We do not want to propagate the AlwaysAdd property.
- asc = asc.withAlwaysAdd(false);
+ appendStmt(Block, E, asc);
}
- return Visit(E->getSubExpr(), asc);
+ return Visit(E->getSubExpr(), AddStmtChoice());
}
CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) {
@@ -3082,9 +3042,6 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
OS << " (BindTemporary)";
}
- if (CS.asLValue())
- OS << " (asLValue)";
-
// Expressions need a newline.
if (isa<Expr>(S))
OS << '\n';
diff --git a/lib/Analysis/PseudoConstantAnalysis.cpp b/lib/Analysis/PseudoConstantAnalysis.cpp
index ff43fc252a..25b04fc2e8 100644
--- a/lib/Analysis/PseudoConstantAnalysis.cpp
+++ b/lib/Analysis/PseudoConstantAnalysis.cpp
@@ -86,6 +86,9 @@ void PseudoConstantAnalysis::RunAnalysis() {
const Stmt* Head = WorkList.front();
WorkList.pop_front();
+ if (const Expr *Ex = dyn_cast<Expr>(Head))
+ Head = Ex->IgnoreParenCasts();
+
switch (Head->getStmtClass()) {
// Case 1: Assignment operators modifying VarDecls
case Stmt::BinaryOperatorClass: {
@@ -225,8 +228,8 @@ void PseudoConstantAnalysis::RunAnalysis() {
continue;
}
- default:
- break;
+ default:
+ break;
} // switch (head->getStmtClass())
// Add all substatements to the worklist
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 1abfde2310..b9585800c9 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -42,6 +42,9 @@ top:
else
return SourceLocation();
+ if (const Expr *Ex = dyn_cast<Expr>(S))
+ S = Ex->IgnoreParenImpCasts();
+
switch (S->getStmtClass()) {
case Expr::BinaryOperatorClass: {
const BinaryOperator *BO = cast<BinaryOperator>(S);
@@ -101,9 +104,6 @@ top:
R1 = CE->getSubExpr()->getSourceRange();
return CE->getTypeBeginLoc();
}
- case Expr::ImplicitCastExprClass:
- ++sn;
- goto top;
case Stmt::CXXTryStmtClass: {
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
}
diff --git a/lib/Checker/AggExprVisitor.cpp b/lib/Checker/AggExprVisitor.cpp
index 9244275343..f31bcec73a 100644
--- a/lib/Checker/AggExprVisitor.cpp
+++ b/lib/Checker/AggExprVisitor.cpp
@@ -53,7 +53,7 @@ void AggExprVisitor::VisitCastExpr(CastExpr *E) {
}
void AggExprVisitor::VisitCXXConstructExpr(CXXConstructExpr *E) {
- Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet, false);
+ Eng.VisitCXXConstructExpr(E, Dest, Pred, DstSet);
}
void GRExprEngine::VisitAggExpr(const Expr *E, const MemRegion *Dest,
diff --git a/lib/Checker/BugReporterVisitors.cpp b/lib/Checker/BugReporterVisitors.cpp
index d466abe068..20e1296997 100644
--- a/lib/Checker/BugReporterVisitors.cpp
+++ b/lib/Checker/BugReporterVisitors.cpp
@@ -318,13 +318,14 @@ void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
GRStateManager &StateMgr = BRC.getStateManager();
const GRState *state = N->getState();
+ // Walk through lvalue-to-rvalue conversions.
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
const VarRegion *R =
- StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
+ StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
// What did we load?
- SVal V = state->getSVal(S);
+ SVal V = state->getSVal(loc::MemRegionVal(R));
if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)
|| V.isUndef()) {
diff --git a/lib/Checker/DereferenceChecker.cpp b/lib/Checker/DereferenceChecker.cpp
index af929a7af7..f1d77204cb 100644
--- a/lib/Checker/DereferenceChecker.cpp
+++ b/lib/Checker/DereferenceChecker.cpp
@@ -125,6 +125,11 @@ void DereferenceChecker::VisitLocation(CheckerContext &C, const Stmt *S,
llvm::SmallString<100> buf;
llvm::SmallVector<SourceRange, 2> Ranges;
+
+ // Walk through lvalue casts to get the original expression
+ // that syntactically caused the load.
+ if (const Expr *expr = dyn_cast<Expr>(S))
+ S = expr->IgnoreParenLValueCasts();
switch (S->getStmtClass()) {
case Stmt::ArraySubscriptExprClass: {
diff --git a/lib/Checker/Environment.cpp b/lib/Checker/Environment.cpp
index f2893ea95e..7bf2929161 100644
--- a/lib/Checker/Environment.cpp
+++ b/lib/Checker/Environment.cpp
@@ -62,8 +62,7 @@ SVal Environment::getSVal(const Stmt *E, SValBuilder& svalBuilder) const {
QualType CT = C->getType();
if (CT->isVoidType())
return UnknownVal();
- if (C->getCastKind() == CK_NoOp ||
- C->getCastKind() == CK_LValueToRValue) { // temporary workaround
+ if (C->getCastKind() == CK_NoOp) {
E = C->getSubExpr();
continue;
}
diff --git a/lib/Checker/GRCXXExprEngine.cpp b/lib/Checker/GRCXXExprEngine.cpp
index 9fb6699f6d..0e2ac04efb 100644
--- a/lib/Checker/GRCXXExprEngine.cpp
+++ b/lib/Checker/GRCXXExprEngine.cpp
@@ -59,11 +59,7 @@ void GRExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE,
: false;
}
- if (VisitAsLvalue)
- VisitLValue(*Item.I, Item.N, Tmp);
- else
- Visit(*Item.I, Item.N, Tmp);
-
+ Visit(*Item.I, Item.N, Tmp);
++(Item.I);
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
WorkList.push_back(CallExprWLItem(Item.I, *NI));
@@ -106,7 +102,7 @@ void GRExprEngine::CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
const MemRegion *Dest,
ExplodedNode *Pred,
- ExplodedNodeSet &Dst, bool asLValue) {
+ ExplodedNodeSet &Dst) {
if (!Dest)
Dest = svalBuilder.getRegionManager().getCXXTempObjectRegion(E,
Pred->getLocationContext());
@@ -131,7 +127,8 @@ void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E,
// The callee stack frame context used to create the 'this' parameter region.
const StackFrameContext *SFC = AMgr.getStackFrame(CD,
Pred->getLocationContext(),
- E, asLValue, Builder->getBlock(), Builder->getIndex());
+ E, Builder->getBlock(),
+ Builder->getIndex());
const CXXThisRegion *ThisR =getCXXThisRegion(E->getConstructor()->getParent(),
SFC);
@@ -159,7 +156,7 @@ void GRExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
// Create the context for 'this' region.
const StackFrameContext *SFC = AMgr.getStackFrame(DD,
Pred->getLocationContext(),
- S, false, Builder->getBlock(),
+ S, Builder->getBlock(),
Builder->getIndex());
const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC);
@@ -193,10 +190,7 @@ void GRExprEngine::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE,
Expr *ObjArgExpr = ME->getBase();
for (ExplodedNodeSet::iterator I = argsEvaluated.begin(),
E = argsEvaluated.end(); I != E; ++I) {
- if (ME->isArrow())
Visit(ObjArgExpr, *I, AllargsEvaluated);
- else
- VisitLValue(ObjArgExpr, *I, AllargsEvaluated);
}
// Now evaluate the call itself.
@@ -211,7 +205,7 @@ void GRExprEngine::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(C->getCalleeDecl());
if (!MD) {
// If the operator doesn't represent a method call treat as regural call.
- VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
+ VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst);
return;
}
@@ -245,7 +239,7 @@ void GRExprEngine::evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
const StackFrameContext *SFC = AMgr.getStackFrame(MD,
Pred->getLocationContext(),
- MCE, false,
+ MCE,
Builder->getBlock(),
Builder->getIndex());
const CXXThisRegion *ThisR = getCXXThisRegion(MD, SFC);
diff --git a/lib/Checker/GRCoreEngine.cpp b/lib/Checker/GRCoreEngine.cpp
index a676e6ca26..270985f416 100644
--- a/lib/Checker/GRCoreEngine.cpp
+++ b/lib/Checker/GRCoreEngine.cpp
@@ -758,7 +758,7 @@ void GRCallEnterNodeBuilder::GenerateNode(const GRState *state) {
const StackFrameContext *OldLocCtx = CalleeCtx;
const StackFrameContext *NewLocCtx = AMgr.getStackFrame(NewAnaCtx,
OldLocCtx->getParent(),
- OldLocCtx->getCallSite(), false,
+ OldLocCtx->getCallSite(),
OldLocCtx->getCallSiteBlock(),
OldLocCtx->getIndex());
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index efe8fbf25c..247435fb83 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -57,47 +57,6 @@ static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
return Ctx.Selectors.getSelector(0, &II);
}
-
-static QualType GetCalleeReturnType(const CallExpr *CE) {
- const Expr *Callee = CE->getCallee();
- QualType T = Callee->getType();
- if (const PointerType *PT = T->getAs<PointerType>()) {
- const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>();
- T = FT->getResultType();
- }
- else {
- const BlockPointerType *BT = T->getAs<BlockPointerType>();
- T = BT->getPointeeType()->getAs<FunctionType>()->getResultType();
- }
- return T;
-}
-
-static bool CalleeReturnsReference(const CallExpr *CE) {
- return (bool) GetCalleeReturnType(CE)->getAs<ReferenceType>();
-}
-
-static bool ReceiverReturnsReference(const ObjCMessageExpr *ME) {
- const ObjCMethodDecl *MD = ME->getMethodDecl();
- if (!MD)
- return false;
- return MD->getResultType()->getAs<ReferenceType>();
-}
-
-#ifndef NDEBUG
-static bool ReceiverReturnsReferenceOrRecord(const ObjCMessageExpr *ME) {
- const ObjCMethodDecl *MD = ME->getMethodDecl();
- if (!MD)
- return false;
- QualType T = MD->getResultType();
- return T->getAs<RecordType>() || T->getAs<ReferenceType>();
-}
-
-static bool CalleeReturnsReferenceOrRecord(const CallExpr *CE) {
- QualType T = GetCalleeReturnType(CE);
- return T->getAs<ReferenceType>() || T->getAs<RecordType>();
-}
-#endif
-
//===----------------------------------------------------------------------===//
// Checker worklist routines.
//===----------------------------------------------------------------------===//
@@ -556,7 +515,6 @@ void GRExprEngine::ProcessElement(const CFGElement E,
GRStmtNodeBuilder& builder) {
switch (E.getKind()) {
case CFGElement::Statement:
- case CFGElement::StatementAsLValue:
ProcessStmt(E.getAs<CFGStmt>(), builder);
break;
case CFGElement::Initializer:
@@ -648,17 +606,13 @@ void GRExprEngine::ProcessStmt(const CFGStmt S, GRStmtNodeBuilder& builder) {
bool HasAutoGenerated = false;
for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
-
ExplodedNodeSet Dst;
// Set the cleaned state.
Builder->SetCleanedState(*I == EntryNode ? CleanedState : GetState(*I));
// Visit the statement.
- if (S.asLValue())
- VisitLValue(cast<Expr>(CurrentStmt), *I, Dst);
- else
- Visit(CurrentStmt, *I, Dst);
+ Visit(CurrentStmt, *I, Dst);
// Do we need to auto-generate a node? We only need to do this to generate
// a node with a "cleaned" state; GRCoreEngine will actually handle
@@ -780,7 +734,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
// Expressions to ignore.
if (const Expr *Ex = dyn_cast<Expr>(S))
- S = Ex->IgnoreParenLValueCasts();
+ S = Ex->IgnoreParens();
// FIXME: add metadata to the CFG so that we can disable
// this check when we KNOW that there is no block-level subexpression.
@@ -880,16 +834,18 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
case Stmt::ArraySubscriptExprClass:
- VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst, false);
+ VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
break;
case Stmt::AsmStmtClass:
VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
break;
- case Stmt::BlockDeclRefExprClass:
- VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(S), Pred, Dst, false);
+ case Stmt::BlockDeclRefExprClass: {
+ const BlockDeclRefExpr *BE = cast<BlockDeclRefExpr>(S);
+ VisitCommonDeclRefExpr(BE, BE->getDecl(), Pred, Dst);
break;
+ }
case Stmt::BlockExprClass:
VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
@@ -897,7 +853,6 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
case Stmt::BinaryOperatorClass: {
const BinaryOperator* B = cast<BinaryOperator>(S);
-
if (B->isLogicalOp()) {
VisitLogicalExpr(B, Pred, Dst);
break;
@@ -911,18 +866,18 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
if (AMgr.shouldEagerlyAssume() &&
(B->isRelationalOp() || B->isEqualityOp())) {
ExplodedNodeSet Tmp;
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp, false);
+ VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
evalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
}
else
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
+ VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
break;
}
case Stmt::CallExprClass: {
const CallExpr* C = cast<CallExpr>(S);
- VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, false);
+ VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst);
break;
}
@@ -930,7 +885,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
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, false);
+ VisitCXXConstructExpr(C, 0, Pred, Dst);
break;
}
@@ -967,11 +922,11 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
}
case Stmt::CompoundAssignOperatorClass:
- VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst, false);
+ VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
break;
case Stmt::CompoundLiteralExprClass:
- VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst, false);
+ VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
break;
case Stmt::ConditionalOperatorClass: { // '?' operator
@@ -984,9 +939,11 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
break;
- case Stmt::DeclRefExprClass:
- VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst, false);
+ case Stmt::DeclRefExprClass: {
+ const DeclRefExpr *DE = cast<DeclRefExpr>(S);
+ VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
break;
+ }
case Stmt::DeclStmtClass:
VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
@@ -1006,7 +963,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
case Stmt::CXXConstCastExprClass:
case Stmt::CXXFunctionalCastExprClass: {
const CastExpr* C = cast<CastExpr>(S);
- VisitCast(C, C->getSubExpr(), Pred, Dst, false);
+ VisitCast(C, C->getSubExpr(), Pred, Dst);
break;
}
@@ -1021,11 +978,10 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
case Stmt::MemberExprClass:
- VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst, false);
+ VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
break;
-
case Stmt::ObjCIvarRefExprClass:
- VisitObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst, false);
+ VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
break;
case Stmt::ObjCForCollectionStmtClass:
@@ -1033,7 +989,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
case Stmt::ObjCMessageExprClass:
- VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst, false);
+ VisitObjCMessageExpr(cast<ObjCMessageExpr>(S), Pred, Dst);
break;
case Stmt::ObjCAtThrowStmtClass: {
@@ -1078,9 +1034,12 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
break;
}
- case Stmt::StringLiteralClass:
- VisitLValue(cast<StringLiteral>(S), Pred, Dst);
- break;
+ case Stmt::StringLiteralClass: {