48 #include "llvm/ADT/ArrayRef.h"
49 #include "llvm/ADT/None.h"
50 #include "llvm/ADT/Optional.h"
51 #include "llvm/ADT/STLExtras.h"
52 #include "llvm/ADT/SmallPtrSet.h"
53 #include "llvm/ADT/SmallString.h"
54 #include "llvm/ADT/SmallVector.h"
55 #include "llvm/ADT/StringExtras.h"
56 #include "llvm/ADT/StringRef.h"
57 #include "llvm/Support/Casting.h"
58 #include "llvm/Support/ErrorHandling.h"
59 #include "llvm/Support/raw_ostream.h"
66 using namespace clang;
68 using namespace bugreporter;
102 const auto *E = dyn_cast<Expr>(S);
107 if (
const auto *CE = dyn_cast<CastExpr>(E)) {
108 if (CE->getCastKind() == CK_LValueToRValue) {
112 E = CE->getSubExpr();
113 }
else if (
const auto *B = dyn_cast<BinaryOperator>(E)) {
122 }
else if (
const auto *
U = dyn_cast<UnaryOperator>(E)) {
123 if (
U->getOpcode() == UO_Deref ||
U->getOpcode() == UO_AddrOf ||
124 (
U->isIncrementDecrementOp() &&
U->getType()->isPointerType())) {
135 else if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
137 }
else if (
const auto *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
138 E = IvarRef->getBase();
139 }
else if (
const auto *AE = dyn_cast<ArraySubscriptExpr>(E)) {
141 }
else if (
const auto *PE = dyn_cast<ParenExpr>(E)) {
142 E = PE->getSubExpr();
143 }
else if (
const auto *FE = dyn_cast<FullExpr>(E)) {
144 E = FE->getSubExpr();
154 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E))
155 if (CE->getCastKind() == CK_LValueToRValue)
156 E = CE->getSubExpr();
161 static const MemRegion *
163 bool LookingForReference =
true) {
164 if (
const auto *DR = dyn_cast<DeclRefExpr>(E)) {
165 if (
const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
166 if (LookingForReference && !VD->getType()->isReferenceType())
169 ->getLValue(VD, N->getLocationContext())
192 const ExplodedNode *RightNode, SVal RightVal) {
193 if (LeftVal == RightVal)
196 const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
200 const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
204 return LLCV->getRegion() == RLCV->getRegion() &&
205 LLCV->getStore() == LeftNode->getState()->getStore() &&
206 RLCV->getStore() == RightNode->getState()->getStore();
210 const ExplodedNode *N) {
221 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CondVarExpr))
222 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
223 return State->getSVal(
State->getLValue(VD, LCtx));
225 if (
const auto *ME = dyn_cast<MemberExpr>(CondVarExpr))
226 if (
const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
227 if (
auto FieldL =
State->getSVal(ME, LCtx).getAs<Loc>())
228 return State->getRawSVal(*FieldL, FD->getType());
237 if (
auto CI =
V->getAs<nonloc::ConcreteInt>())
238 return &CI->getValue();
243 const ExplodedNode *N,
244 const PathSensitiveBugReport *B) {
248 if (!B->getErrorNode()->getStackFrame()->isParentOf(N->getStackFrame()))
259 const PathSensitiveBugReport *B) {
261 return B->getInterestingnessKind(*V).has_value();
267 BugReporterContext &BRC) {
270 BRC.getSourceManager(),
271 BRC.getASTContext().getLangOpts());
280 while (
SM.isMacroArgExpansion(Loc))
281 Loc =
SM.getImmediateExpansionRange(Loc).getBegin();
282 std::pair<FileID, unsigned> TLInfo =
SM.getDecomposedLoc(Loc);
292 const ExplodedNode *N,
295 ProgramStateManager &Mgr = N->getState()->getStateManager();
302 if (
auto PS = N->getLocationAs<
PostStmt>())
304 if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(
305 N->getSVal(BO->getLHS()).getAsRegion()))
309 SVal ValueAtN = N->getState()->getSVal(RegionOfInterest);
310 if (!Mgr.getSValBuilder()
311 .areEqual(
State, ValueAtN, ValueAfter)
312 .isConstrainedTrue() &&
313 (!ValueAtN.isUndef() || !ValueAfter.isUndef()))
342 auto P = std::make_shared<PathDiagnosticEventPiece>(
354 bool NoStateChangeFuncVisitor::isModifiedInFrame(
const ExplodedNode *N) {
357 if (!FramesModifyingCalculated.count(SCtx))
358 findModifyingFrames(N);
359 return FramesModifying.count(SCtx);
362 void NoStateChangeFuncVisitor::markFrameAsModifying(
365 auto p = FramesModifying.insert(SCtx);
381 auto IsMatchingCallExitEnd = [OrigSCtx](
const ExplodedNode *N) {
385 while (N && !IsMatchingCallExitEnd(N)) {
386 assert(N->succ_size() <= 1 &&
387 "This function is to be used on the trimmed ExplodedGraph!");
388 N = N->getFirstSucc();
393 void NoStateChangeFuncVisitor::findModifyingFrames(
394 const ExplodedNode *
const CallExitBeginN) {
401 const ExplodedNode *CurrCallExitBeginN = CallExitBeginN;
404 for (
const ExplodedNode *CurrN = CallExitBeginN; CurrN;
405 CurrN = CurrN->getFirstPred()) {
408 CurrCallExitBeginN = CurrN;
410 FramesModifyingCalculated.insert(CurrentSCtx);
415 if (
auto CE = CurrN->getLocationAs<
CallEnter>()) {
417 if (wasModifiedInFunction(CurrN, CallExitEndN))
418 markFrameAsModifying(CurrentSCtx);
429 if (CE->getCalleeContext() == OriginalSCtx) {
430 markFrameAsModifying(CurrentSCtx);
435 if (wasModifiedBeforeCallExit(CurrN, CurrCallExitBeginN))
436 markFrameAsModifying(CurrentSCtx);
449 if (!CallExitLoc || isModifiedInFrame(N))
464 if (Call->isInSystemHeader()) {
479 if (
const auto *MC = dyn_cast<ObjCMethodCall>(Call)) {
486 if (
const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) {
489 return maybeEmitNoteForCXXThis(R, *CCall, N);
492 return maybeEmitNoteForParameters(R, *Call, N);
513 static const unsigned DEREFERENCE_LIMIT = 2;
520 MmrMgr(R->getMemRegionManager()),
521 SM(MmrMgr.getContext().getSourceManager()),
522 PP(MmrMgr.getContext().getPrintingPolicy()) {}
524 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
527 ID.AddPointer(RegionOfInterest);
534 wasModifiedBeforeCallExit(
const ExplodedNode *CurrN,
535 const ExplodedNode *CallExitBeginN)
override;
545 const MemRegion *R,
const RegionVector &Vec = {},
551 maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
552 const ObjCMethodCall &Call,
553 const ExplodedNode *N)
override final;
556 maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
557 const CXXConstructorCall &Call,
558 const ExplodedNode *N)
override final;
561 maybeEmitNoteForParameters(PathSensitiveBugReport &R,
const CallEvent &Call,
562 const ExplodedNode *N)
override final;
569 maybeEmitNote(PathSensitiveBugReport &R,
const CallEvent &Call,
570 const ExplodedNode *N,
const RegionVector &FieldChain,
571 const MemRegion *MatchedRegion, StringRef FirstElement,
572 bool FirstIsReferenceType,
unsigned IndirectionLevel);
574 bool prettyPrintRegionName(
const RegionVector &FieldChain,
575 const MemRegion *MatchedRegion,
576 StringRef FirstElement,
bool FirstIsReferenceType,
577 unsigned IndirectionLevel,
578 llvm::raw_svector_ostream &os);
580 StringRef prettyPrintFirstElement(StringRef FirstElement,
581 bool MoreItemsExpected,
582 int IndirectionLevel,
583 llvm::raw_svector_ostream &os);
591 using namespace ast_matchers;
592 const char *IvarBind =
"Ivar";
596 hasOperatorName(
"="),
597 hasLHS(ignoringParenImpCasts(
603 if (IvarRef->isFreeIvar())
606 const Expr *
Base = IvarRef->getBase();
607 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
Base))
608 Base = ICE->getSubExpr();
610 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
Base))
611 if (
const auto *
ID = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
627 NoStoreFuncVisitor::findRegionOfInterestInRecord(
632 if (depth == DEREFERENCE_LIMIT)
635 if (
const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
636 if (!RDX->hasDefinition())
641 if (
const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
642 for (
const auto &II : RDX->bases())
643 if (
const RecordDecl *RRD = II.getType()->getAsRecordDecl())
645 findRegionOfInterestInRecord(RRD,
State, R, Vec, depth))
650 const FieldRegion *FR = MmrMgr.
getFieldRegion(I, cast<SubRegion>(R));
651 const SVal
V =
State->getSVal(FR);
652 const MemRegion *VR =
V.getAsRegion();
654 RegionVector VecF = Vec;
657 if (RegionOfInterest == VR)
662 findRegionOfInterestInRecord(RRD,
State, FR, VecF, depth + 1))
671 findRegionOfInterestInRecord(RRD,
State, VR, VecF, depth + 1))
679 NoStoreFuncVisitor::maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
680 const ObjCMethodCall &Call,
681 const ExplodedNode *N) {
682 if (
const auto *IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest)) {
683 const MemRegion *SelfRegion =
Call.getReceiverSVal().getAsRegion();
684 if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
687 return maybeEmitNote(R, Call, N, {}, SelfRegion,
"self",
694 NoStoreFuncVisitor::maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
695 const CXXConstructorCall &Call,
696 const ExplodedNode *N) {
697 const MemRegion *ThisR =
Call.getCXXThisVal().getAsRegion();
698 if (RegionOfInterest->isSubRegionOf(ThisR) && !
Call.getDecl()->isImplicit())
699 return maybeEmitNote(R, Call, N, {}, ThisR,
"this",
714 PathSensitiveBugReport &R,
const CallEvent &Call,
const ExplodedNode *N) {
716 for (
unsigned I = 0; I <
Call.getNumArgs() && I <
Parameters.size(); ++I) {
718 SVal
V =
Call.getArgSVal(I);
722 unsigned IndirectionLevel = 1;
724 while (
const MemRegion *MR =
V.getAsRegion()) {
726 return maybeEmitNote(R, Call, N, {}, MR, ParamName,
727 ParamIsReferenceType, IndirectionLevel);
730 if (PT.isNull() || PT->isVoidType())
735 if (
const RecordDecl *RD = PT->getAsRecordDecl())
737 findRegionOfInterestInRecord(RD,
State, MR))
738 return maybeEmitNote(R, Call, N, *
P, RegionOfInterest, ParamName,
739 ParamIsReferenceType, IndirectionLevel);
741 V =
State->getSVal(MR, PT);
750 bool NoStoreFuncVisitor::wasModifiedBeforeCallExit(
751 const ExplodedNode *CurrN,
const ExplodedNode *CallExitBeginN) {
753 RegionOfInterest, CurrN,
754 CallExitBeginN->getState()->getSVal(RegionOfInterest));
758 ", which participates in a condition later";
761 PathSensitiveBugReport &R,
const CallEvent &Call,
const ExplodedNode *N,
762 const RegionVector &FieldChain,
const MemRegion *MatchedRegion,
763 StringRef FirstElement,
bool FirstIsReferenceType,
764 unsigned IndirectionLevel) {
766 PathDiagnosticLocation L =
772 if (!L.hasValidLocation())
776 llvm::raw_svector_ostream os(sbuf);
777 os <<
"Returning without writing to '";
780 if (!prettyPrintRegionName(FieldChain, MatchedRegion, FirstElement,
781 FirstIsReferenceType, IndirectionLevel, os))
787 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
790 bool NoStoreFuncVisitor::prettyPrintRegionName(
const RegionVector &FieldChain,
791 const MemRegion *MatchedRegion,
792 StringRef FirstElement,
793 bool FirstIsReferenceType,
794 unsigned IndirectionLevel,
795 llvm::raw_svector_ostream &os) {
797 if (FirstIsReferenceType)
800 RegionVector RegionSequence;
803 assert(RegionOfInterest->isSubRegionOf(MatchedRegion));
804 const MemRegion *R = RegionOfInterest;
805 while (R != MatchedRegion) {
806 RegionSequence.push_back(R);
807 R = cast<SubRegion>(R)->getSuperRegion();
809 std::reverse(RegionSequence.begin(), RegionSequence.end());
810 RegionSequence.append(FieldChain.begin(), FieldChain.end());
813 for (
const MemRegion *R : RegionSequence) {
817 if (isa<CXXBaseObjectRegion, CXXTempObjectRegion>(R))
821 Sep = prettyPrintFirstElement(FirstElement,
823 IndirectionLevel, os);
828 if (!isa<DeclRegion>(R))
831 const auto *DR = cast<DeclRegion>(R);
832 Sep = DR->getValueType()->isAnyPointerType() ?
"->" :
".";
833 DR->getDecl()->getDeclName().print(os, PP);
837 prettyPrintFirstElement(FirstElement,
838 false, IndirectionLevel, os);
842 StringRef NoStoreFuncVisitor::prettyPrintFirstElement(
843 StringRef FirstElement,
bool MoreItemsExpected,
int IndirectionLevel,
844 llvm::raw_svector_ostream &os) {
847 if (IndirectionLevel > 0 && MoreItemsExpected) {
852 if (IndirectionLevel > 0 && MoreItemsExpected)
855 for (
int i = 0; i < IndirectionLevel; i++)
859 if (IndirectionLevel > 0 && MoreItemsExpected)
873 class MacroNullReturnSuppressionVisitor final :
public BugReporterVisitor {
874 const SubRegion *RegionOfInterest;
875 const SVal ValueAtDereference;
879 bool WasModified =
false;
882 MacroNullReturnSuppressionVisitor(
const SubRegion *R,
const SVal
V)
883 : RegionOfInterest(R), ValueAtDereference(
V) {}
886 BugReporterContext &BRC,
887 PathSensitiveBugReport &BR)
override {
891 auto BugPoint = BR.getErrorNode()->getLocation().getAs<
StmtPoint>();
896 if (
auto Loc = matchAssignment(N)) {
901 BR.markInvalid(getTag(), MacroName.c_str());
911 static void addMacroVisitorIfNecessary(
912 const ExplodedNode *N,
const MemRegion *R,
913 bool EnableNullFPSuppression, PathSensitiveBugReport &BR,
915 AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
916 if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths &&
918 BR.addVisitor<MacroNullReturnSuppressionVisitor>(R->getAs<SubRegion>(),
922 void* getTag()
const {
924 return static_cast<void *
>(&Tag);
927 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
928 ID.AddPointer(getTag());
935 const Stmt *S = N->getStmtForDiagnostics();
937 auto *LCtx = N->getLocationContext();
941 if (
const auto *DS = dyn_cast<DeclStmt>(S)) {
942 if (
const auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl()))
943 if (
const Expr *RHS = VD->getInit())
944 if (RegionOfInterest->isSubRegionOf(
945 State->getLValue(VD, LCtx).getAsRegion()))
946 return RHS->getBeginLoc();
947 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(S)) {
948 const MemRegion *R = N->getSVal(BO->getLHS()).getAsRegion();
949 const Expr *RHS = BO->getRHS();
950 if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) {
977 bool EnableNullFPSuppression;
978 bool ShouldInvalidate =
true;
987 EnableNullFPSuppression(Suppressed), Options(Options), TKind(TKind) {}
989 static void *getTag() {
991 return static_cast<void *
>(&Tag);
994 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
995 ID.AddPointer(ReturnVisitor::getTag());
996 ID.AddPointer(CalleeSFC);
997 ID.AddBoolean(EnableNullFPSuppression);
1001 BugReporterContext &BRC,
1002 PathSensitiveBugReport &BR) {
1004 if (N->getLocationContext() != CalleeSFC)
1011 const auto *
Ret = dyn_cast<ReturnStmt>(SP->getStmt());
1018 SVal
V =
State->getSVal(
Ret, CalleeSFC);
1019 if (
V.isUnknownOrUndef())
1025 const Expr *RetE =
Ret->getRetValue();
1026 assert(RetE &&
"Tracking a return value for a void function");
1031 if ((LValue =
V.getAs<Loc>())) {
1032 SVal RValue =
State->getRawSVal(*LValue, RetE->
getType());
1033 if (isa<DefinedSVal>(RValue))
1039 if (isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(
V))
1045 getParentTracker().track(RetE, N, {TKind, EnableNullFPSuppression});
1049 llvm::raw_svector_ostream Out(Msg);
1051 bool WouldEventBeMeaningless =
false;
1053 if (
State->isNull(
V).isConstrainedTrue()) {
1059 if (EnableNullFPSuppression &&
1060 Options.ShouldAvoidSuppressingNullArgumentPaths)
1061 Mode = MaybeUnsuppress;
1064 Out <<
"Returning nil";
1066 Out <<
"Returning null pointer";
1069 Out <<
"Returning zero";
1073 if (
auto CI =
V.getAs<nonloc::ConcreteInt>()) {
1074 Out <<
"Returning the value " << CI->getValue();
1081 if (N->getCFG().size() == 3)
1082 WouldEventBeMeaningless =
true;
1084 Out << (isa<Loc>(
V) ?
"Returning pointer" :
"Returning value");
1089 if (
const MemRegion *MR = LValue->getAsRegion()) {
1090 if (MR->canPrintPretty()) {
1091 Out <<
" (reference to ";
1092 MR->printPretty(Out);
1098 if (
const auto *DR = dyn_cast<DeclRefExpr>(RetE))
1099 if (
const auto *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
1100 Out <<
" (loaded from '" << *DD <<
"')";
1103 PathDiagnosticLocation L(
Ret, BRC.getSourceManager(), CalleeSFC);
1104 if (!L.isValid() || !L.asLocation().isValid())
1110 auto EventPiece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
1114 if (WouldEventBeMeaningless)
1115 EventPiece->setPrunable(
true);
1117 BR.markInteresting(CalleeSFC);
1123 BugReporterContext &BRC,
1124 PathSensitiveBugReport &BR) {
1125 assert(Options.ShouldAvoidSuppressingNullArgumentPaths);
1132 if (CE->getCalleeContext() != CalleeSFC)
1140 ProgramStateManager &StateMgr = BRC.getStateManager();
1141 CallEventManager &CallMgr = StateMgr.getCallEventManager();
1144 CallEventRef<>
Call = CallMgr.getCaller(CalleeSFC,
State);
1145 for (
unsigned I = 0, E =
Call->getNumArgs(); I != E; ++I) {
1150 const Expr *ArgE =
Call->getArgExpr(I);
1155 if (!
State->isNull(*ArgV).isConstrainedTrue())
1158 if (getParentTracker()
1159 .track(ArgE, N, {TKind, EnableNullFPSuppression})
1160 .FoundSomethingToTrack)
1161 ShouldInvalidate =
false;
1172 BugReporterContext &BRC,
1173 PathSensitiveBugReport &BR)
override {
1176 return visitNodeInitial(N, BRC, BR);
1177 case MaybeUnsuppress:
1178 return visitNodeMaybeUnsuppress(N, BRC, BR);
1183 llvm_unreachable(
"Invalid visit mode!");
1186 void finalizeVisitor(BugReporterContext &,
const ExplodedNode *,
1187 PathSensitiveBugReport &BR)
override {
1188 if (EnableNullFPSuppression && ShouldInvalidate)
1189 BR.markInvalid(ReturnVisitor::getTag(), CalleeSFC);
1204 bool Satisfied =
false;
1206 TrackingOptions Options;
1221 const MemRegion *R, TrackingOptions Options,
1224 OriginSFC(OriginSFC) {
1228 void Profile(llvm::FoldingSetNodeID &
ID)
const override;
1231 BugReporterContext &BRC,
1232 PathSensitiveBugReport &BR)
override;
1237 ID.AddPointer(&tag);
1240 ID.AddInteger(
static_cast<int>(Options.Kind));
1241 ID.AddBoolean(Options.EnableNullFPSuppression);
1258 const MemSpaceRegion *VarSpace = VR->getMemorySpace();
1259 const auto *FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace);
1264 assert(VR->getDecl()->isStaticLocal() &&
"non-static stackless VarRegion");
1268 assert(VR->getDecl()->hasLocalStorage());
1274 if (R->isBoundable())
1275 if (
const auto *TR = dyn_cast<TypedValueRegion>(R))
1276 return TR->getValueType()->isObjCObjectPointerType();
1287 const bool HasPrefix = SI.Dest->canPrintPretty();
1290 SI.Dest->printPretty(OS);
1294 const char *Action =
nullptr;
1296 switch (SI.StoreKind) {
1298 Action = HasPrefix ?
"initialized to " :
"Initializing to ";
1301 Action = HasPrefix ?
"captured by block as " :
"Captured by block as ";
1304 llvm_unreachable(
"Unexpected store kind");
1307 if (isa<loc::ConcreteInt>(SI.Value)) {
1308 OS << Action << (
isObjCPointer(SI.Dest) ?
"nil" :
"a null pointer value");
1310 }
else if (
auto CVal = SI.Value.getAs<nonloc::ConcreteInt>()) {
1311 OS << Action << CVal->getValue();
1313 }
else if (SI.Origin && SI.Origin->canPrintPretty()) {
1314 OS << Action <<
"the value of ";
1315 SI.Origin->printPretty(OS);
1324 if (SI.Value.isUndef()) {
1325 if (isa<VarRegion>(SI.Dest)) {
1326 const auto *VD = cast<VarDecl>(DS->getSingleDecl());
1328 if (VD->getInit()) {
1329 OS << (HasPrefix ?
"initialized" :
"Initializing")
1330 <<
" to a garbage value";
1332 OS << (HasPrefix ?
"declared" :
"Declaring")
1333 <<
" without an initial value";
1337 OS << (HasPrefix ?
"initialized" :
"Initialized") <<
" here";
1345 const auto *VR = cast<VarRegion>(SI.Dest);
1346 const auto *Param = cast<ParmVarDecl>(VR->getDecl());
1350 if (isa<loc::ConcreteInt>(SI.Value)) {
1352 :
"null pointer value");
1354 }
else if (SI.Value.isUndef()) {
1355 OS <<
"uninitialized value";
1357 }
else if (
auto CI = SI.Value.getAs<nonloc::ConcreteInt>()) {
1358 OS <<
"the value " << CI->getValue();
1360 }
else if (SI.Origin && SI.Origin->canPrintPretty()) {
1361 SI.Origin->printPretty(OS);
1368 unsigned Idx = Param->getFunctionScopeIndex() + 1;
1369 OS <<
" via " << Idx << llvm::getOrdinalSuffix(Idx) <<
" parameter";
1370 if (VR->canPrintPretty()) {
1372 VR->printPretty(OS);
1379 const bool HasSuffix = SI.Dest->canPrintPretty();
1381 if (isa<loc::ConcreteInt>(SI.Value)) {
1382 OS << (
isObjCPointer(SI.Dest) ?
"nil object reference stored"
1383 : (HasSuffix ?
"Null pointer value stored"
1384 :
"Storing null pointer value"));
1386 }
else if (SI.Value.isUndef()) {
1387 OS << (HasSuffix ?
"Uninitialized value stored"
1388 :
"Storing uninitialized value");
1390 }
else if (
auto CV = SI.Value.getAs<nonloc::ConcreteInt>()) {
1392 OS <<
"The value " << CV->getValue() <<
" is assigned";
1394 OS <<
"Assigning " << CV->getValue();
1396 }
else if (SI.Origin && SI.Origin->canPrintPretty()) {
1398 OS <<
"The value of ";
1399 SI.Origin->printPretty(OS);
1400 OS <<
" is assigned";
1402 OS <<
"Assigning the value of ";
1403 SI.Origin->printPretty(OS);
1407 OS << (HasSuffix ?
"Value assigned" :
"Assigning value");
1412 SI.Dest->printPretty(OS);
1417 BugReporterContext &BRC,
1418 PathSensitiveBugReport &BR) {
1422 const ExplodedNode *StoreSite =
nullptr;
1423 const ExplodedNode *Pred = Succ->getFirstPred();
1424 const Expr *InitE =
nullptr;
1425 bool IsParam =
false;
1428 if (
const auto *VR = dyn_cast<VarRegion>(R)) {
1431 InitE = VR->getDecl()->getInit();
1438 const MemRegion *FieldReg = (
const MemRegion *)PIP->getLocationValue();
1439 if (FieldReg == R) {
1441 InitE = PIP->getInitializer()->getInit();
1451 if (Succ->getState()->getSVal(R) !=
V)
1456 if (!PS || PS->getLocationValue() != R)
1466 if (BO->isAssignmentOp())
1467 InitE = BO->getRHS();
1474 if (
const auto *VR = dyn_cast<VarRegion>(R)) {
1476 if (
const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
1477 ProgramStateManager &StateMgr = BRC.getStateManager();
1478 CallEventManager &CallMgr = StateMgr.getCallEventManager();
1480 CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
1482 InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1485 assert(isa<ImplicitParamDecl>(VR->getDecl()));
1486 InitE = cast<ObjCMessageExpr>(CE->getCalleeContext()->getCallSite())
1495 if (
const auto *TmpR = dyn_cast<CXXTempObjectRegion>(R))
1496 InitE = TmpR->getExpr();
1510 getParentTracker().track(InitE, StoreSite, Options);
1514 const MemRegion *OldRegion =
nullptr;
1527 if (
const MemRegion *Candidate =
1529 const StoreManager &
SM = BRC.getStateManager().getStoreManager();
1533 for (
const ExplodedNode *N = StoreSite; N; N = N->getFirstPred()) {
1534 if (
SM.includedInBindings(N->getState()->getStore(), Candidate)) {
1536 if (N->getState()->getSVal(Candidate) ==
V) {
1537 OldRegion = Candidate;
1556 if (!OldRegion && StoreSite->getState()->getSVal(R) ==
V) {
1559 const ExplodedNode *NodeWithoutBinding = StoreSite->getFirstPred();
1561 NodeWithoutBinding && NodeWithoutBinding->getState()->getSVal(R) ==
V;
1562 NodeWithoutBinding = NodeWithoutBinding->getFirstPred()) {
1565 if (NodeWithoutBinding) {
1574 StoreManager::FindUniqueBinding FB(
V.getAsLocSymbol());
1575 BRC.getStateManager().iterBindings(NodeWithoutBinding->getState(), FB);
1577 OldRegion = FB.getRegion();
1582 !OriginSFC->isParentOf(StoreSite->getStackFrame()))
1587 llvm::raw_svector_ostream os(sbuf);
1597 const Stmt *S = PS->getStmt();
1598 const auto *DS = dyn_cast<DeclStmt>(S);
1599 const auto *VR = dyn_cast<VarRegion>(R);
1603 }
else if (isa<BlockExpr>(S)) {
1608 SVal
V = StoreSite->getSVal(S);
1609 if (
const auto *BDR =
1610 dyn_cast_or_null<BlockDataRegion>(
V.getAsRegion())) {
1611 if (
const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
1612 getParentTracker().track(
State->getSVal(OriginalR), OriginalR,
1613 Options, OriginSFC);
1618 }
else if (SI.StoreSite->getLocation().getAs<
CallEnter>() &&
1619 isa<VarRegion>(SI.Dest)) {
1623 return getParentTracker().handle(SI, BRC, Options);
1632 ID.AddPointer(&tag);
1633 ID.AddBoolean(Assumption);
1640 return "TrackConstraintBRVisitor";
1643 bool TrackConstraintBRVisitor::isUnderconstrained(
const ExplodedNode *N)
const {
1645 return N->
getState()->isNull(Constraint).isUnderconstrained();
1646 return (
bool)N->
getState()->assume(Constraint, !Assumption);
1657 if (!IsTrackingTurnedOn)
1658 if (!isUnderconstrained(N))
1659 IsTrackingTurnedOn =
true;
1660 if (!IsTrackingTurnedOn)
1665 if (isUnderconstrained(PrevN)) {
1672 assert(!isUnderconstrained(N));
1677 llvm::raw_svector_ostream os(sbuf);
1679 if (isa<Loc>(Constraint)) {
1680 os <<
"Assuming pointer value is ";
1681 os << (Assumption ?
"non-null" :
"null");
1684 if (os.str().empty())
1693 if (isa_and_nonnull<NoteTag>(
P.getTag()))
1701 auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
1702 X->setTag(getTag());
1703 return std::move(
X);
1718 if (!Options.ShouldSuppressInlinedDefensiveChecks)
1723 llvm::FoldingSetNodeID &
ID)
const {
1730 return "IDCVisitor";
1742 if (!IsTrackingTurnedOn)
1743 if (Succ->
getState()->isNull(
V).isConstrainedTrue())
1744 IsTrackingTurnedOn =
true;
1745 if (!IsTrackingTurnedOn)
1750 if (!Pred->
getState()->isNull(
V).isConstrainedTrue() &&
1751 Succ->
getState()->isNull(
V).isConstrainedTrue()) {
1757 if (CurLC != ReportLC && !CurLC->
isParentOf(ReportLC)) {
1772 const Stmt *CurTerminatorStmt =
nullptr;
1774 CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
1776 const Stmt *CurStmt = SP->getStmt();
1786 if (!CurTerminatorStmt)
1820 class TrackControlDependencyCondBRVisitor final
1824 llvm::SmallSet<const CFGBlock *, 32> VisitedBlocks;
1827 TrackControlDependencyCondBRVisitor(
TrackerRef ParentTracker,
1830 ControlDeps(&O->getCFG()) {}
1832 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
1838 BugReporterContext &BRC,
1839 PathSensitiveBugReport &BR)
override;
1843 static std::shared_ptr<PathDiagnosticEventPiece>
1845 const ExplodedNode *N,
1846 BugReporterContext &BRC) {
1848 if (BRC.getAnalyzerOptions().AnalysisDiagOpt ==
PD_NONE ||
1849 !BRC.getAnalyzerOptions().ShouldTrackConditionsDebug)
1854 BRC.getSourceManager(), BRC.getASTContext().getLangOpts()));
1856 return std::make_shared<PathDiagnosticEventPiece>(
1858 Cond, BRC.getSourceManager(), N->getLocationContext()),
1859 (Twine() +
"Tracking condition '" + ConditionText +
"'").str());
1887 if (
const auto *BinOp = dyn_cast<BinaryOperator>(ElseCond))
1888 if (BinOp->isLogicalOp())
1895 TrackControlDependencyCondBRVisitor::VisitNode(
const ExplodedNode *N,
1896 BugReporterContext &BRC,
1897 PathSensitiveBugReport &BR) {
1899 if (Origin->getStackFrame() != N->getStackFrame())
1905 if (!VisitedBlocks.insert(NB).second)
1911 if (!OriginB || !NB)
1917 if (ControlDeps.isControlDependent(OriginB, NB)) {
1943 if (isa<CallExpr>(InnerExpr))
1949 if (BR.addTrackedCondition(N)) {
1950 getParentTracker().track(InnerExpr, N,
1968 if (
const auto *FE = dyn_cast<FullExpr>(Ex))
1970 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(Ex))
1972 if (
const auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
1973 const auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
1974 if (PropRef && PropRef->isMessagingGetter()) {
1975 const Expr *GetterMessageSend =
1976 POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
1983 if (
const auto *CO = dyn_cast<ConditionalOperator>(Ex)) {
1986 const ExplodedNode *NI = N;
1990 const CFGBlock *srcBlk = BE->getSrc();
1993 bool TookTrueBranch = (*(srcBlk->
succ_begin()) == BE->getDst());
2001 NI = NI->getFirstPred();
2005 if (
auto *BO = dyn_cast<BinaryOperator>(Ex))
2009 if (
auto *UO = dyn_cast<UnaryOperator>(Ex)) {
2010 if (UO->getOpcode() == UO_LNot)
2021 if (UO->getOpcode() == UO_AddrOf && UO->getSubExpr()->isLValue())
2032 const Expr *Inner) {
2034 if (N->getStmtForDiagnostics() == Inner)
2047 StringRef NodeText) {
2053 P.getLocationContext());
2061 return std::make_shared<PathDiagnosticEventPiece>(L, NodeText);
2066 using StoreHandler::StoreHandler;
2069 TrackingOptions Opts)
override {
2072 llvm::raw_svector_ostream OS(Buffer);
2074 switch (SI.StoreKind) {
2075 case StoreInfo::Initialization:
2076 case StoreInfo::BlockCapture:
2079 case StoreInfo::CallArgument:
2090 return constructNote(SI, BRC, OS.str());
2096 using ExpressionHandler::ExpressionHandler;
2098 Tracker::Result handle(
const Expr *Inner,
const ExplodedNode *InputNode,
2099 const ExplodedNode *LVNode,
2100 TrackingOptions Opts)
override {
2101 PathSensitiveBugReport &Report = getParentTracker().getReport();
2109 if (LVNode->getState()
2110 ->getAnalysisManager()
2111 .getAnalyzerOptions()
2112 .ShouldTrackConditions) {
2113 Report.addVisitor<TrackControlDependencyCondBRVisitor>(
2114 &getParentTracker(), InputNode);
2124 using ExpressionHandler::ExpressionHandler;
2126 Tracker::Result handle(
const Expr *Inner,
const ExplodedNode *InputNode,
2127 const ExplodedNode *LVNode,
2128 TrackingOptions Opts)
override {
2132 if (
const Expr *Receiver =
2134 return getParentTracker().track(Receiver, LVNode, Opts);
2142 using ExpressionHandler::ExpressionHandler;
2144 Tracker::Result handle(
const Expr *Inner,
const ExplodedNode *InputNode,
2145 const ExplodedNode *LVNode,
2146 TrackingOptions Opts)
override {
2148 if (
const auto *Arr = dyn_cast<ArraySubscriptExpr>(Inner))
2149 return getParentTracker().track(
2150 Arr->getIdx(), LVNode,
2151 {Opts.Kind, false});
2160 using ExpressionHandler::ExpressionHandler;
2162 Tracker::Result handle(
const Expr *Inner,
const ExplodedNode *InputNode,
2163 const ExplodedNode *LVNode,
2164 TrackingOptions Opts)
override {
2167 PathSensitiveBugReport &Report = getParentTracker().getReport();
2168 Tracker::Result Result;
2173 SVal LVal = LVNode->getSVal(Inner);
2176 bool LVIsNull = LVState->isNull(LVal).isConstrainedTrue();
2181 if (RR && !LVIsNull)
2182 Result.combineWith(getParentTracker().track(LVal, RR, Opts, SFC));
2188 const MemRegion *R =
2189 (RR && LVIsNull) ? RR : LVNode->getSVal(Inner).getAsRegion();
2194 SVal
V = LVState->getRawSVal(loc::MemRegionVal(R));
2195 Report.addVisitor<NoStoreFuncVisitor>(cast<SubRegion>(R), Opts.Kind);
2199 Result.FoundSomethingToTrack =
true;
2200 Result.WasInterrupted =
true;
2202 MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(
2203 LVNode, R, Opts.EnableNullFPSuppression, Report,
V);
2205 Report.markInteresting(
V, Opts.Kind);
2206 Report.addVisitor<UndefOrNullArgVisitor>(R);
2210 if (
V.getAsLocSymbol(
true))
2211 if (LVState->isNull(
V).isConstrainedTrue())
2212 Report.addVisitor<TrackConstraintBRVisitor>(
V.castAs<DefinedSVal>(),
2216 if (
auto DV =
V.getAs<DefinedSVal>())
2217 if (!DV->isZeroConstant() && Opts.EnableNullFPSuppression)
2224 Report.addVisitor<SuppressInlineDefensiveChecksVisitor>(*DV,
2226 getParentTracker().track(
V, R, Opts, SFC);
2242 using ExpressionHandler::ExpressionHandler;
2244 Tracker::Result handle(
const Expr *E,
const ExplodedNode *InputNode,
2245 const ExplodedNode *ExprNode,
2246 TrackingOptions Opts)
override {
2254 const bool BypassCXXNewExprEval = isa<CXXNewExpr>(E);
2262 if (CEE->getCalleeContext()->getCallSite() == E)
2266 ExprNode = ExprNode->getFirstPred();
2275 if (!BypassCXXNewExprEval)
2278 if (SP->getStmt() == E && CurrentSFC == PredSFC)
2281 CurrentSFC = PredSFC;
2282 }
while (ExprNode->getStackFrame() == CurrentSFC);
2285 while (ExprNode && ExprNode->getLocation().getAs<
PostStmt>())
2286 ExprNode = ExprNode->getFirstPred();
2301 SVal RetVal = ExprNode->getSVal(E);
2304 if (cast<Expr>(E)->isGLValue())
2306 RetVal =
State->getSVal(*LValue);
2311 bool EnableNullFPSuppression =
false;
2312 if (Opts.EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths)
2314 EnableNullFPSuppression =
State->isNull(*RetLoc).isConstrainedTrue();
2316 PathSensitiveBugReport &Report = getParentTracker().getReport();
2317 Report.addVisitor<ReturnVisitor>(&getParentTracker(), CalleeContext,
2318 EnableNullFPSuppression, Options,
2326 using ExpressionHandler::ExpressionHandler;
2328 Tracker::Result handle(
const Expr *Inner,
const ExplodedNode *InputNode,
2329 const ExplodedNode *LVNode,
2330 TrackingOptions Opts)
override {
2333 PathSensitiveBugReport &Report = getParentTracker().getReport();
2334 Tracker::Result Result;
2338 SVal
V = LVState->getSValAsScalarOrLoc(Inner, LVNode->getLocationContext());
2341 if (
auto L =
V.getAs<loc::MemRegionVal>()) {
2346 bool CanDereference =
true;
2347 if (
const auto *SR = L->getRegionAs<SymbolicRegion>()) {
2348 if (SR->getSymbol()->getType()->getPointeeType()->isVoidType())
2349 CanDereference =
false;
2350 }
else if (L->getRegionAs<AllocaRegion>())
2351 CanDereference =
false;
2358 RVal = LVState->getRawSVal(*L, Inner->getType());
2359 else if (CanDereference)
2360 RVal = LVState->getSVal(L->getRegion());
2362 if (CanDereference) {
2363 Report.addVisitor<UndefOrNullArgVisitor>(L->getRegion());
2364 Result.FoundSomethingToTrack =
true;
2366 if (
auto KV = RVal.getAs<KnownSVal>())
2368 getParentTracker().track(*KV, L->getRegion(), Opts, SFC));
2371 const MemRegion *RegionRVal = RVal.getAsRegion();
2372 if (isa_and_nonnull<SymbolicRegion>(RegionRVal)) {
2373 Report.markInteresting(RegionRVal, Opts.Kind);
2374 Report.addVisitor<TrackConstraintBRVisitor>(
2375 loc::MemRegionVal(RegionRVal),
2377 Result.FoundSomethingToTrack =
true;
2389 using ExpressionHandler::ExpressionHandler;
2391 Tracker::Result handle(
const Expr *E,
const ExplodedNode *InputNode,
2392 const ExplodedNode *ExprNode,
2393 TrackingOptions Opts)
override {
2402 SVal
V = RVState->getSValAsScalarOrLoc(E, RVNode->getLocationContext());
2403 const auto *BO = dyn_cast<BinaryOperator>(E);
2405 if (!BO || !BO->isMultiplicativeOp() || !
V.isZeroConstant())
2408 SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext());
2409 SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext());
2412 Tracker::Result CombinedResult;
2413 Tracker &
Parent = getParentTracker();
2415 const auto track = [&CombinedResult, &
Parent, ExprNode, Opts](
Expr *Inner) {
2416 CombinedResult.combineWith(
Parent.track(Inner, ExprNode, Opts));
2419 if (BO->getOpcode() == BO_Mul) {
2420 if (LHSV.isZeroConstant())
2421 track(BO->getLHS());
2422 if (RHSV.isZeroConstant())
2423 track(BO->getRHS());
2425 if (LHSV.isZeroConstant())
2426 track(BO->getLHS());
2429 return CombinedResult;
2435 addLowPriorityHandler<ControlDependencyHandler>();
2436 addLowPriorityHandler<NilReceiverHandler>();
2437 addLowPriorityHandler<ArrayIndexHandler>();
2438 addLowPriorityHandler<InterestingLValueHandler>();
2439 addLowPriorityHandler<InlinedFunctionCallHandler>();
2440 addLowPriorityHandler<DefaultExpressionHandler>();
2441 addLowPriorityHandler<PRValueHandler>();
2443 addHighPriorityHandler<DefaultStoreHandler>();
2456 Result CombinedResult;
2458 for (ExpressionHandlerPtr &Handler : ExpressionHandlers) {
2459 CombinedResult.combineWith(Handler->handle(Inner, N, LVNode, Opts));
2460 if (CombinedResult.WasInterrupted) {
2463 CombinedResult.WasInterrupted =
false;
2468 return CombinedResult;
2471 Tracker::Result
Tracker::track(SVal
V,
const MemRegion *R, TrackingOptions Opts,
2473 if (
auto KV =
V.getAs<KnownSVal>()) {
2483 for (StoreHandlerPtr &Handler : StoreHandlers) {
2498 ->track(E, InputNode, Opts)
2499 .FoundSomethingToTrack;
2504 TrackingOptions Opts,
2515 const auto *ME = dyn_cast<ObjCMessageExpr>(S);
2518 if (
const Expr *Receiver = ME->getInstanceReceiver()) {
2521 if (
state->isNull(
V).isConstrainedTrue())
2534 const Stmt *S =
P->getStmt();
2535 const Expr *Receiver = getNilReceiver(S, N);
2540 llvm::raw_svector_ostream
OS(Buf);
2542 if (
const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
2544 ME->getSelector().print(
OS);
2545 OS <<
"' not called";
2548 OS <<
"No method is called";
2550 OS <<
" because the receiver is nil";
2561 return std::make_shared<PathDiagnosticEventPiece>(L,
OS.str());
2575 auto piece = VisitNodeImpl(N, BRC, BR);
2577 piece->setTag(getTag());
2578 if (
auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
2579 ev->setPrunable(
true,
false);
2589 const std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags =
2595 const CFGBlock *SrcBlock = BE->getSrc();
2603 if (PreviousNodeTag == Tags.first || PreviousNodeTag == Tags.second)
2606 return VisitTerminator(Term, N, SrcBlock, BE->getDst(), BR, BRC);
2613 if (CurrentNodeTag != Tags.first && CurrentNodeTag != Tags.second)
2616 bool TookTrue = CurrentNodeTag == Tags.first;
2617 return VisitTrueTest(cast<Expr>(PS->getStmt()), BRC, BR, N, TookTrue);
2627 const Expr *Cond =
nullptr;
2647 case Stmt::IfStmtClass:
2648 Cond = cast<IfStmt>(Term)->getCond();
2650 case Stmt::ConditionalOperatorClass:
2651 Cond = cast<ConditionalOperator>(Term)->getCond();
2653 case Stmt::BinaryOperatorClass:
2657 const auto *BO = cast<BinaryOperator>(Term);
2658 assert(BO->isLogicalOp() &&
2659 "CFG terminator is not a short-circuit operator!");
2660 Cond = BO->getLHS();
2669 while (
const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
2670 if (!InnerBO->isLogicalOp())
2677 const bool TookTrue = *(srcBlk->
succ_begin()) == dstBlk;
2678 return VisitTrueTest(Cond, BRC, R, N, TookTrue);
2695 CurrentState->getSVal(Cond, LCtx).isUnknownOrUndef();
2699 const Expr *CondTmp = Cond;
2700 bool TookTrueTmp = TookTrue;
2707 case Stmt::BinaryOperatorClass:
2708 if (
auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
2709 BRC, R, N, TookTrueTmp, IsAssuming))
2712 case Stmt::DeclRefExprClass:
2713 if (
auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
2714 BRC, R, N, TookTrueTmp, IsAssuming))
2717 case Stmt::MemberExprClass:
2718 if (
auto P = VisitTrueTest(Cond, cast<MemberExpr>(CondTmp),
2719 BRC, R, N, TookTrueTmp, IsAssuming))
2722 case Stmt::UnaryOperatorClass: {
2723 const auto *UO = cast<UnaryOperator>(CondTmp);
2724 if (UO->getOpcode() == UO_LNot) {
2725 TookTrueTmp = !TookTrueTmp;
2726 CondTmp = UO->getSubExpr();
2746 return std::make_shared<PathDiagnosticEventPiece>(
2747 Loc, TookTrue ? GenericTrueMessage : GenericFalseMessage);
2751 const Expr *ParentEx,
2757 bool IsSameFieldName) {
2758 const Expr *OriginalExpr = Ex;
2779 if (
const auto *DR = dyn_cast<DeclRefExpr>(Ex)) {
2780 const bool quotes = isa<VarDecl>(DR->getDecl());
2785 if (
const MemRegion *R =
state->getLValue(cast<VarDecl>(DR->getDecl()),
2786 LCtx).getAsRegion()) {
2797 Out << DR->getDecl()->getDeclName().getAsString();
2803 if (
const auto *IL = dyn_cast<IntegerLiteral>(Ex)) {
2806 if (IL->getValue() == 0) {
2812 if (IL->getValue() == 0) {
2818 Out << IL->getValue();
2822 if (
const auto *ME = dyn_cast<MemberExpr>(Ex)) {
2823 if (!IsSameFieldName)
2824 Out <<
"field '" << ME->getMemberDecl()->getName() <<
'\'';
2841 bool shouldInvert =
false;
2846 bool IsSameFieldName =
false;
2852 LhsME->getMemberDecl()->getName() == RhsME->getMemberDecl()->getName();
2856 llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
2857 const bool isVarLHS = patternMatch(BExpr->
getLHS(), BExpr, OutLHS, BRC, R,
2858 N, shouldPrune, IsSameFieldName);
2859 const bool isVarRHS = patternMatch(BExpr->
getRHS(), BExpr, OutRHS, BRC, R,
2860 N, shouldPrune, IsSameFieldName);
2862 shouldInvert = !isVarLHS && isVarRHS;
2870 return VisitConditionVariable(LhsString, BExpr->
getLHS(), BRC, R, N,
2876 if (LhsString.empty() || RhsString.empty() ||
2882 llvm::raw_svector_ostream Out(buf);
2883 Out << (IsAssuming ?
"Assuming " :
"")
2884 << (shouldInvert ? RhsString : LhsString) <<
" is ";
2890 case BO_LT: Op = BO_GT;
break;
2891 case BO_GT: Op = BO_LT;
break;
2892 case BO_LE: Op = BO_GE;
break;
2893 case BO_GE: Op = BO_LE;
break;
2898 case BO_EQ: Op = BO_NE;
break;
2899 case BO_NE: Op = BO_EQ;
break;
2900 case BO_LT: Op = BO_GE;
break;
2901 case BO_GT: Op = BO_LE;
break;
2902 case BO_LE: Op = BO_GT;
break;
2903 case BO_GE: Op = BO_LT;
break;
2913 Out <<
"not equal to ";
2920 Out << (shouldInvert ? LhsString : RhsString);
2930 Message[0] = toupper(Message[0]);
2935 if (!shouldInvert) {
2936 if (LhsME && LhsME->getMemberLoc().isValid())
2941 if (RhsME && RhsME->getMemberLoc().isValid())
2947 return std::make_shared<PathDiagnosticPopUpPiece>(
Loc, Message);
2951 auto event = std::make_shared<PathDiagnosticEventPiece>(
Loc, Message);
2953 event->setPrunable(shouldPrune.getValue());
2964 llvm::raw_svector_ostream Out(buf);
2965 Out <<
"Assuming " << LhsString <<
" is ";
2967 if (!printValue(CondVarExpr, Out, N, TookTrue,
true))
2976 auto event = std::make_shared<PathDiagnosticEventPiece>(
Loc, Out.str());
2979 event->setPrunable(
false);
2988 const auto *VD = dyn_cast<VarDecl>(DRE->
getDecl());
2993 llvm::raw_svector_ostream Out(Buf);
2995 Out << (IsAssuming ?
"Assuming '" :
"'") << VD->getDeclName() <<
"' is ";
2997 if (!printValue(DRE, Out, N, TookTrue, IsAssuming))
3008 return std::make_shared<PathDiagnosticPopUpPiece>(
Loc, Out.str());
3012 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3015 event->setPrunable(
false);
3017 return std::move(event);
3022 PathSensitiveBugReport &report,
const ExplodedNode *N,
bool TookTrue,
3025 llvm::raw_svector_ostream Out(Buf);
3027 Out << (IsAssuming ?
"Assuming field '" :
"Field '")
3030 if (!printValue(ME, Out, N, TookTrue, IsAssuming))
3034 PathDiagnosticLocation Loc;
3038 Loc = PathDiagnosticLocation(ME->
getMemberLoc(), BRC.getSourceManager());
3040 Loc = PathDiagnosticLocation(Cond, BRC.getSourceManager(), LCtx);
3042 if (!Loc.isValid() || !Loc.asLocation().isValid())
3050 return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
3052 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3054 event->setPrunable(
false);
3064 Out << (TookTrue ?
"non-null" :
"null");
3069 Out << (TookTrue ?
"non-nil" :
"nil");
3080 if (IsAssuming || !IntValue) {
3082 Out << (TookTrue ?
"true" :
"false");
3084 Out << (TookTrue ?
"not equal to 0" :
"0");
3087 Out << (IntValue.getValue()->getBoolValue() ?
"true" :
"false");
3089 Out << *IntValue.getValue();
3095 constexpr llvm::StringLiteral ConditionBRVisitor::GenericTrueMessage;
3096 constexpr llvm::StringLiteral ConditionBRVisitor::GenericFalseMessage;
3100 return Piece->
getString() == GenericTrueMessage ||
3101 Piece->
getString() == GenericFalseMessage;
3121 if (Options.ShouldSuppressFromCXXStandardLibrary) {
3131 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3133 if (CD->
getName() ==
"list") {
3141 if (
const auto *MD = dyn_cast<CXXConstructorDecl>(D)) {
3143 if (CD->
getName() ==
"__independent_bits_engine") {
3151 const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->
getDecl());
3162 if (CD->
getName() ==
"basic_string") {
3170 if (CD->
getName() ==
"shared_ptr") {
3182 while (
Loc.isMacroID()) {
3183 Loc =
Loc.getSpellingLoc();
3184 if (
SM.getFilename(
Loc).endswith(
"sys/queue.h")) {
3212 for (
const auto ParamDecl : parms) {
3213 const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
3221 assert(ParamDecl &&
"Formal parameter has no decl?");
3259 llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver();
3263 for (
const auto &I : Constraints) {
3265 auto RangeIt = I.second.begin();
3268 RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(),
3270 while ((++RangeIt) != I.second.end()) {
3271 SMTConstraints = RefutationSolver->mkOr(
3273 RangeIt->From(), RangeIt->To(),
3277 RefutationSolver->addConstraint(SMTConstraints);
3285 if (!IsSAT.getValue())
3290 const ExplodedNode *N,
bool OverwriteConstraintsOnExistingSyms) {
3296 for (
auto const &C : NewCs) {
3298 if (!Constraints.contains(Sym)) {
3300 Constraints =
CF.add(Constraints, Sym, C.second);
3301 }
else if (OverwriteConstraintsOnExistingSyms) {
3303 Constraints =
CF.remove(Constraints, Sym);
3304 Constraints =
CF.add(Constraints, Sym, C.second);
3316 llvm::FoldingSetNodeID &
ID)
const {
3318 ID.AddPointer(&Tag);
3325 int NoteTag::Kind = 0;
3329 ID.AddPointer(&Tag);
3343 auto Piece = std::make_shared<PathDiagnosticEventPiece>(
Loc, *Msg);