49 #include "llvm/ADT/ArrayRef.h" 50 #include "llvm/ADT/None.h" 51 #include "llvm/ADT/Optional.h" 52 #include "llvm/ADT/STLExtras.h" 53 #include "llvm/ADT/SmallPtrSet.h" 54 #include "llvm/ADT/SmallString.h" 55 #include "llvm/ADT/SmallVector.h" 56 #include "llvm/ADT/StringExtras.h" 57 #include "llvm/ADT/StringRef.h" 58 #include "llvm/Support/Casting.h" 59 #include "llvm/Support/ErrorHandling.h" 60 #include "llvm/Support/raw_ostream.h" 67 using namespace clang;
74 bool bugreporter::isDeclRefExprToReference(
const Expr *E) {
75 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
76 return DRE->getDecl()->getType()->isReferenceType();
103 const Expr *bugreporter::getDerefExpr(
const Stmt *S) {
104 const auto *E = dyn_cast<
Expr>(S);
109 if (
const auto *CE = dyn_cast<CastExpr>(E)) {
110 if (CE->getCastKind() == CK_LValueToRValue) {
114 E = CE->getSubExpr();
115 }
else if (
const auto *B = dyn_cast<BinaryOperator>(E)) {
124 }
else if (
const auto *U = dyn_cast<UnaryOperator>(E)) {
125 if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf ||
126 (U->isIncrementDecrementOp() && U->getType()->isPointerType())) {
137 else if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
139 }
else if (
const auto *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
140 E = IvarRef->getBase();
141 }
else if (
const auto *AE = dyn_cast<ArraySubscriptExpr>(E)) {
143 }
else if (
const auto *PE = dyn_cast<ParenExpr>(E)) {
144 E = PE->getSubExpr();
145 }
else if (
const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
146 E = EWC->getSubExpr();
156 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E))
157 if (CE->getCastKind() == CK_LValueToRValue)
158 E = CE->getSubExpr();
165 if (
const auto *BE = dyn_cast<BinaryOperator>(S))
172 if (
const auto *RS = dyn_cast<ReturnStmt>(S))
173 return RS->getRetValue();
181 std::shared_ptr<PathDiagnosticPiece>
192 std::shared_ptr<PathDiagnosticPiece> BugReporterVisitor::getDefaultEndPath(
201 auto P = std::make_shared<PathDiagnosticEventPiece>(
251 N->
getSVal(BO->getLHS()).getAsRegion()))
255 SVal ValueAtN = N->
getState()->getSVal(RegionOfInterest);
274 static constexpr
const char *DiagnosticsMsg =
275 "Returning without writing to '";
285 llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifyingRegion;
286 llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifyingCalculated;
290 : RegionOfInterest(R),
294 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
299 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
318 if (
const auto *MC = dyn_cast<ObjCMethodCall>(Call))
319 if (
const auto *IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest))
320 if (potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(),
322 !isRegionOfInterestModifiedInFrame(N))
323 return notModifiedMemberDiagnostics(
324 Ctx, *CallExitLoc, Call, MC->getReceiverSVal().getAsRegion());
326 if (
const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) {
327 const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion();
328 if (RegionOfInterest->isSubRegionOf(ThisR)
329 && !CCall->getDecl()->isImplicit()
330 && !isRegionOfInterestModifiedInFrame(N))
331 return notModifiedMemberDiagnostics(Ctx, *CallExitLoc, Call, ThisR);
335 for (
unsigned I = 0; I < Call->getNumArgs() && I < parameters.size(); ++I) {
337 SVal S = Call->getArgSVal(I);
338 unsigned IndirectionLevel = 1;
341 if (RegionOfInterest->isSubRegionOf(R)
344 if (isRegionOfInterestModifiedInFrame(N))
347 return notModifiedParameterDiagnostics(
348 Ctx, *CallExitLoc, Call, PVD, R, IndirectionLevel);
352 S = State->getSVal(R, PT);
365 bool potentiallyWritesIntoIvar(
const Decl *
Parent,
368 if (!Parent || !Parent->
getBody())
375 return !Matches.empty();
381 bool isRegionOfInterestModifiedInFrame(
const ExplodedNode *N) {
384 if (!FramesModifyingCalculated.count(SCtx))
385 findModifyingFrames(N);
386 return FramesModifyingRegion.count(SCtx);
395 SVal ValueAtReturn = LastReturnState->getSVal(RegionOfInterest);
403 LastReturnState =
State;
404 ValueAtReturn = LastReturnState->getSVal(RegionOfInterest);
407 FramesModifyingCalculated.insert(
413 auto p = FramesModifyingRegion.insert(SCtx);
422 if (CE->getCalleeContext() == OriginalSCtx)
434 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(RD.
getDecl()))
435 return FD->parameters();
437 return Call->parameters();
448 std::shared_ptr<PathDiagnosticPiece> notModifiedMemberDiagnostics(
453 const char *TopRegionName = isa<ObjCMethodCall>(Call) ?
"self" :
"this";
455 llvm::raw_svector_ostream os(sbuf);
456 os << DiagnosticsMsg;
457 bool out = prettyPrintRegionName(TopRegionName,
"->",
true,
458 1, ArgRegion, os, PP);
467 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
474 std::shared_ptr<PathDiagnosticPiece>
480 unsigned IndirectionLevel) {
484 llvm::raw_svector_ostream os(sbuf);
485 os << DiagnosticsMsg;
487 const char *Sep = IsReference && IndirectionLevel == 1 ?
"." :
"->";
488 bool Success = prettyPrintRegionName(
490 Sep, IsReference, IndirectionLevel, ArgRegion, os, PP);
496 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
508 Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(),
SM);
513 bool prettyPrintRegionName(StringRef TopRegionName,
516 int IndirectionLevel,
518 llvm::raw_svector_ostream &os,
522 while (R != ArgRegion) {
523 if (!(isa<FieldRegion>(R) || isa<CXXBaseObjectRegion>(R) ||
524 isa<ObjCIvarRegion>(R)))
526 Subregions.push_back(R);
527 R = cast<SubRegion>(R)->getSuperRegion();
529 bool IndirectReference = !Subregions.empty();
531 if (IndirectReference)
537 bool ShouldSurround = IndirectReference && IndirectionLevel > 0;
541 for (
int i = 0; i < IndirectionLevel; i++)
547 for (
auto I = Subregions.rbegin(), E = Subregions.rend(); I != E; ++I) {
548 if (
const auto *FR = dyn_cast<FieldRegion>(*I)) {
550 FR->getDecl()->getDeclName().print(os, PP);
552 }
else if (
const auto *IR = dyn_cast<ObjCIvarRegion>(*I)) {
554 IR->getDecl()->getDeclName().print(os, PP);
556 }
else if (isa<CXXBaseObjectRegion>(*I)) {
559 llvm_unreachable(
"Previous check has missed an unexpected region");
570 const SVal ValueAtDereference;
574 bool WasModified =
false;
577 MacroNullReturnSuppressionVisitor(
const SubRegion *R,
578 const SVal V) : RegionOfInterest(R),
579 ValueAtDereference(V) {}
581 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
593 if (
auto Loc = matchAssignment(N, BRC)) {
608 static void addMacroVisitorIfNecessary(
610 bool EnableNullFPSuppression,
BugReport &BR,
615 BR.
addVisitor(llvm::make_unique<MacroNullReturnSuppressionVisitor>(
619 void* getTag()
const {
621 return static_cast<void *
>(&Tag);
624 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
625 ID.AddPointer(getTag());
639 if (
const auto *DS = dyn_cast<DeclStmt>(S)) {
640 if (
const auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl()))
641 if (
const Expr *RHS = VD->getInit())
642 if (RegionOfInterest->isSubRegionOf(
643 State->getLValue(VD, LCtx).getAsRegion()))
644 return RHS->getLocStart();
645 }
else if (
const auto *BO = dyn_cast<BinaryOperator>(S)) {
647 const Expr *RHS = BO->getRHS();
648 if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) {
671 bool EnableNullFPSuppression;
672 bool ShouldInvalidate =
true;
676 : StackFrame(Frame), EnableNullFPSuppression(Suppressed) {}
678 static void *getTag() {
680 return static_cast<void *
>(&Tag);
683 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
684 ID.AddPointer(ReturnVisitor::getTag());
685 ID.AddPointer(StackFrame);
686 ID.AddBoolean(EnableNullFPSuppression);
698 bool InEnableNullFPSuppression) {
705 if (CEE->getCalleeContext()->getCallSite() == S)
708 if (SP->getStmt() == S)
734 if (cast<Expr>(S)->isGLValue())
736 RetVal = State->getSVal(*LValue);
741 bool EnableNullFPSuppression =
false;
744 EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
747 BR.
addVisitor(llvm::make_unique<ReturnVisitor>(CalleeContext,
748 EnableNullFPSuppression));
757 std::shared_ptr<PathDiagnosticPiece>
768 const auto *Ret = dyn_cast<
ReturnStmt>(SP->getStmt());
775 SVal V = State->getSVal(Ret, StackFrame);
782 const Expr *RetE = Ret->getRetValue();
783 assert(RetE &&
"Tracking a return value for a void function");
789 SVal RValue = State->getRawSVal(*LValue, RetE->
getType());
804 if (!State->isNull(V).isConstrainedTrue()) {
806 ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
807 EnableNullFPSuppression);
812 bugreporter::trackNullOrUndefValue(N, RetE, BR,
false,
813 EnableNullFPSuppression);
817 llvm::raw_svector_ostream Out(Msg);
824 if (EnableNullFPSuppression && hasCounterSuppression(Options))
825 Mode = MaybeUnsuppress;
828 Out <<
"Returning nil";
830 Out <<
"Returning null pointer";
832 Out <<
"Returning zero";
836 if (
const MemRegion *MR = LValue->getAsRegion()) {
837 if (MR->canPrintPretty()) {
838 Out <<
" (reference to ";
839 MR->printPretty(Out);
845 if (
const auto *DR = dyn_cast<DeclRefExpr>(RetE))
846 if (
const auto *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
847 Out <<
" (loaded from '" << *DD <<
"')";
851 if (!L.isValid() || !L.asLocation().isValid())
854 return std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
857 std::shared_ptr<PathDiagnosticPiece>
862 assert(hasCounterSuppression(Options));
870 if (CE->getCalleeContext() != StackFrame)
883 for (
unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
888 const Expr *ArgE = Call->getArgExpr(I);
893 if (!State->isNull(*ArgV).isConstrainedTrue())
896 if (bugreporter::trackNullOrUndefValue(N, ArgE, BR,
true,
897 EnableNullFPSuppression))
898 ShouldInvalidate =
false;
908 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
914 return visitNodeInitial(N, PrevN, BRC, BR);
915 case MaybeUnsuppress:
916 return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
921 llvm_unreachable(
"Invalid visit mode!");
926 if (EnableNullFPSuppression && ShouldInvalidate)
927 BR.
markInvalid(ReturnVisitor::getTag(), StackFrame);
933 void FindLastStoreBRVisitor::Profile(llvm::FoldingSetNodeID &
ID)
const {
938 ID.AddBoolean(EnableNullFPSuppression);
981 if (
const auto *TR = dyn_cast<TypedValueRegion>(R)) {
982 if (TR->getValueType()->isObjCObjectPointerType()) {
983 os << action <<
"nil";
989 os << action <<
"a null pointer value";
992 os << action << CVal->getValue();
995 if (isa<VarRegion>(R)) {
999 <<
" to a garbage value";
1002 <<
" without an initial value";
1016 const auto *Param = cast<ParmVarDecl>(VR->
getDecl());
1021 if (Param->getType()->isObjCObjectPointerType())
1022 os <<
"nil object reference";
1024 os <<
"null pointer value";
1026 os <<
"uninitialized value";
1028 os <<
"the value " << CI->getValue();
1034 unsigned Idx = Param->getFunctionScopeIndex() + 1;
1035 os <<
" via " << Idx << llvm::getOrdinalSuffix(Idx) <<
" parameter";
1049 if (
const auto *TR = dyn_cast<TypedValueRegion>(R)) {
1050 if (TR->getValueType()->isObjCObjectPointerType()) {
1051 os <<
"nil object reference stored";
1058 os <<
"Null pointer value stored";
1060 os <<
"Storing null pointer value";
1065 os <<
"Uninitialized value stored";
1067 os <<
"Storing uninitialized value";
1071 os <<
"The value " << CV->getValue() <<
" is assigned";
1073 os <<
"Assigning " << CV->getValue();
1077 os <<
"Value assigned";
1079 os <<
"Assigning value";
1088 std::shared_ptr<PathDiagnosticPiece>
1089 FindLastStoreBRVisitor::VisitNode(
const ExplodedNode *Succ,
1096 const Expr *InitE =
nullptr;
1097 bool IsParam =
false;
1100 if (
const auto *VR = dyn_cast<VarRegion>(R)) {
1103 InitE = VR->getDecl()->getInit();
1111 if (FieldReg && FieldReg == R) {
1113 InitE = PIP->getInitializer()->getInit();
1123 if (Succ->
getState()->getSVal(R) != V)
1126 if (Pred->
getState()->getSVal(R) == V) {
1128 if (!PS || PS->getLocationValue() != R)
1138 if (BO->isAssignmentOp())
1139 InitE = BO->getRHS();
1146 if (
const auto *VR = dyn_cast<VarRegion>(R)) {
1147 const auto *Param = cast<ParmVarDecl>(VR->getDecl());
1154 InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1161 if (
const auto *TmpR = dyn_cast<CXXTempObjectRegion>(R))
1162 InitE = TmpR->getExpr();
1176 bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam,
1177 EnableNullFPSuppression);
1180 BR, EnableNullFPSuppression);
1186 llvm::raw_svector_ostream os(sbuf);
1189 const Stmt *S = PS->getStmt();
1190 const char *action =
nullptr;
1191 const auto *DS = dyn_cast<
DeclStmt>(S);
1192 const auto *VR = dyn_cast<
VarRegion>(R);
1197 }
else if (isa<BlockExpr>(S)) {
1198 action = R->canPrintPretty() ?
"captured by block as " :
1199 "Captured by block as ";
1204 if (
const auto *BDR =
1205 dyn_cast_or_null<BlockDataRegion>(V.
getAsRegion())) {
1206 if (
const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
1208 State->getSVal(OriginalR).getAs<
KnownSVal>())
1209 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1210 *KV, OriginalR, EnableNullFPSuppression));
1219 if (
const auto *VR = dyn_cast<VarRegion>(R))
1223 if (os.str().empty())
1239 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
1242 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID)
const {
1244 ID.AddPointer(&tag);
1245 ID.AddBoolean(Assumption);
1251 const char *TrackConstraintBRVisitor::getTag() {
1252 return "TrackConstraintBRVisitor";
1255 bool TrackConstraintBRVisitor::isUnderconstrained(
const ExplodedNode *N)
const {
1257 return N->
getState()->isNull(Constraint).isUnderconstrained();
1258 return (
bool)N->
getState()->assume(Constraint, !Assumption);
1261 std::shared_ptr<PathDiagnosticPiece>
1262 TrackConstraintBRVisitor::VisitNode(
const ExplodedNode *N,
1270 if (!IsTrackingTurnedOn)
1271 if (!isUnderconstrained(N))
1272 IsTrackingTurnedOn =
true;
1273 if (!IsTrackingTurnedOn)
1278 if (isUnderconstrained(PrevN)) {
1284 assert(!isUnderconstrained(N));
1289 llvm::raw_svector_ostream os(sbuf);
1291 if (Constraint.getAs<
Loc>()) {
1292 os <<
"Assuming pointer value is ";
1293 os << (Assumption ?
"non-null" :
"null");
1296 if (os.str().empty())
1306 auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
1307 X->setTag(getTag());
1308 return std::move(
X);
1314 SuppressInlineDefensiveChecksVisitor::
1322 assert(N->
getState()->isNull(V).isConstrainedTrue() &&
1323 "The visitor only tracks the cases where V is constrained to 0");
1326 void SuppressInlineDefensiveChecksVisitor::Profile(
1327 llvm::FoldingSetNodeID &ID)
const {
1333 const char *SuppressInlineDefensiveChecksVisitor::getTag() {
1334 return "IDCVisitor";
1337 std::shared_ptr<PathDiagnosticPiece>
1338 SuppressInlineDefensiveChecksVisitor::VisitNode(
const ExplodedNode *Succ,
1346 if (!IsTrackingTurnedOn)
1347 if (Succ->
getState()->isNull(V).isConstrainedTrue())
1348 IsTrackingTurnedOn =
true;
1349 if (!IsTrackingTurnedOn)
1354 if (!Pred->
getState()->isNull(V).isConstrainedTrue()) {
1357 assert(Succ->
getState()->isNull(V).isConstrainedTrue());
1362 if (CurLC != ReportLC && !CurLC->
isParentOf(ReportLC)) {
1377 const Stmt *CurTerminatorStmt =
nullptr;
1379 CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
1381 const Stmt *CurStmt = SP->getStmt();
1385 CFGStmtMap *Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap();
1391 if (!CurTerminatorStmt)
1411 if (
const auto *DR = dyn_cast<DeclRefExpr>(E)) {
1412 if (
const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1413 if (!VD->getType()->isReferenceType())
1433 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(Ex))
1435 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(Ex))
1437 if (
const auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
1439 if (PropRef && PropRef->isMessagingGetter()) {
1440 const Expr *GetterMessageSend =
1441 POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
1448 if (
const auto *CO = dyn_cast<ConditionalOperator>(Ex)) {
1455 const CFGBlock *srcBlk = BE->getSrc();
1458 bool TookTrueBranch = (*(srcBlk->
succ_begin()) == BE->getDst());
1470 if (
auto *BO = dyn_cast<BinaryOperator>(Ex))
1482 const Expr *Inner) {
1486 if (ps->getStmt() == S || ps->getStmt() == Inner)
1489 if (CEE->getCalleeContext()->getCallSite() == S ||
1490 CEE->getCalleeContext()->getCallSite() == Inner)
1501 const Expr *Inner) {
1504 if (
P->getStmt() == Inner)
1509 assert(N &&
"Unable to find the lvalue node.");
1527 if (
const auto *Op = dyn_cast<UnaryOperator>(Ex))
1528 if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
1529 if (
const Expr *DerefEx = bugreporter::getDerefExpr(Op->getSubExpr()))
1534 bool bugreporter::trackNullOrUndefValue(
const ExplodedNode *N,
1537 bool EnableNullFPSuppression) {
1541 if (
const auto *Ex = dyn_cast<Expr>(S))
1544 const Expr *Inner =
nullptr;
1545 if (
const auto *Ex = dyn_cast<Expr>(S)) {
1547 Ex = Ex->IgnoreParenCasts();
1554 if (IsArg && !Inner) {
1567 if (
const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(S, N))
1568 trackNullOrUndefValue(N, Receiver, report,
false,
1569 EnableNullFPSuppression);
1579 bool LVIsNull = LVState->isNull(LVal).isConstrainedTrue();
1584 if (RR && !LVIsNull) {
1586 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1587 *KV, RR, EnableNullFPSuppression));
1594 const MemRegion *R = (RR && LVIsNull) ? RR :
1602 llvm::make_unique<NoStoreFuncVisitor>(cast<SubRegion>(R)));
1604 MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(
1605 N, R, EnableNullFPSuppression, report, V);
1609 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(R));
1613 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1618 if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() &&
1619 EnableNullFPSuppression) {
1621 llvm::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV,
1627 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1628 *KV, R, EnableNullFPSuppression));
1639 if (
const auto *E = dyn_cast<Expr>(S))
1642 ReturnVisitor::addVisitorIfNecessary(N, S, report, EnableNullFPSuppression);
1649 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
1655 if (
const auto *E = dyn_cast<Expr>(S))
1656 RVal = state->getRawSVal(L.getValue(), E->
getType());
1658 RVal = state->getSVal(L->getRegion());
1661 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1662 *KV, L->getRegion(), EnableNullFPSuppression));
1665 if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
1667 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1674 const Expr *NilReceiverBRVisitor::getNilReceiver(
const Stmt *S,
1679 if (
const Expr *Receiver = ME->getInstanceReceiver()) {
1682 if (state->isNull(V).isConstrainedTrue())
1688 std::shared_ptr<PathDiagnosticPiece>
1696 const Stmt *S = P->getStmt();
1697 const Expr *Receiver = getNilReceiver(S, N);
1702 llvm::raw_svector_ostream OS(Buf);
1704 if (
const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
1706 ME->getSelector().print(OS);
1707 OS <<
"' not called";
1710 OS <<
"No method is called";
1712 OS <<
" because the receiver is nil";
1717 bugreporter::trackNullOrUndefValue(N, Receiver, BR,
false,
1722 return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
1726 void FindLastStoreBRVisitor::registerStatementVarDecls(
BugReport &BR,
1728 bool EnableNullFPSuppression) {
1731 WorkList.push_back(S);
1733 while (!WorkList.empty()) {
1734 const Stmt *Head = WorkList.front();
1735 WorkList.pop_front();
1739 if (
const auto *DR = dyn_cast<DeclRefExpr>(Head)) {
1740 if (
const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1749 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1756 WorkList.push_back(SubStmt);
1766 const char *ConditionBRVisitor::getTag() {
1767 return "ConditionBRVisitor";
1770 std::shared_ptr<PathDiagnosticPiece>
1773 auto piece = VisitNodeImpl(N, Prev, BRC, BR);
1775 piece->setTag(getTag());
1776 if (
auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
1777 ev->setPrunable(
true,
false);
1782 std::shared_ptr<PathDiagnosticPiece>
1783 ConditionBRVisitor::VisitNodeImpl(
const ExplodedNode *N,
1793 if (CurrentState->getGDM().getRoot() ==
1794 PrevState->getGDM().getRoot())
1800 const CFGBlock *srcBlk = BE->getSrc();
1802 return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
1807 const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
1811 if (tag == tags.first)
1812 return VisitTrueTest(cast<Expr>(PS->getStmt()),
true,
1814 if (tag == tags.second)
1815 return VisitTrueTest(cast<Expr>(PS->getStmt()),
false,
1824 std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitTerminator(
1827 const Expr *Cond =
nullptr;
1847 case Stmt::IfStmtClass:
1848 Cond = cast<IfStmt>(Term)->getCond();
1850 case Stmt::ConditionalOperatorClass:
1851 Cond = cast<ConditionalOperator>(Term)->getCond();
1853 case Stmt::BinaryOperatorClass:
1857 const auto *BO = cast<BinaryOperator>(Term);
1858 assert(BO->isLogicalOp() &&
1859 "CFG terminator is not a short-circuit operator!");
1860 Cond = BO->getLHS();
1867 while (
const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
1868 if (!InnerBO->isLogicalOp())
1875 const bool tookTrue = *(srcBlk->
succ_begin()) == dstBlk;
1876 return VisitTrueTest(Cond, tookTrue, BRC, R, N);
1879 std::shared_ptr<PathDiagnosticPiece>
1880 ConditionBRVisitor::VisitTrueTest(
const Expr *Cond,
bool tookTrue,
1885 const Expr *CondTmp = Cond;
1886 bool tookTrueTmp = tookTrue;
1893 case Stmt::BinaryOperatorClass:
1894 if (
auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
1895 tookTrueTmp, BRC, R, N))
1898 case Stmt::DeclRefExprClass:
1899 if (
auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
1900 tookTrueTmp, BRC, R, N))
1903 case Stmt::UnaryOperatorClass: {
1904 const auto *UO = cast<UnaryOperator>(CondTmp);
1905 if (UO->getOpcode() == UO_LNot) {
1906 tookTrueTmp = !tookTrueTmp;
1907 CondTmp = UO->getSubExpr();
1923 return std::make_shared<PathDiagnosticEventPiece>(
1924 Loc, tookTrue ? GenericTrueMessage : GenericFalseMessage);
1927 bool ConditionBRVisitor::patternMatch(
const Expr *Ex,
1928 const Expr *ParentEx,
1934 const Expr *OriginalExpr = Ex;
1942 (isa<GNUNullExpr>(Ex) ||
1943 isa<ObjCBoolLiteralExpr>(Ex) ||
1944 isa<CXXBoolLiteralExpr>(Ex) ||
1945 isa<IntegerLiteral>(Ex) ||
1946 isa<FloatingLiteral>(Ex))) {
1951 bool beginAndEndAreTheSameMacro = StartName.equals(EndName);
1953 bool partOfParentMacro =
false;
1958 partOfParentMacro = PName.equals(StartName);
1961 if (beginAndEndAreTheSameMacro && !partOfParentMacro ) {
1977 if (
const auto *DR = dyn_cast<DeclRefExpr>(Ex)) {
1978 const bool quotes = isa<VarDecl>(DR->getDecl());
1995 Out << DR->getDecl()->getDeclName().getAsString();
2001 if (
const auto *IL = dyn_cast<IntegerLiteral>(Ex)) {
2004 if (IL->getValue() == 0) {
2010 if (IL->getValue() == 0) {
2016 Out << IL->getValue();
2023 std::shared_ptr<PathDiagnosticPiece>
2027 bool shouldInvert =
false;
2032 llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
2033 const bool isVarLHS = patternMatch(BExpr->
getLHS(), BExpr, OutLHS,
2034 BRC, R, N, shouldPrune);
2035 const bool isVarRHS = patternMatch(BExpr->
getRHS(), BExpr, OutRHS,
2036 BRC, R, N, shouldPrune);
2038 shouldInvert = !isVarLHS && isVarRHS;
2046 return VisitConditionVariable(LhsString, BExpr->
getLHS(), tookTrue,
2052 if (LhsString.empty() || RhsString.empty() ||
2058 llvm::raw_svector_ostream Out(buf);
2059 Out <<
"Assuming " << (shouldInvert ? RhsString : LhsString) <<
" is ";
2065 case BO_LT: Op = BO_GT;
break;
2066 case BO_GT: Op = BO_LT;
break;
2067 case BO_LE: Op = BO_GE;
break;
2068 case BO_GE: Op = BO_LE;
break;
2073 case BO_EQ: Op = BO_NE;
break;
2074 case BO_NE: Op = BO_EQ;
break;
2075 case BO_LT: Op = BO_GE;
break;
2076 case BO_GT: Op = BO_LE;
break;
2077 case BO_LE: Op = BO_GT;
break;
2078 case BO_GE: Op = BO_LT;
break;
2088 Out <<
"not equal to ";
2095 Out << (shouldInvert ? LhsString : RhsString);
2098 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
2099 if (shouldPrune.hasValue())
2100 event->setPrunable(shouldPrune.getValue());
2104 std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitConditionVariable(
2105 StringRef LhsString,
const Expr *CondVarExpr,
const bool tookTrue,
2111 llvm::raw_svector_ostream Out(buf);
2112 Out <<
"Assuming " << LhsString <<
" is ";
2117 Out << (tookTrue ?
"not null" :
"null");
2119 Out << (tookTrue ?
"not nil" :
"nil");
2121 Out << (tookTrue ?
"true" :
"false");
2123 Out << (tookTrue ?
"non-zero" :
"zero");
2129 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
2131 if (
const auto *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
2132 if (
const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
2136 event->setPrunable(
false);
2144 std::shared_ptr<PathDiagnosticPiece>
2145 ConditionBRVisitor::VisitTrueTest(
const Expr *Cond,
const DeclRefExpr *DR,
2153 llvm::raw_svector_ostream Out(Buf);
2155 Out <<
"Assuming '" << VD->getDeclName() <<
"' is ";
2160 Out << (tookTrue ?
"non-null" :
"null");
2162 Out << (tookTrue ?
"non-nil" :
"nil");
2164 Out << (tookTrue ?
"not equal to 0" :
"0");
2170 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
2173 if (
const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
2175 event->setPrunable(
false);
2177 SVal V = state->getSVal(R);
2179 event->setPrunable(
false);
2182 return std::move(event);
2185 const char *
const ConditionBRVisitor::GenericTrueMessage =
2186 "Assuming the condition is true";
2187 const char *
const ConditionBRVisitor::GenericFalseMessage =
2188 "Assuming the condition is false";
2190 bool ConditionBRVisitor::isPieceMessageGeneric(
2192 return Piece->
getString() == GenericTrueMessage ||
2193 Piece->
getString() == GenericFalseMessage;
2196 void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor(
2218 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2220 if (CD->
getName() ==
"list") {
2228 if (
const auto *MD = dyn_cast<CXXConstructorDecl>(D)) {
2230 if (CD->
getName() ==
"__independent_bits_engine") {
2249 if (CD->
getName() ==
"basic_string") {
2257 if (CD->
getName() ==
"shared_ptr") {
2271 if (SM.
getFilename(Loc).endswith(
"sys/queue.h")) {
2278 std::shared_ptr<PathDiagnosticPiece>
2279 UndefOrNullArgVisitor::VisitNode(
const ExplodedNode *N,
2296 for (
const auto ParamDecl : parms) {
2297 const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
2301 if ( !ArgReg || !R->isSubRegionOf(ArgReg->
StripCasts()))
2305 assert(ParamDecl &&
"Formal parameter has no decl?");
2320 SVal BoundVal = State->getSVal(R);
2329 std::shared_ptr<PathDiagnosticPiece>
2330 CXXSelfAssignmentBRVisitor::VisitNode(
const ExplodedNode *Succ,
2337 if (!Edge.hasValue())
2340 auto Tag = Edge->
getTag();
2344 if (Tag->getTagDescription() !=
"cplusplus.SelfAssignment")
2351 assert(Met &&
"Not a C++ method.");
2352 assert((Met->isCopyAssignmentOperator() || Met->isMoveAssignmentOperator()) &&
2353 "Not a copy/move assignment operator.");
2355 const auto *LCtx = Edge->getLocationContext();
2358 auto &SVB =
State->getStateManager().getSValBuilder();
2361 State->getSVal(
State->getRegion(Met->getParamDecl(0), LCtx));
2363 State->getSVal(SVB.getCXXThis(Met, LCtx->getStackFrame()));
2367 if (!L.isValid() || !L.asLocation().isValid())
2371 llvm::raw_svector_ostream Out(Buf);
2373 Out <<
"Assuming " << Met->getParamDecl(0)->getName() <<
2374 ((Param == This) ?
" == " :
" != ") <<
"*this";
2376 auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
2377 Piece->
addRange(Met->getSourceRange());
2379 return std::move(Piece);
2382 std::shared_ptr<PathDiagnosticPiece>
2400 return std::make_shared<PathDiagnosticEventPiece>(L,
"Taint originated here");
2403 FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor()
2406 void FalsePositiveRefutationBRVisitor::finalizeVisitor(
2409 VisitNode(EndPathNode,
nullptr, BRC, BR);
2416 for (
const auto &I : Constraints) {
2419 SMTExprRef Constraints = RefutationSolver->fromBoolean(
false);
2420 for (
const auto &
Range : I.second) {
2421 Constraints = RefutationSolver->mkOr(
2426 RefutationSolver->addConstraint(Constraints);
2430 if (RefutationSolver->check().isConstrainedFalse())
2434 std::shared_ptr<PathDiagnosticPiece>
2435 FalsePositiveRefutationBRVisitor::VisitNode(
const ExplodedNode *N,
2445 for (
auto const &C : NewCs) {
2447 if (!Constraints.contains(Sym)) {
2448 Constraints = CF.add(Constraints, Sym, C.second);
2455 void FalsePositiveRefutationBRVisitor::Profile(
2456 llvm::FoldingSetNodeID &ID)
const {
2458 ID.AddPointer(&Tag);
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
const llvm::APSInt & From() const
Defines the clang::ASTContext interface.
This is a discriminated union of FileInfo and ExpansionInfo.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
ASTContext & getASTContext()
static StringRef getMacroName(SourceLocation Loc, BugReporterContext &BRC)
bool isInteresting(SymbolRef sym)
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
succ_iterator succ_begin()
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
AnalyzerOptions & getAnalyzerOptions()
Stmt - This represents one statement.
internal::Matcher< Stmt > StatementMatcher
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool shouldSuppressNullReturnPaths()
Returns whether or not paths that go through null returns should be suppressed.
internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, internal::Matcher< Decl >, void(internal::HasDeclarationSupportedTypes)> hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
C Language Family Type Representation.
Defines the SourceManager interface.
static bool isPointerToConst(const QualType &QT)
Decl - This represents one declaration (or definition), e.g.
Represents a point when we begin processing an inlined call.
StringRef getDescription() const
Manages the lifetime of CallEvent objects.
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher. ...
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded...
A Range represents the closed range [from, to].
std::unique_ptr< SMTSolver > CreateZ3Solver()
Convenience method to create and Z3Solver object.
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
llvm::ImmutableMap< SymbolRef, RangeSet > ConstraintRangeTy
const ProgramStateRef & getState() const
bool shouldAvoidSuppressingNullArgumentPaths()
Returns whether a bug report should not be suppressed if its path includes a call with a null argumen...
Value representing integer constant.
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
unsigned succ_size() const
ASTContext & getContext()
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
Represents a variable declaration or definition.
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator > binaryOperator
Matches binary operator expressions.
const Decl & getCodeDecl() const
static const Expr * peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N)
const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCIvarRefExpr > objcIvarRefExpr
Matches a reference to an ObjCIvar.
Describes how types, statements, expressions, and declarations should be printed. ...
void addRange(SourceRange R)
Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
bool isParentOf(const LocationContext *LC) const
SourceLocation getBegin() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a program point after a store evaluation.
MemRegionManager & getRegionManager()
bool isReferenceType() const
SValBuilder & getSValBuilder()
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
bool isAssignmentOp() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Represents a point when we start the call exit sequence (for inlined call).
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
StringRef getOpcodeStr() const
static bool isInStdNamespace(const Decl *D)
Returns true if the root namespace of the given declaration is the 'std' C++ namespace.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const LocationContext * getLocationContext() const
const clang::PrintingPolicy & getPrintingPolicy() const
static const Expr * peelOfOuterAddrOf(const Expr *Ex)
Performing operator `&' on an lvalue expression is essentially a no-op.
const LocationContext * getParent() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest, const ExplodedNode *N, SVal ValueAfter)
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
static const Expr * peelOffPointerArithmetic(const BinaryOperator *B)
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N)
ExplodedNode * getFirstPred()
bool isScalarType() const
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const MemSpaceRegion * getMemorySpace() const
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
bool shouldSuppressInlinedDefensiveChecks()
Returns whether or not diagnostics containing inlined defensive NULL checks should be suppressed...
const Stmt * getCallSite() const
Represents a single basic block in a source-level CFG.
Represents a point when we finish the call exit sequence (for inlined call).
ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)
const RegionTy * getAs() const
ProgramState - This class encapsulates:
Expr - This represents one expression.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
CFGBlock * getBlock(Stmt *S)
Returns the CFGBlock the specified Stmt* appears in.
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const
Get the lvalue for a base class object reference.
bool inTopFrame() const override
Return true if the current LocationContext has no caller context.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
An expression that sends a message to the given Objective-C object or class.
bool isValid() const =delete
void markInteresting(SymbolRef sym)
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const ExpansionInfo & getExpansion() const
const VarDecl * getDecl() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
virtual bool isBoundable() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isComparisonOp() const
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
const MemRegion * StripCasts(bool StripBaseCasts=true) const
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
CFGTerminator getTerminator()
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Defines the runtime definition of the called function.
QualType getCanonicalType() const
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static const ExplodedNode * findNodeForStatement(const ExplodedNode *N, const Stmt *S, const Expr *Inner)
Walk through nodes until we get one that matches the statement exactly.
Encodes a location in the source.
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
const MemRegion * getAsRegion() const
CallEventManager & getCallEventManager()
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocStart() const LLVM_READONLY
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
Represents a static or instance method of a struct/union/class.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
bool isAnyPointerType() const
bool isObjCObjectPointerType() const
FullSourceLoc asLocation() const
SourceLocation getLocEnd() const LLVM_READONLY
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
const ReturnStmt * getReturnStmt() const
static void showBRDiagnostics(const char *action, llvm::raw_svector_ostream &os, const MemRegion *R, SVal V, const DeclStmt *DS)
Show diagnostics for initializing or declaring a region R with a bad value.
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static bool isFunctionMacroExpansion(SourceLocation Loc, const SourceManager &SM)
ast_type_traits::DynTypedNode Node
Dataflow Directional Tag Classes.
static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &os, const MemRegion *R, SVal V)
Show default diagnostics for storing bad region.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isZeroConstant() const
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const llvm::APSInt & To() const
StmtClass getStmtClass() const
bool isBooleanType() const
const Decl * getSingleDecl() const
const ProgramPointTag * getTag() const
static void showBRParamDiagnostics(llvm::raw_svector_ostream &os, const VarRegion *VR, SVal V)
Display diagnostics for passing bad region as a parameter.
const Decl * getDecl() const
Represents an SVal that is guaranteed to not be UnknownVal.
static const ExplodedNode * findNodeForExpression(const ExplodedNode *N, const Expr *Inner)
Find the ExplodedNode where the lvalue (the value of 'Ex') was computed.
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SubRegion - A region that subsets another larger region.
ProgramStateManager & getStateManager()
const ExplodedNode * getErrorNode() const
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
const LocationContext * getLocationContext() const
bool shouldSuppressFromCXXStandardLibrary()
Returns whether or not diagnostics reported within the C++ standard library should be suppressed...
static bool isAdditiveOp(Opcode Opc)
const StackFrameContext * getStackFrame() const
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
SourceManager & getSourceManager()
MemRegionManager * getMemRegionManager() const override
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Defines the clang::SourceLocation class and associated facilities.
Represents a C++ struct/union/class.
ObjCIvarDecl - Represents an ObjC instance variable.
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
Create a location corresponding to the next valid ExplodedNode as end of path location.
void markInvalid(const void *Tag, const void *Data)
Marks the current report as invalid, meaning that it is probably a false positive and should not be r...
static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR)
Returns true if N represents the DeclStmt declaring and initializing VR.
FullSourceLoc getSpellingLoc() const
A SourceLocation and its associated SourceManager.
std::shared_ptr< SMTExpr > SMTExprRef
Shared pointer for SMTExprs, used by SMTSolver API.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
std::string getQualifiedNameAsString() const
A reference to a declared variable, function, enum, etc.
bool isFunctionMacroExpansion() const
bool isPointerType() const
static llvm::ImmutableListFactory< const FieldRegion * > Factory
const StackFrameContext * getStackFrame() const
A trivial tuple used to represent a source range.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
This class provides an interface through which checkers can create individual bug reports...
StringRef getString() const
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
const LangOptions & getLangOpts() const
This class handles loading and caching of source files into memory.
SourceManager & getSourceManager()
bool isUnknownOrUndef() const
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.