summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AdjustedReturnValueChecker.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp12
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp9
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp85
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp16
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp16
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp6
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp10
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp24
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp23
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp11
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp5
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp17
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp41
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp42
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp12
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp7
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp2
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp11
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp2
36 files changed, 236 insertions, 167 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AdjustedReturnValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AdjustedReturnValueChecker.cpp
index 7dad2421bf5..df5620b803a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/AdjustedReturnValueChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/AdjustedReturnValueChecker.cpp
@@ -38,19 +38,20 @@ void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
// Fetch the signature of the called function.
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
- SVal V = state->getSVal(CE);
+ SVal V = state->getSVal(CE, LCtx);
if (V.isUnknown())
return;
// Casting to void? Discard the value.
if (expectedResultTy->isVoidType()) {
- C.addTransition(state->BindExpr(CE, UnknownVal()));
+ C.addTransition(state->BindExpr(CE, LCtx, UnknownVal()));
return;
}
- const MemRegion *callee = state->getSVal(CE->getCallee()).getAsRegion();
+ const MemRegion *callee = state->getSVal(CE->getCallee(), LCtx).getAsRegion();
if (!callee)
return;
@@ -82,7 +83,7 @@ void AdjustedReturnValueChecker::checkPostStmt(const CallExpr *CE,
// the cast avoids some assertion failures elsewhere.
SValBuilder &svalBuilder = C.getSValBuilder();
V = svalBuilder.evalCast(V, expectedResultTy, actualResultTy);
- C.addTransition(state->BindExpr(CE, V));
+ C.addTransition(state->BindExpr(CE, LCtx, V));
}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
index 8296eb93c5a..a3dc9648f4d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
@@ -34,9 +34,10 @@ public:
void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
// Check if the callee has a 'nonnull' attribute.
- SVal X = state->getSVal(CE->getCallee());
+ SVal X = state->getSVal(CE->getCallee(), LCtx);
const FunctionDecl *FD = X.getAsFunctionDecl();
if (!FD)
@@ -55,7 +56,7 @@ void AttrNonNullChecker::checkPreStmt(const CallExpr *CE,
if (!Att->isNonNull(idx))
continue;
- SVal V = state->getSVal(*I);
+ SVal V = state->getSVal(*I, LCtx);
DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
// If the value is unknown or undefined, we can't perform this check.
diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 1f627297ec8..fbe4671ddc5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -129,7 +129,7 @@ void NilArgChecker::checkPreObjCMessage(ObjCMessage msg,
Name == "compare:options:range:locale:" ||
Name == "componentsSeparatedByCharactersInSet:" ||
Name == "initWithFormat:") {
- if (isNil(msg.getArgSVal(0, C.getState())))
+ if (isNil(msg.getArgSVal(0, C.getLocationContext(), C.getState())))
WarnNilArg(C, msg, 0);
}
}
@@ -262,7 +262,8 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
return;
// Get the value of the "theType" argument.
- SVal TheTypeVal = state->getSVal(CE->getArg(1));
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal TheTypeVal = state->getSVal(CE->getArg(1), LCtx);
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
@@ -280,7 +281,7 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
// Look at the value of the integer being passed by reference. Essentially
// we want to catch cases where the value passed in is not equal to the
// size of the type being created.
- SVal TheValueExpr = state->getSVal(CE->getArg(2));
+ SVal TheValueExpr = state->getSVal(CE->getArg(2), LCtx);
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
@@ -382,7 +383,7 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
// Get the argument's value.
const Expr *Arg = CE->getArg(0);
- SVal ArgVal = state->getSVal(Arg);
+ SVal ArgVal = state->getSVal(Arg, C.getLocationContext());
DefinedSVal *DefArgVal = dyn_cast<DefinedSVal>(&ArgVal);
if (!DefArgVal)
return;
@@ -593,7 +594,8 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
continue;
// Ignore pointer constants.
- if (isa<loc::ConcreteInt>(msg.getArgSVal(I, state)))
+ if (isa<loc::ConcreteInt>(msg.getArgSVal(I, C.getLocationContext(),
+ state)))
continue;
// Ignore pointer types annotated with 'NSObject' attribute.
diff --git a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 2cf1209f51d..50938fa777b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -33,6 +33,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
+ const LocationContext *LCtx = C.getLocationContext();
if (!FD)
return false;
@@ -45,8 +46,8 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
case Builtin::BI__builtin_expect: {
// For __builtin_expect, just return the value of the subexpression.
assert (CE->arg_begin() != CE->arg_end());
- SVal X = state->getSVal(*(CE->arg_begin()));
- C.addTransition(state->BindExpr(CE, X));
+ SVal X = state->getSVal(*(CE->arg_begin()), LCtx);
+ C.addTransition(state->BindExpr(CE, LCtx, X));
return true;
}
@@ -60,7 +61,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
// SVal of the argument directly. If we save the extent in bits, we
// cannot represent values like symbol*8.
DefinedOrUnknownSVal Size =
- cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin())));
+ cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin()), LCtx));
SValBuilder& svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
@@ -68,7 +69,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
svalBuilder.evalEQ(state, Extent, Size);
state = state->assume(extentMatchesSizeArg, true);
- C.addTransition(state->BindExpr(CE, loc::MemRegionVal(R)));
+ C.addTransition(state->BindExpr(CE, LCtx, loc::MemRegionVal(R)));
return true;
}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 49d8bf5388b..bc8d184af7f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -329,12 +329,13 @@ const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
SValBuilder &svalBuilder = C.getSValBuilder();
ASTContext &Ctx = svalBuilder.getContext();
+ const LocationContext *LCtx = C.getLocationContext();
QualType sizeTy = Size->getType();
QualType PtrTy = Ctx.getPointerType(Ctx.CharTy);
// Check that the first buffer is non-null.
- SVal BufVal = state->getSVal(FirstBuf);
+ SVal BufVal = state->getSVal(FirstBuf, LCtx);
state = checkNonNull(C, state, FirstBuf, BufVal);
if (!state)
return NULL;
@@ -342,7 +343,7 @@ const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
// Get the access length and make sure it is known.
// FIXME: This assumes the caller has already checked that the access length
// is positive. And that it's unsigned.
- SVal LengthVal = state->getSVal(Size);
+ SVal LengthVal = state->getSVal(Size, LCtx);
NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
if (!Length)
return state;
@@ -368,7 +369,7 @@ const ProgramState *CStringChecker::CheckBufferAccess(CheckerContext &C,
// If there's a second buffer, check it as well.
if (SecondBuf) {
- BufVal = state->getSVal(SecondBuf);
+ BufVal = state->getSVal(SecondBuf, LCtx);
state = checkNonNull(C, state, SecondBuf, BufVal);
if (!state)
return NULL;
@@ -403,8 +404,9 @@ const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
const ProgramState *stateTrue, *stateFalse;
// Get the buffer values and make sure they're known locations.
- SVal firstVal = state->getSVal(First);
- SVal secondVal = state->getSVal(Second);
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal firstVal = state->getSVal(First, LCtx);
+ SVal secondVal = state->getSVal(Second, LCtx);
Loc *firstLoc = dyn_cast<Loc>(&firstVal);
if (!firstLoc)
@@ -456,7 +458,7 @@ const ProgramState *CStringChecker::CheckOverlap(CheckerContext &C,
}
// Get the length, and make sure it too is known.
- SVal LengthVal = state->getSVal(Size);
+ SVal LengthVal = state->getSVal(Size, LCtx);
NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
if (!Length)
return state;
@@ -846,7 +848,8 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
CurrentFunctionDescription = "memory copy function";
// See if the size argument is zero.
- SVal sizeVal = state->getSVal(Size);
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal sizeVal = state->getSVal(Size, LCtx);
QualType sizeTy = Size->getType();
const ProgramState *stateZeroSize, *stateNonZeroSize;
@@ -854,12 +857,12 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
assumeZero(C, state, sizeVal, sizeTy);
// Get the value of the Dest.
- SVal destVal = state->getSVal(Dest);
+ SVal destVal = state->getSVal(Dest, LCtx);
// If the size is zero, there won't be any actual memory access, so
// just bind the return value to the destination buffer and return.
if (stateZeroSize) {
- stateZeroSize = stateZeroSize->BindExpr(CE, destVal);
+ stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal);
C.addTransition(stateZeroSize);
}
@@ -874,7 +877,7 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
return;
// Get the value of the Src.
- SVal srcVal = state->getSVal(Source);
+ SVal srcVal = state->getSVal(Source, LCtx);
// Ensure the source is not null. If it is NULL there will be a
// NULL pointer dereference.
@@ -910,20 +913,20 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
Dest->getType());
// The byte after the last byte copied is the return value.
- state = state->BindExpr(CE, lastElement);
+ state = state->BindExpr(CE, LCtx, lastElement);
} else {
// If we don't know how much we copied, we can at least
// conjure a return value for later.
unsigned Count = C.getCurrentBlockCount();
SVal result =
C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
- state = state->BindExpr(CE, result);
+ state = state->BindExpr(CE, LCtx, result);
}
} else {
// All other copies return the destination buffer.
// (Well, bcopy() has a void return type, but this won't hurt.)
- state = state->BindExpr(CE, destVal);
+ state = state->BindExpr(CE, LCtx, destVal);
}
// Invalidate the destination.
@@ -931,7 +934,8 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
// can use LazyCompoundVals to copy the source values into the destination.
// This would probably remove any existing bindings past the end of the
// copied region, but that's still an improvement over blank invalidation.
- state = InvalidateBuffer(C, state, Dest, state->getSVal(Dest));
+ state = InvalidateBuffer(C, state, Dest,
+ state->getSVal(Dest, C.getLocationContext()));
C.addTransition(state);
}
}
@@ -982,7 +986,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
SValBuilder &svalBuilder = C.getSValBuilder();
// See if the size argument is zero.
- SVal sizeVal = state->getSVal(Size);
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal sizeVal = state->getSVal(Size, LCtx);
QualType sizeTy = Size->getType();
const ProgramState *stateZeroSize, *stateNonZeroSize;
@@ -993,7 +998,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
// have to check either of the buffers.
if (stateZeroSize) {
state = stateZeroSize;
- state = state->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
+ state = state->BindExpr(CE, LCtx,
+ svalBuilder.makeZeroVal(CE->getType()));
C.addTransition(state);
}
@@ -1003,8 +1009,10 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
// If we know the two buffers are the same, we know the result is 0.
// First, get the two buffers' addresses. Another checker will have already
// made sure they're not undefined.
- DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(state->getSVal(Left));
- DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(state->getSVal(Right));
+ DefinedOrUnknownSVal LV =
+ cast<DefinedOrUnknownSVal>(state->getSVal(Left, LCtx));
+ DefinedOrUnknownSVal RV =
+ cast<DefinedOrUnknownSVal>(state->getSVal(Right, LCtx));
// See if they are the same.
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
@@ -1017,7 +1025,8 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
state = StSameBuf;
state = CheckBufferAccess(C, state, Size, Left);
if (state) {
- state = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
+ state = StSameBuf->BindExpr(CE, LCtx,
+ svalBuilder.makeZeroVal(CE->getType()));
C.addTransition(state);
}
}
@@ -1031,7 +1040,7 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
// The return value is the comparison result, which we don't know.
unsigned Count = C.getCurrentBlockCount();
SVal CmpV = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
- state = state->BindExpr(CE, CmpV);
+ state = state->BindExpr(CE, LCtx, CmpV);
C.addTransition(state);
}
}
@@ -1054,10 +1063,11 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
bool IsStrnlen) const {
CurrentFunctionDescription = "string length function";
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
if (IsStrnlen) {
const Expr *maxlenExpr = CE->getArg(1);
- SVal maxlenVal = state->getSVal(maxlenExpr);
+ SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
const ProgramState *stateZeroSize, *stateNonZeroSize;
llvm::tie(stateZeroSize, stateNonZeroSize) =
@@ -1067,7 +1077,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// have to check the string itself.
if (stateZeroSize) {
SVal zero = C.getSValBuilder().makeZeroVal(CE->getType());
- stateZeroSize = stateZeroSize->BindExpr(CE, zero);
+ stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, zero);
C.addTransition(stateZeroSize);
}
@@ -1081,7 +1091,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// Check that the string argument is non-null.
const Expr *Arg = CE->getArg(0);
- SVal ArgVal = state->getSVal(Arg);
+ SVal ArgVal = state->getSVal(Arg, LCtx);
state = checkNonNull(C, state, Arg, ArgVal);
@@ -1105,7 +1115,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// It's a little unfortunate to be getting this again,
// but it's not that expensive...
const Expr *maxlenExpr = CE->getArg(1);
- SVal maxlenVal = state->getSVal(maxlenExpr);
+ SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
@@ -1170,7 +1180,7 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// Bind the return value.
assert(!result.isUnknown() && "Should have conjured a value by now");
- state = state->BindExpr(CE, result);
+ state = state->BindExpr(CE, LCtx, result);
C.addTransition(state);
}
@@ -1219,10 +1229,11 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
bool isAppending) const {
CurrentFunctionDescription = "string copy function";
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
// Check that the destination is non-null.
const Expr *Dst = CE->getArg(0);
- SVal DstVal = state->getSVal(Dst);
+ SVal DstVal = state->getSVal(Dst, LCtx);
state = checkNonNull(C, state, Dst, DstVal);
if (!state)
@@ -1230,7 +1241,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// Check that the source is non-null.
const Expr *srcExpr = CE->getArg(1);
- SVal srcVal = state->getSVal(srcExpr);
+ SVal srcVal = state->getSVal(srcExpr, LCtx);
state = checkNonNull(C, state, srcExpr, srcVal);
if (!state)
return;
@@ -1257,7 +1268,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (isBounded) {
// Get the max number of characters to copy.
const Expr *lenExpr = CE->getArg(2);
- SVal lenVal = state->getSVal(lenExpr);
+ SVal lenVal = state->getSVal(lenExpr, LCtx);
// Protect against misdeclared strncpy().
lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType());
@@ -1512,7 +1523,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
}
// Set the return value.
- state = state->BindExpr(CE, Result);
+ state = state->BindExpr(CE, LCtx, Result);
C.addTransition(state);
}
@@ -1542,17 +1553,18 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
bool isBounded, bool ignoreCase) const {
CurrentFunctionDescription = "string comparison function";
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
// Check that the first string is non-null
const Expr *s1 = CE->getArg(0);
- SVal s1Val = state->getSVal(s1);
+ SVal s1Val = state->getSVal(s1, LCtx);
state = checkNonNull(C, state, s1, s1Val);
if (!state)
return;
// Check that the second string is non-null.
const Expr *s2 = CE->getArg(1);
- SVal s2Val = state->getSVal(s2);
+ SVal s2Val = state->getSVal(s2, LCtx);
state = checkNonNull(C, state, s2, s2Val);
if (!state)
return;
@@ -1582,7 +1594,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
// If the two arguments might be the same buffer, we know the result is 0,
// and we only need to check one size.
if (StSameBuf) {
- StSameBuf = StSameBuf->BindExpr(CE, svalBuilder.makeZeroVal(CE->getType()));
+ StSameBuf = StSameBuf->BindExpr(CE, LCtx,
+ svalBuilder.makeZeroVal(CE->getType()));
C.addTransition(StSameBuf);
// If the two arguments are GUARANTEED to be the same, we're done!
@@ -1608,7 +1621,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
if (isBounded) {
// Get the max number of characters to compare.
const Expr *lenExpr = CE->getArg(2);
- SVal lenVal = state->getSVal(lenExpr);
+ SVal lenVal = state->getSVal(lenExpr, LCtx);
// If the length is known, we can get the right substrings.
if (const llvm::APSInt *len = svalBuilder.getKnownValue(state, lenVal)) {
@@ -1645,7 +1658,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
// Build the SVal of the comparison and bind the return value.
SVal resultVal = svalBuilder.makeIntVal(result, CE->getType());
- state = state->BindExpr(CE, resultVal);
+ state = state->BindExpr(CE, LCtx, resultVal);
}
}
@@ -1653,7 +1666,7 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
// Conjure a symbolic value. It's the best we can do.
unsigned Count = C.getCurrentBlockCount();
SVal resultVal = svalBuilder.getConjuredSymbolVal(NULL, CE, Count);
- state = state->BindExpr(CE, resultVal);
+ state = state->BindExpr(CE, LCtx, resultVal);
}
// Record this as a possible path.
@@ -1728,7 +1741,7 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
if (!MR)
continue;
- SVal StrVal = state->getSVal(Init);
+ SVal StrVal = state->getSVal(Init, C.getLocationContext());
assert(StrVal.isValid() && "Initializer string is unknown or undefined");
DefinedOrUnknownSVal strLength
= cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 914b806dd74..f5f0c1655b9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -193,7 +193,8 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const{
const Expr *Callee = CE->getCallee()->IgnoreParens();
- SVal L = C.getState()->getSVal(Callee);
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal L = C.getState()->getSVal(Callee, LCtx);
if (L.isUndef()) {
if (!BT_call_undef)
@@ -210,7 +211,7 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
EmitBadCall(BT_call_null.get(), C, CE);
}
- PreVisitProcessArgs(C, CallOrObjCMessage(CE, C.getState()),
+ PreVisitProcessArgs(C, CallOrObjCMessage(CE, C.getState(), LCtx),
"Function call argument is an uninitialized value",
BT_call_arg);
}
@@ -219,10 +220,11 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
CheckerContext &C) const {
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
// FIXME: Handle 'super'?
if (const Expr *receiver = msg.getInstanceReceiver()) {
- SVal recVal = state->getSVal(receiver);
+ SVal recVal = state->getSVal(receiver, LCtx);
if (recVal.isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT_msg_undef)
@@ -255,7 +257,8 @@ void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
"Argument for property setter is an uninitialized value"
: "Argument in message expression is an uninitialized value";
// Check for any arguments that are uninitialized/undefined.
- PreVisitProcessArgs(C, CallOrObjCMessage(msg, state), bugDesc, BT_msg_arg);
+ PreVisitProcessArgs(C, CallOrObjCMessage(msg, state, LCtx),
+ bugDesc, BT_msg_arg);
}
void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
@@ -298,11 +301,12 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
// return different values depending on the return type and the architecture.
QualType RetTy = msg.getType(Ctx);
CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
+ const LocationContext *LCtx = C.getLocationContext();
if (CanRetTy->isStructureOrClassType()) {
// Structure returns are safe since the compiler zeroes them out.
SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
- C.addTransition(state->BindExpr(msg.getOriginExpr(), V));
+ C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V));
return;
}
@@ -339,7 +343,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
// of this case unless we have *a lot* more knowledge.
//
SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
- C.addTransition(state->BindExpr(msg.getOriginExpr(), V));
+ C.addTransition(state->BindExpr(msg.getOriginExpr(), LCtx, V));
return;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
index 84a9e6b3c52..32b60d91540 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
@@ -45,7 +45,7 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
return;
const ProgramState *state = C.getState();
- const MemRegion *R = state->getSVal(E).getAsRegion();
+ const MemRegion *R = state->getSVal(E, C.getLocationContext()).getAsRegion();
if (R == 0)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index fa79f218661..22f7b775a54 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -105,7 +105,7 @@ void ChrootChecker::Chdir(CheckerContext &C, const CallExpr *CE) const {
// After chdir("/"), enter the jail, set the enum value JAIL_ENTERED.
const Expr *ArgExpr = CE->getArg(0);
- SVal ArgVal = state->getSVal(ArgExpr);
+ SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
if (const MemRegion *R = ArgVal.getAsRegion()) {
R = R->StripCasts();
diff --git a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
index d4fbfa14b9e..12fd6f4e76d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
@@ -42,7 +42,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
!B->getRHS()->getType()->isScalarType())
return;
- SVal Denom = C.getState()->getSVal(B->getRHS());
+ SVal Denom = C.getState()->getSVal(B->getRHS(), C.getLocationContext());
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
// Divide-by-undefined handled in the generic checking for uses of
diff --git a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
index 7bdd4f34a73..d570da001e8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
@@ -45,8 +45,7 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
return;
const ProgramState *state = C.getState();
-
- SVal RV = state->getSVal(B->getRHS());
+ SVal RV = state->getSVal(B->getRHS(), C.getLocationContext());
if (!RV.isConstant() || RV.isZeroConstant())
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index f09d670c1ff..9e67e21cc3c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -154,7 +154,7 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
const Expr* Arg,
bool IssueWarning) const {
const ProgramState *State = C.getState();
- SVal AddrVal = State->getSVal(Arg->IgnoreParens());
+ SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext());
if (AddrVal.isUnknownOrUndef())
return 0;
@@ -185,7 +185,8 @@ const ProgramState *GenericTaintChecker::preFscanf(const CallExpr *CE,
const ProgramState *State = C.getState();
// Check is the file descriptor is tainted.
- if (State->isTainted(CE->getArg(0)) || isStdin(CE->getArg(0), C))
+ if (State->isTainted(CE->getArg(0), C.getLocationContext()) ||
+ isStdin(CE->getArg(0), C))
return State->set<TaintOnPreVisit>(PrevisitTaintArgs);
return 0;
}
@@ -196,7 +197,8 @@ const ProgramState * GenericTaintChecker::preAnyArgs(const CallExpr *CE,
for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
const ProgramState *State = C.getState();
const Expr *Arg = CE->getArg(i);
- if (State->isTainted(Arg) || State->isTainted(getPointedToSymbol(C, Arg)))
+ if (State->isTainted(Arg, C.getLocationContext()) ||
+ State->isTainted(getPointedToSymbol(C, Arg)))
return State = State->set<TaintOnPreVisit>(PrevisitTaintRet);
}
return 0;
@@ -209,7 +211,7 @@ const ProgramState *GenericTaintChecker::postDefault(const CallExpr *CE,
// Check if we know that the result needs to be tainted based on the
// pre-visit analysis.
if (State->get<TaintOnPreVisit>() == PrevisitTaintRet) {
- State = State->addTaint(CE);
+ State = State->addTaint(CE, C.getLocationContext());
return State->set<TaintOnPreVisit>(PrevisitNone);
}
@@ -220,7 +222,7 @@ const ProgramState *GenericTaintChecker::postScanf(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *State = C.getState();
assert(CE->getNumArgs() >= 2);
- SVal x = State->getSVal(CE->getArg(1));
+ SVal x = State->getSVal(CE->getArg(1), C.getLocationContext());
// All arguments except for the very first one should get taint.
for (unsigned int i = 1; i < CE->getNumArgs(); ++i) {
// The arguments are pointer arguments. The data they are pointing at is
@@ -262,13 +264,13 @@ const ProgramState *GenericTaintChecker::postFscanf(const CallExpr *CE,
const ProgramState *GenericTaintChecker::postRetTaint(const CallExpr *CE,
CheckerContext &C) const {
- return C.getState()->addTaint(CE);
+ return C.getState()->addTaint(CE, C.getLocationContext());
}
bool GenericTaintChecker::isStdin(const Expr *E,
CheckerContext &C) const {
const ProgramState *State = C.getState();
- SVal Val = State->getSVal(E);
+ SVal Val = State->getSVal(E, C.getLocationContext());
// stdin is a pointer, so it would be a region.
const MemRegion *MemReg = Val.getAsRegion();
diff --git a/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
index a3ebf0b750a..ef830e8684e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
@@ -142,9 +142,9 @@ void IdempotentOperationChecker::checkPreStmt(const BinaryOperator *B,
}
const ProgramState *state = C.getState();
-
- SVal LHSVal = state->getSVal(LHS);
- SVal RHSVal = state->getSVal(RHS);
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal LHSVal = state->getSVal(LHS, LCtx);
+ SVal RHSVal = state->getSVal(RHS, LCtx);
// If either value is unknown, we can't be 100% sure of all paths.
if (LHSVal.isUnknownOrUndef() || RHSVal.isUnknownOrUndef()) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
index ab3242bdf5b..341d42510b5 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
@@ -254,7 +254,7 @@ const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state,
lexp = M->GetTemporaryExpr();
if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(lexp))
lexp = ICE->getSubExpr();
- SVal sv = state->getSVal(lexp);
+ SVal sv = state->getSVal(lexp, LC);
const MemRegion *MR = sv.getAsRegion();
if (!MR)
return state;
@@ -574,7 +574,7 @@ void IteratorsChecker::checkPreStmt(const CXXMemberCallExpr *MCE,
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ME->getBase());
if (!DRE || getTemplateKind(DRE->getType()) != VectorKind)
return;
- SVal tsv = C.getState()->getSVal(DRE);
+ SVal tsv = C.getState()->getSVal(DRE, C.getLocationContext());
// Get the MemRegion associated with the container instance.
const MemRegion *MR = tsv.getAsRegion();
if (!MR)
diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index 78707e7e8ae..0a675e562ce 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -220,7 +220,7 @@ static bool isBadDeallocationArgument(const MemRegion *Arg) {
static SymbolRef getAsPointeeSymbol(const Expr *Expr,
CheckerContext &C) {
const ProgramState *State = C.getState();
- SVal ArgV = State->getSVal(Expr);
+ SVal ArgV = State->getSVal(Expr, C.getLocationContext());
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
StoreManager& SM = C.getStoreManager();
@@ -325,7 +325,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
// Check the argument to the deallocator.
const Expr *ArgExpr = CE->getArg(FunctionsToTrack[idx].Param);
- SVal ArgSVal = State->getSVal(ArgExpr);
+ SVal ArgSVal = State->getSVal(ArgExpr, C.getLocationContext());
// Undef is reported by another checker.
if (ArgSVal.isUndef())
@@ -462,7 +462,8 @@ void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE,
// allocated value symbol, since our diagnostics depend on the value
// returned by the call. Ex: Data should only be freed if noErr was
// returned during allocation.)
- SymbolRef RetStatusSymbol = State->getSVal(CE).getAsSymbol();
+ SymbolRef RetStatusSymbol =
+ State->getSVal(CE, C.getLocationContext()).getAsSymbol();
C.getSymbolManager().addSymbolDependency(V, RetStatusSymbol);
// Track the allocated value in the checker state.
@@ -481,7 +482,8 @@ void MacOSKeychainAPIChecker::checkPreStmt(const ReturnStmt *S,
// Check if the value is escaping through the return.
const ProgramState *state = C.getState();
- const MemRegion *V = state->getSVal(retExpr).getAsRegion();
+ const MemRegion *V =
+ state->getSVal(retExpr, C.getLocationContext()).getAsRegion();
if (!V)
return;
state = state->remove<AllocatedData>(getSymbolForRegion(C, V));
diff --git a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
index f8c01047c38..9141656f0cb 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
@@ -57,7 +57,8 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
// Check if the first argument is stack allocated. If so, issue a warning
// because that's likely to be bad news.
const ProgramState *state = C.getState();
- const MemRegion *R = state->getSVal(CE->getArg(0)).getAsRegion();
+ const MemRegion *R =
+ state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index dcc7ab95dc0..ea42da40673 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -100,7 +100,9 @@ private:
static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
const Expr *SizeEx, SVal Init,
const ProgramState *state) {
- return MallocMemAux(C, CE, state->getSVal(SizeEx), Init, state);
+ return MallocMemAux(C, CE,
+ state->getSVal(SizeEx, C.getLocationContext()),
+ Init, state);
}
static const ProgramState *MallocMemAux(CheckerContext &C, const CallExpr *CE,
SVal SizeEx, SVal Init,
@@ -230,7 +232,7 @@ const ProgramState *MallocChecker::MallocMemAux(CheckerContext &C,
// Set the return value.
SVal retVal = svalBuilder.getConjuredSymbolVal(NULL, CE,
CE->getType(), Count);
- state = state->BindExpr(CE, retVal);
+ state = state->BindExpr(CE, C.getLocationContext(), retVal);
// Fill the region with the initialization value.
state = state->bindDefault(retVal, Init);
@@ -280,7 +282,7 @@ const ProgramState *MallocChecker::FreeMemAux(CheckerContext &C,
unsigned Num,
bool Hold) const {
const Expr *ArgExpr = CE->getArg(Num);
- SVal ArgVal = state->getSVal(ArgExpr);
+ SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
@@ -501,8 +503,9 @@ void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
const Expr *arg0Expr = CE->getArg(0);
+ const LocationContext *LCtx = C.getLocationContext();
DefinedOrUnknownSVal arg0Val
- = cast<DefinedOrUnknownSVal>(state->getSVal(arg0Expr));
+ = cast<DefinedOrUnknownSVal>(state->getSVal(arg0Expr, LCtx));
SValBuilder &svalBuilder = C.getSValBuilder();
@@ -516,7 +519,7 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
// Get the value of the size argument.
DefinedOrUnknownSVal Arg1Val =
- cast<DefinedOrUnknownSVal>(state->getSVal(Arg1));
+ cast<DefinedOrUnknownSVal>(state->getSVal(Arg1, LCtx));
// Compare the size argument to 0.
DefinedOrUnknownSVal SizeZero =
@@ -548,7 +551,8 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
FreeMemAux(C, CE, stateSizeZero, 0, false)) {
// Bind the return value to NULL because it is now free.
- C.addTransition(stateFree->BindExpr(CE, svalBuilder.makeNull(), true));
+ C.addTransition(stateFree->BindExpr(CE, LCtx,
+ svalBuilder.makeNull(), true));
}
if (const ProgramState *stateSizeNotZero =
stateNotEqual->assume(SizeZero,false))
@@ -565,9 +569,9 @@ void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
const ProgramState *state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
-
- SVal count = state->getSVal(CE->getArg(0));
- SVal elementSize = state->getSVal(CE->getArg(1));
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal count = state->getSVal(CE->getArg(0), LCtx);
+ SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
svalBuilder.getContext().getSizeType());
SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
@@ -638,7 +642,7 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
const ProgramState *state = C.getState();
- SymbolRef Sym = state->getSVal(retExpr).getAsSymbol();
+ SymbolRef Sym = state->getSVal(retExpr, C.getLocationContext()).getAsSymbol();
if (!Sym)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index 81f1924b2c7..b831a822476 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -42,7 +42,7 @@ void NoReturnFunctionChecker::checkPostStmt(const CallExpr *CE,
bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
if (!BuildSinks) {
- SVal L = state->getSVal(Callee);
+ SVal L = state->getSVal(Callee, C.getLocationContext());
const FunctionDecl *FD = L.getAsFunctionDecl();
if (!FD)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
index 27d8fb5abbd..4089b346b80 100644
--- a/clang/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
@@ -36,9 +36,10 @@ private:
}
static StringRef getCalleeName(const ProgramState *State,
- const CallExpr *CE) {
+ const CallExpr *CE,
+ const LocationContext *LCtx) {
const Expr *Callee = CE->getCallee();
- SVal L = State->getSVal(Callee);
+ SVal L = State->getSVal(Callee, LCtx);
const FunctionDecl *funDecl = L.getAsFunctionDecl();
if (!funDecl)
return StringRef();
@@ -52,7 +53,8 @@ bool OSAtomicChecker::inlineCall(const CallExpr *CE,
ExprEngine &Eng,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) const {
- StringRef FName = getCalleeName(Pred->getState(), CE);
+ StringRef FName = getCalleeName(Pred->getState(),
+ CE, Pred->getLocationContext());
if (FName.empty())
return false;
@@ -103,8 +105,9 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
// Load 'theValue'.
const ProgramState *state = Pred->getState();
+ const LocationContext *LCtx = Pred->getLocationContext();
ExplodedNodeSet Tmp;
- SVal location = state->getSVal(theValueExpr);
+ SVal location = state->getSVal(theValueExpr, LCtx);
// Here we should use the value type of the region as the load type, because
// we are simulating the semantics of the function, not the semantics of
// passing argument. So the type of theValue expr is not we are loading.
@@ -135,9 +138,9 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
// Use direct bindings from the environment since we are forcing a load
// from a location that the Environment would typically not be used
// to bind a value.
- SVal theValueVal_untested = stateLoad->getSVal(theValueExpr, true);
+ SVal theValueVal_untested = stateLoad->getSVal(theValueExpr, LCtx, true);
- SVal oldValueVal_untested = stateLoad->getSVal(oldValueExpr);
+ SVal oldValueVal_untested = stateLoad->getSVal(oldValueExpr, LCtx);
// FIXME: Issue an error.
if (theValueVal_untested.isUndef() || oldValueVal_untested.isUndef()) {
@@ -161,7 +164,7 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
if (stateEqual) {
// Perform the store.
ExplodedNodeSet TmpStore;
- SVal val = stateEqual->getSVal(newValueExpr);
+ SVal val = stateEqual->getSVal(newValueExpr, LCtx);
// Handle implicit value casts.
if (const TypedValueRegion *R =
@@ -189,7 +192,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
QualType T = CE->getType();
if (!T->isVoidType())
Res = Eng.getSValBuilder().makeTruthVal(true, T);
- B.generateNode(CE, predNew, stateNew->BindExpr(CE, Res), false, this);
+ B.generateNode(CE, predNew, stateNew->BindExpr(CE, LCtx, Res),
+ false, this);
}
}
@@ -201,7 +205,8 @@ bool OSAtomicChecker::evalOSAtomicCompareAndSwap(const CallExpr *CE,
if (!T->isVoidType())
Res = Eng.getSValBuilder().makeTruthVal(false, CE->getType());
StmtNodeBuilder B(N, Dst, Eng.getBuilderContext());
- B.generateNode(CE, N, stateNotEqual->BindExpr(CE, Res), false, this);
+ B.generateNode(CE, N, stateNotEqual->BindExpr(CE, LCtx, Res),
+ false, this);
}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
index 5db073c9cb1..06b138e4021 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
@@ -39,7 +39,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
const Expr *Ex = S->getSynchExpr();
const ProgramState *state = C.getState();
- SVal V = state->getSVal(Ex);
+ SVal V = state->getSVal(Ex, C.getLocationContext());
// Uninitialized value used for the mutex?
if (isa<UndefinedVal>(V)) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 8b29a20dc62..a466b41d125 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -156,7 +156,7 @@ static bool hasSelfFlag(SVal val, SelfFlagEnum flag, CheckerContext &C) {
/// points to and is an object that did not come from the result of calling
/// an initializer.
static bool isInvalidSelf(const Expr *E, CheckerContext &C) {
- SVal exprVal = C.getState()->getSVal(E);
+ SVal exprVal = C.getState()->getSVal(E, C.getLocationContext());
if (!hasSelfFlag(exprVal, SelfFlag_Self, C))
return false; // value did not come from 'self'.
if (hasSelfFlag(exprVal, SelfFlag_InitRes, C))
@@ -206,7 +206,7 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
// value out when we return from this method.
state = state->set<CalledInit>(true);
- SVal V = state->getSVal(msg.getOriginExpr());
+ SVal V = state->getSVal(msg.getOriginExpr(), C.getLocationContext());
addSelfFlag(state, V, SelfFlag_InitRes, C);
return;
}
@@ -262,7 +262,7 @@ void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
const ProgramState *state = C.getState();
for (CallExpr::const_arg_iterator
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
- SVal argV = state->getSVal(*I);
+ SVal argV = state->getSVal(*I, C.getLocationContext());
if (isSelfVar(argV, C)) {
unsigned selfFlags = getSelfFlags(state->getSVal(cast<Loc>(argV)), C);
C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
@@ -278,9 +278,10 @@ void ObjCSelfInitChecker::checkPreStmt(const CallExpr *CE,
void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
for (CallExpr::const_arg_iterator
I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
- SVal argV = state->getSVal(*I);
+ SVal argV = state->getSVal(*I, LCtx);
if (isSelfVar(argV, C)) {
SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
state = state->remove<PreCallSelfFlags>();
@@ -289,7 +290,7 @@ void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
SelfFlagEnum prevFlags = (SelfFlagEnum)state->get<PreCallSelfFlags>();
state = state->remove<PreCallSelfFlags>();
- addSelfFlag(state, state->getSVal(CE), prevFlags, C);
+ addSelfFlag(state, state->getSVal(CE, LCtx), prevFlags, C);
return;
}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
index 845ae4f0fcc..6adc4dc8601 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
@@ -37,8 +37,9 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *B,
return;
const ProgramState *state = C.getState();
- SVal LV = state->getSVal(B->getLHS());
- SVal RV = state->getSVal(B->getRHS());
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal LV = state->getSVal(B->getLHS(), LCtx);
+ SVal RV = state->getSVal(B->getRHS(), LCtx);
const MemRegion *LR = LV.getAsRegion();
diff --git a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
index 5e5e3e3bfd1..51f57a20f3e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
@@ -40,8 +40,9 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
return;
const ProgramState *state = C.getState();
- SVal LV = state->getSVal(B->getLHS());
- SVal RV = state->getSVal(B->getRHS());
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal LV = state->getSVal(B->getLHS(), LCtx);
+ SVal RV = state->getSVal(B->getRHS(), LCtx);
const MemRegion *LR = LV.getAsRegion();
const MemRegion *RR = RV.getAsRegion();
diff --git a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index 45988f0a097..a3bbd258591 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -57,6 +57,7 @@ template <> struct ProgramStateTrait<LockSet> :
void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
StringRef FName = C.getCalleeName(CE);
if (FName.empty())
return;
@@ -67,24 +68,28 @@ void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
if (FName == "pthread_mutex_lock" ||
FName == "pthread_rwlock_rdlock" ||
FName == "pthread_rwlock_wrlock")
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), false, PthreadSemantics);
+ AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
+ false, PthreadSemantics);
else if (FName == "lck_mtx_lock" ||
FName == "lck_rw_lock_exclusive" ||
FName == "lck_rw_lock_shared")
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), false, XNUSemantics);
+ AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
+ false, XNUSemantics);
else if (FName == "pthread_mutex_trylock" ||
FName == "pthread_rwlock_tryrdlock" ||
FName == "pthread_rwlock_tryrwlock")
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), true, PthreadSemantics);
+ AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
+ true, PthreadSemantics);
else if (FName == "lck_mtx_try_lock" ||
FName == "lck_rw_try_lock_exclusive" ||
FName == "lck_rw_try_lock_shared")
- AcquireLock(C, CE, state->getSVal(CE->getArg(0)), true, XNUSemantics);
+ AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
+ true, XNUSemantics);
else if (FName == "pthread_mutex_unlock" ||
FName == "pthread_rwlock_unlock" ||
FName == "lck_mtx_unlock" ||
FName == "lck_rw_done")
- ReleaseLock(C, CE, state->getSVal(CE->getArg(0)));
+ ReleaseLock(C, CE, state->getSVal(CE->getArg(0), LCtx));
}
void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
@@ -97,7 +102,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
const ProgramState *state = C.getState();
- SVal X = state->getSVal(CE);
+ SVal X = state->getSVal(CE, C.getLocationContext());
if (X.isUnknownOrUndef())
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 24df0083f50..8ba1edbb414 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1312,7 +1312,7 @@ RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
SVal receiverV;
if (Receiver) {
- receiverV = state->getSValAsScalarOrLoc(Receiver);
+ receiverV = state->getSValAsScalarOrLoc(Receiver, LC);
// FIXME: Eventually replace the use of state->get<RefBindings> with
// a generic API for reasoning about the Objective-C types of symbolic
@@ -1841,6 +1841,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
// Check if the type state has changed.
const ProgramState *PrevSt = PrevN->getState();
const ProgramState *CurrSt = N->getState();
+ const LocationContext *LCtx = N->getLocationContext();
const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
if (!CurrT) return NULL;
@@ -1860,7 +1861,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Get the name of the callee (if it is available).
- SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee());
+ SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
if (const FunctionDecl *FD = X.getAsFunctionDecl())
os << "Call to function '" << *FD << '\'';
else
@@ -1920,7 +1921,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
// Retrieve the value of the argument. Is it the symbol
// we are interested in?
- if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
+ if (CurrSt->getSValAsScalarOrLoc(*AI, LCtx).getAsLocSymbol() != Sym)
continue;
// We have an argument. Get the effect!
@@ -1929,7 +1930,8 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
}
else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
if (const Expr *receiver = ME->getInstanceReceiver())
- if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
+ if (CurrSt->getSValAsScalarOrLoc(receiver, LCtx)
+ .getAsLocSymbol() == Sym) {
// The symbol we are tracking is the receiver.
AEffects.push_back(Summ->getReceiverEffect());
}
@@ -1957,7 +1959,8 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
if (contains(AEffects, MakeCollectable)) {
// Get the name of the function.
const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
- SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
+ SVal X =
+ CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee(), LCtx);
const FunctionDecl *FD = X.getAsFunctionDecl();
if (GCEnabled) {
@@ -2069,7 +2072,7 @@ PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
I!=E; ++I)
if (const Expr *Exp = dyn_cast_or_null<Expr>(*I))
- if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
+ if (CurrSt->getSValAsScalarOrLoc(Exp, LCtx).getAsLocSymbol() == Sym) {
P->addRange(Exp->getSourceRange());
break;
}
@@ -2505,7 +2508,8 @@ void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
const ProgramState *state = C.getState();
const BlockDataRegion *R =
- cast<BlockDataRegion>(state->getSVal(BE).getAsRegion());
+ cast<BlockDataRegion>(state->getSVal(BE,
+ C.getLocationContext()).getAsRegion());
BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
E = R->referenced_vars_end();
@@ -2555,7 +2559,7 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
}
const ProgramState *state = C.getState();
- SymbolRef Sym = state->getSVal(CE).getAsLocSymbol();
+ SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
if (!Sym)
return;
const RefVal* T = state->get<RefBindings>(Sym);
@@ -2579,7 +2583,7 @@ void RetainCountChecker::checkPostStmt(const CallExpr *CE,
// Get the callee.
const ProgramState *state = C.getState();
const Expr *Callee = CE->getCallee();
- SVal L = state->getSVal(Callee);
+ SVal L = state->getSVal(Callee, C.getLocationContext());
RetainSummaryManager &Summaries = getSummaryManager(C);
const RetainSummary *Summ = 0;
@@ -2599,7 +2603,7 @@ void RetainCountChecker::checkPostStmt(const CallExpr *CE,
if (!Summ)
Summ = Summaries.getDefaultSummary();
- checkSummary(*Summ, CallOrObjCMessage(CE, state), C);
+ checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
}
void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE,
@@ -2616,7 +2620,7 @@ void RetainCountChecker::checkPostStmt(const CXXConstructExpr *CE,
return;
const ProgramState *state = C.getState();
- checkSummary(*Summ, CallOrObjCMessage(CE, state), C);
+ checkSummary(*Summ, CallOrObjCMessage(CE, state, C.getLocationContext()), C);
}
void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg,
@@ -2637,7 +2641,7 @@ void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg,
if (!Summ)
return;
- checkSummary(*Summ, CallOrObjCMessage(Msg, state), C);
+ checkSummary(*Summ, CallOrObjCMessage(Msg, state, C.getLocationContext()), C);
}
/// GetReturnType - Used to get the return type of a message expression or
@@ -2737,7 +2741,8 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
case RetEffect::OwnedAllocatedSymbol:
case RetEffect::OwnedSymbol: {
- SymbolRef Sym = state->getSVal(CallOrMsg.getOriginExpr()).getAsSymbol();
+ SymbolRef Sym = state->getSVal(CallOrMsg.getOriginExpr(),
+ C.getLocationContext()).getAsSymbol();
if (!Sym)
break;
@@ -2764,7 +2769,7 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
case RetEffect::ARCNotOwnedSymbol:
case RetEffect::NotOwnedSymbol: {
const Expr *Ex = CallOrMsg.getOriginExpr();
- SymbolRef Sym = state->getSVal(Ex).getAsSymbol();
+ SymbolRef Sym = state->getSVal(Ex, C.getLocationContext()).getAsSymbol();
if (!Sym)
break;
@@ -3030,14 +3035,15 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
return false;
// Bind the return value.
- SVal RetVal = state->getSVal(CE->getArg(0));
+ const LocationContext *LCtx = C.getLocationContext();
+ SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
if (RetVal.isUnknown()) {
// If the receiver is unknown, conjure a return value.
SValBuilder &SVB = C.getSValBuilder();
unsigned Count = C.getCurrentBlockCount();
SVal RetVal = SVB.getConjuredSymbolVal(0, CE, ResultTy, Count);
}
- state = state->BindExpr(CE, RetVal, false);
+ state = state->BindExpr(CE, LCtx, RetVal, false);
// FIXME: This should not be necessary, but otherwise the argument seems to be
// considered alive during the next statement.
@@ -3072,7 +3078,8 @@ void RetainCountChecker::checkPreStmt(const ReturnStmt *S,
return;
const ProgramState *state = C.getState();
- SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol();
+ SymbolRef Sym =
+ state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
if (!Sym)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index e761bff8558..f176eecf34f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -39,7 +39,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
if (!RetE)
return;
- SVal V = state->getSVal(RetE);
+ SVal V = state->getSVal(RetE, C.getLocationContext());
const MemRegion *R = V.getAsRegion();
const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(R);
diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
index e8c8d902a5e..e1316b56e78 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
@@ -38,7 +38,7 @@ void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
if (!RetE)
return;
- if (!C.getState()->getSVal(RetE).isUndef())
+ if (!C.getState()->getSVal(RetE, C.getLocationContext()).isUndef())
return;
ExplodedNode *N = C.generateSink();
diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 0d3059e01a7..8eda407f8ee 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -119,7 +119,7 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
if (!RetE)
return;
- SVal V = C.getState()->getSVal(RetE);
+ SVal V = C.getState()->getSVal(RetE, C.getLocationContext());
const MemRegion *R = V.getAsRegion();
if (!R || !R->hasStackStorage())
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 2f96bbfeac6..c746c775ab6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -223,7 +223,7 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
SValBuilder &svalBuilder = C.getSValBuilder();
DefinedSVal RetVal =
cast<DefinedSVal>(svalBuilder.getConjuredSymbolVal(0, CE, Count));
- state = state->BindExpr(CE, RetVal);
+ state = state->BindExpr(CE, C.getLocationContext(), RetVal);
ConstraintManager &CM = C.getConstraintManager();
// Bifurcate the state into two: one with a valid FILE* pointer, the other
@@ -251,22 +251,25 @@ void StreamChecker::Fclose(CheckerContext &C, const CallExpr *CE) const {
void StreamChecker::Fread(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(3)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Fwrite(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(3)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(3), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!(state = CheckNullStream(state->getSVal(CE->getArg(0)), state, C)))
+ if (!(state = CheckNullStream(state->getSVal(CE->getArg(0),
+ C.getLocationContext()), state, C)))
return;
// Check the legality of the 'whence' argument of 'fseek'.
- SVal Whence = state->getSVal(CE->getArg(2));
+ SVal Whence = state->getSVal(CE->getArg(2), C.getLocationContext());
const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Whence);
if (!CI)
@@ -289,49 +292,57 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
void StreamChecker::Ftell(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Rewind(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Fgetpos(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Fsetpos(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Clearerr(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Feof(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Ferror(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) const {
const ProgramState *state = C.getState();
- if (!CheckNullStream(state->getSVal(CE->getArg(0)), state, C))
+ if (!CheckNullStream(state->getSVal(CE->getArg(0), C.getLocationContext()),
+ state, C))
return;
}
@@ -361,7 +372,8 @@ const ProgramState *StreamChecker::CheckNullStream(SVal SV, const ProgramState *
const ProgramState *StreamChecker::CheckDoubleClose(const CallExpr *CE,
const ProgramState *state,
CheckerContext &C) const {
- SymbolRef Sym = state->getSVal(CE->getArg(0)).getAsSymbol();
+ SymbolRef Sym =
+ state->getSVal(CE->getArg(0), C.getLocationContext()).getAsSymbol();
if (!Sym)
return state;
@@ -442,7 +454,7 @@ void StreamChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
return;
const ProgramState *state = C.getState();
- SymbolRef Sym = state->getSVal(RetE).getAsSymbol();
+ SymbolRef Sym = state->getSVal(RetE, C.getLocationContext()).getAsSymbol();
if (!Sym)
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
index 415346f29c4..297beaeedcd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
@@ -47,7 +47,7 @@ void TaintTesterChecker::checkPostStmt(const Expr *E,
if (!State)
return;
- if (State->isTainted(E)) {
+ if (State->isTainted(E, C.getLocationContext())) {
if (ExplodedNode *N = C.addTransition()) {
initBugType();
BugReport *report = new BugReport(*BT, "tainted",N);
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index afb79b5d166..fc0b9c2ec6f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -28,8 +28,10 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
struct FindUndefExpr {
const ProgramState *St;
+ const LocationContext *LCtx;
- FindUndefExpr(const ProgramState *S) : St(S) {}
+ FindUndefExpr(const ProgramState *S, const LocationContext *L)
+ : St(S), LCtx(L) {}
const Expr *FindExpr(const Expr *Ex) {
if (!MatchesCriteria(Ex))
@@ -45,7 +47,9 @@ class UndefBranchChecker : public Checker<check::BranchCondition> {
return Ex;
}
- bool MatchesCriteria(const Expr *Ex) { return St->getSVal(Ex).isUndef(); }
+ bool MatchesCriteria(const Expr *Ex) {
+ return St->getSVal(Ex, LCtx).isUndef();
+ }
};
public:
@@ -56,7 +60,7 @@ public:
void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
CheckerContext &Ctx) const {
- SVal X = Ctx.getState()->getSVal(Condition);
+ SVal X = Ctx.getState()->getSVal(Condition, Ctx.getLocationContext());
if (X.isUndef()) {
// Generate a sink node, which implicitly marks both outgoing branches as
// infeasible.
@@ -90,7 +94,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
if (PS->getStmt() == Ex)
St = PrevN->getState();
- FindUndefExpr FindIt(St);
+ FindUndefExpr FindIt(St, Ctx.getLocationContext());
Ex = FindIt.FindExpr(Ex);
// Emit the bug report.
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
index 82c9fd4a86b..60f1f5b8e34 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
@@ -57,7 +57,8 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
const ProgramState *state = C.getState();
const BlockDataRegion *R =
- cast<BlockDataRegion>(state->getSVal(BE).getAsRegion());
+ cast<BlockDataRegion>(state->getSVal(BE,
+ C.getLocationContext()).getAsRegion());
BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
E = R->referenced_vars_end();
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 7ae966865c8..b074ff918e8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -36,7 +36,8 @@ public:
void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
CheckerContext &C) const {
const ProgramState *state = C.getState();
- if (state->getSVal(B).isUndef()) {
+ const LocationContext *LCtx = C.getLocationContext();
+ if (state->getSVal(B, LCtx).isUndef()) {
// Generate an error node.
ExplodedNode *N = C.generateSink();
if (!N)
@@ -50,11 +51,11 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
const Expr *Ex = NULL;
bool isLeft = true;
- if (state->getSVal(B->getLHS()).isUndef()) {
+ if (state->getSVal(B->getLHS(), LCtx).isUndef()) {
Ex = B->getLHS()->IgnoreParenCasts();
isLeft = true;
}
- else if (state->getSVal(B->getRHS()).isUndef()) {
+ else if (state->getSVal(B->getRHS(), LCtx).isUndef()) {
Ex = B->getRHS()->IgnoreParenCasts();
isLeft = false;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
index bb6831b7830..ee58a043cc0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
@@ -34,7 +34,7 @@ public:
void
UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
CheckerContext &C) const {
- if (C.getState()->getSVal(A->getIdx()).isUndef()) {
+ if (C.getState()->getSVal(A->getIdx(), C.getLocationContext()).isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT)
BT.reset(new BuiltinBug("Array subscript is undefined"));
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index 5ca4a9fe46d..bb9eeb1fa8c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -55,7 +55,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
if (B->isCompoundAssignmentOp()) {
const ProgramState *state = C.getState();
- if (state->getSVal(B->getLHS()).isUndef()) {
+ if (state->getSVal(B->getLHS(), C.getLocationContext()).isUndef()) {
str = "The left expression of the compound assignment is an "
"uninitialized value. The computed value will also be garbage";
ex = B->getLHS();
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 28ff6971a24..420acd5aacd 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -91,7 +91,7 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
// Now check if oflags has O_CREAT set.
const Expr *oflagsEx = CE->getArg(1);
- const SVal V = state->getSVal(oflagsEx);
+ const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
if (!isa<NonLoc>(V)) {
// The case where 'V' can be a location can only be due to a bad header,
// so in this case bail out.
@@ -149,7 +149,8 @@ void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
// Check if the first argument is stack allocated. If so, issue a warning
// because that's likely to be bad news.
const ProgramState *state = C.getState();
- const MemRegion *R = state->getSVal(CE->getArg(0)).getAsRegion();
+ const MemRegion *R =
+ state->getSVal(CE->getArg(0), C.getLocationContext()).getAsRegion();
if (!R || !isa<StackSpaceRegion>(R->getMemorySpace()))
return;
@@ -229,7 +230,7 @@ void UnixAPIChecker::CheckCallocZero(CheckerContext &C,
unsigned int i;
for (i = 0; i < nArgs; i++) {
const Expr *arg = CE->getArg(i);
- SVal argVal = state->getSVal(arg);
+ SVal argVal = state->getSVal(arg, C.getLocationContext());
if (argVal.isUnknownOrUndef()) {
if (i == 0)
continue;
@@ -265,7 +266,7 @@ void UnixAPIChecker::CheckMallocZero(CheckerContext &C,
const ProgramState *state = C.getState();
const ProgramState *trueState = NULL, *falseState = NULL;
const Expr *arg = CE->getArg(0);
- SVal argVal = state->getSVal(arg);
+ SVal argVal = state->getSVal(arg, C.getLocationContext());
if (argVal.isUnknownOrUndef())
return;
@@ -289,7 +290,7 @@ void UnixAPIChecker::CheckReallocZero(CheckerContext &C,
const ProgramState *state = C.getState();
const ProgramState *trueState = NULL, *falseState = NULL;
const Expr *arg = CE->getArg(1);
- SVal argVal = state->getSVal(arg);
+ SVal argVal = state->getSVal(arg, C.getLocationContext());
if (argVal.isUnknownOrUndef())
return;
diff --git a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index 969a896b63b..0308bf5c11b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -50,7 +50,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
// FIXME: Handle multi-dimensional VLAs.
const Expr *SE = VLA->getSizeExpr();
const ProgramState *state = C.getState();
- SVal sizeV = state->getSVal(SE);
+ SVal sizeV = state->getSVal(SE, C.getLocationContext());
if (sizeV.isUndef()) {
// Generate an error node.
OpenPOWER on IntegriCloud