diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
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. |