summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Core/ExprEngineC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineC.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp79
1 files changed, 47 insertions, 32 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 67aeab6..983fda0 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -184,7 +184,8 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
// Get the value of the block itself.
SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
- Pred->getLocationContext());
+ Pred->getLocationContext(),
+ currBldrCtx->blockCount());
ProgramStateRef State = Pred->getState();
@@ -309,7 +310,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
case CK_BlockPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
case CK_ObjCObjectLValueCast:
- case CK_ZeroToOCLEvent: {
+ case CK_ZeroToOCLEvent:
+ case CK_LValueBitCast: {
// Delegate to SValBuilder to process.
SVal V = state->getSVal(Ex, LCtx);
V = svalBuilder.evalCast(V, T, ExTy);
@@ -370,7 +372,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
}
case CK_NullToMemberPointer: {
// FIXME: For now, member pointers are represented by void *.
- SVal V = svalBuilder.makeIntValWithPtrWidth(0, true);
+ SVal V = svalBuilder.makeNull();
state = state->BindExpr(CastE, LCtx, V);
Bldr.generateNode(CastE, Pred, state);
continue;
@@ -381,8 +383,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
case CK_BaseToDerivedMemberPointer:
case CK_DerivedToBaseMemberPointer:
case CK_ReinterpretMemberPointer:
- case CK_VectorSplat:
- case CK_LValueBitCast: {
+ case CK_VectorSplat: {
// Recover some path-sensitivty by conjuring a new value.
QualType resultType = CastE->getType();
if (CastE->isGLValue())
@@ -446,7 +447,8 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
ExplodedNodeSet dstPreVisit;
getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
- StmtNodeBuilder B(dstPreVisit, Dst, *currBldrCtx);
+ ExplodedNodeSet dstEvaluated;
+ StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
I!=E; ++I) {
ExplodedNode *N = *I;
@@ -499,6 +501,8 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
B.generateNode(DS, N, state);
}
}
+
+ getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
}
void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
@@ -579,9 +583,10 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
const LocationContext *LCtx = Pred->getLocationContext();
QualType T = getContext().getCanonicalType(IE->getType());
unsigned NumInitElements = IE->getNumInits();
-
- if (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
- T->isAnyComplexType()) {
+
+ if (!IE->isGLValue() &&
+ (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
+ T->isAnyComplexType())) {
llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
// Handle base case where the initializer has no elements.
@@ -595,8 +600,6 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
ei = IE->rend(); it != ei; ++it) {
SVal V = state->getSVal(cast<Expr>(*it), LCtx);
- if (dyn_cast_or_null<CXXTempObjectRegion>(V.getAsRegion()))
- V = UnknownVal();
vals = getBasicVals().consVals(V, vals);
}
@@ -606,7 +609,9 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
return;
}
- // Handle scalars: int{5} and int{}.
+ // Handle scalars: int{5} and int{} and GLvalues.
+ // Note, if the InitListExpr is a GLvalue, it means that there is an address
+ // representing it, so it must have a single init element.
assert(NumInitElements <= 1);
SVal V;
@@ -735,15 +740,23 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
- StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
- switch (U->getOpcode()) {
+ // FIXME: Prechecks eventually go in ::Visit().
+ ExplodedNodeSet CheckedSet;
+ getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
+
+ ExplodedNodeSet EvalSet;
+ StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+
+ for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+ I != E; ++I) {
+ switch (U->getOpcode()) {
default: {
- Bldr.takeNodes(Pred);
+ Bldr.takeNodes(*I);
ExplodedNodeSet Tmp;
- VisitIncrementDecrementOperator(U, Pred, Tmp);
+ VisitIncrementDecrementOperator(U, *I, Tmp);
Bldr.addNodes(Tmp);
- }
break;
+ }
case UO_Real: {
const Expr *Ex = U->getSubExpr()->IgnoreParens();
@@ -755,10 +768,10 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// For all other types, UO_Real is an identity operation.
assert (U->getType() == Ex->getType());
- ProgramStateRef state = Pred->getState();
- const LocationContext *LCtx = Pred->getLocationContext();
- Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
- state->getSVal(Ex, LCtx)));
+ ProgramStateRef state = (*I)->getState();
+ const LocationContext *LCtx = (*I)->getLocationContext();
+ Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
+ state->getSVal(Ex, LCtx)));
break;
}
@@ -770,10 +783,10 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
break;
}
// For all other types, UO_Imag returns 0.
- ProgramStateRef state = Pred->getState();
- const LocationContext *LCtx = Pred->getLocationContext();
+ ProgramStateRef state = (*I)->getState();
+ const LocationContext *LCtx = (*I)->getLocationContext();
SVal X = svalBuilder.makeZeroVal(Ex->getType());
- Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, X));
+ Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
break;
}
@@ -791,10 +804,10 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// generate an extra node that just propagates the value of the
// subexpression.
const Expr *Ex = U->getSubExpr()->IgnoreParens();
- ProgramStateRef state = Pred->getState();
- const LocationContext *LCtx = Pred->getLocationContext();
- Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
- state->getSVal(Ex, LCtx)));
+ ProgramStateRef state = (*I)->getState();
+ const LocationContext *LCtx = (*I)->getLocationContext();
+ Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
+ state->getSVal(Ex, LCtx)));
break;
}
@@ -803,14 +816,14 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
case UO_Not: {
assert (!U->isGLValue());
const Expr *Ex = U->getSubExpr()->IgnoreParens();
- ProgramStateRef state = Pred->getState();
- const LocationContext *LCtx = Pred->getLocationContext();
+ ProgramStateRef state = (*I)->getState();
+ const LocationContext *LCtx = (*I)->getLocationContext();
// Get the value of the subexpression.
SVal V = state->getSVal(Ex, LCtx);
if (V.isUnknownOrUndef()) {
- Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, V));
+ Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
break;
}
@@ -847,11 +860,13 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
state = state->BindExpr(U, LCtx, Result);
break;
}
- Bldr.generateNode(U, Pred, state);
+ Bldr.generateNode(U, *I, state);
break;
}
+ }
}
+ getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
}
void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
OpenPOWER on IntegriCloud