25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/Support/raw_ostream.h" 29 using namespace clang;
32 using llvm::FoldingSetNodeID;
39 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
40 return DRE->getDecl()->getType()->isReferenceType();
63 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
64 if (CE->getCastKind() == CK_LValueToRValue) {
69 }
else if (
const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
71 if (B->getType()->isPointerType()) {
72 if (B->getLHS()->getType()->isPointerType()) {
74 }
else if (B->getRHS()->getType()->isPointerType()) {
84 }
else if (
const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
85 if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf ||
86 (U->isIncrementDecrementOp() && U->getType()->isPointerType())) {
97 else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
99 }
else if (
const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
100 E = IvarRef->getBase();
103 }
else if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
104 E = PE->getSubExpr();
115 if (CE->getCastKind() == CK_LValueToRValue)
116 E = CE->getSubExpr();
130 if (
const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
131 return RS->getRetValue();
139 std::unique_ptr<PathDiagnosticPiece>
154 auto P = llvm::make_unique<PathDiagnosticEventPiece>(
179 bool EnableNullFPSuppression;
183 : StackFrame(Frame), Mode(Initial), EnableNullFPSuppression(Suppressed) {}
185 static void *getTag() {
187 return static_cast<void *
>(&Tag);
190 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
191 ID.AddPointer(ReturnVisitor::getTag());
192 ID.AddPointer(StackFrame);
193 ID.AddBoolean(EnableNullFPSuppression);
205 bool InEnableNullFPSuppression) {
212 if (CEE->getCalleeContext()->getCallSite() == S)
215 if (SP->getStmt() == S)
241 if (cast<Expr>(S)->isGLValue())
243 RetVal = State->getSVal(*LValue);
246 SubEngine *Eng = State->getStateManager().getOwningEngine();
247 assert(Eng &&
"Cannot file a bug report without an owning engine");
250 bool EnableNullFPSuppression =
false;
253 EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
256 BR.
addVisitor(llvm::make_unique<ReturnVisitor>(CalleeContext,
257 EnableNullFPSuppression));
266 std::shared_ptr<PathDiagnosticPiece>
284 SVal V = State->getSVal(Ret, StackFrame);
292 assert(RetE &&
"Tracking a return value for a void function");
298 SVal RValue = State->getRawSVal(*LValue, RetE->
getType());
313 if (!State->isNull(V).isConstrainedTrue()) {
315 ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
316 EnableNullFPSuppression);
322 EnableNullFPSuppression);
326 llvm::raw_svector_ostream Out(Msg);
334 if (EnableNullFPSuppression && hasCounterSuppression(Options))
335 Mode = MaybeUnsuppress;
338 Out <<
"Returning nil";
340 Out <<
"Returning null pointer";
342 Out <<
"Returning zero";
346 if (
const MemRegion *MR = LValue->getAsRegion()) {
347 if (MR->canPrintPretty()) {
348 Out <<
" (reference to ";
349 MR->printPretty(Out);
355 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
356 if (
const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
357 Out <<
" (loaded from '" << *DD <<
"')";
361 if (!L.isValid() || !L.asLocation().isValid())
364 return std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
367 std::shared_ptr<PathDiagnosticPiece>
373 assert(hasCounterSuppression(Options));
381 if (CE->getCalleeContext() != StackFrame)
394 for (
unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
399 const Expr *ArgE = Call->getArgExpr(I);
404 if (!State->isNull(*ArgV).isConstrainedTrue())
408 EnableNullFPSuppression))
425 return visitNodeInitial(N, PrevN, BRC, BR);
426 case MaybeUnsuppress:
427 return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
432 llvm_unreachable(
"Invalid visit mode!");
438 if (EnableNullFPSuppression)
439 BR.
markInvalid(ReturnVisitor::getTag(), StackFrame);
451 ID.AddBoolean(EnableNullFPSuppression);
483 std::shared_ptr<PathDiagnosticPiece>
492 const Expr *InitE =
nullptr;
493 bool IsParam =
false;
496 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
499 InitE = VR->getDecl()->getInit();
507 if (FieldReg && FieldReg == R) {
509 InitE = PIP->getInitializer()->getInit();
519 if (Succ->
getState()->getSVal(R) != V)
522 if (Pred->
getState()->getSVal(R) == V) {
524 if (!PS || PS->getLocationValue() != R)
534 if (BO->isAssignmentOp())
535 InitE = BO->getRHS();
542 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
543 const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
558 InitE = TmpR->getExpr();
573 EnableNullFPSuppression);
576 BR, EnableNullFPSuppression);
582 llvm::raw_svector_ostream os(sbuf);
585 const Stmt *S = PS->getStmt();
586 const char *action =
nullptr;
593 }
else if (isa<BlockExpr>(S)) {
594 action = R->canPrintPretty() ?
"captured by block as " :
595 "Captured by block as ";
599 SVal V = State->getSVal(S, PS->getLocationContext());
601 dyn_cast_or_null<BlockDataRegion>(V.
getAsRegion())) {
602 if (
const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
604 State->getSVal(OriginalR).getAs<
KnownSVal>())
605 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
606 *KV, OriginalR, EnableNullFPSuppression));
613 if (R->canPrintPretty()) {
620 if (R->isBoundable()) {
622 if (TR->getValueType()->isObjCObjectPointerType()) {
623 os << action <<
"nil";
630 os << action <<
"a null pointer value";
633 os << action << CVal->getValue();
637 if (isa<VarRegion>(R)) {
640 os << (R->canPrintPretty() ?
"initialized" :
"Initializing")
641 <<
" to a garbage value";
643 os << (R->canPrintPretty() ?
"declared" :
"Declaring")
644 <<
" without an initial value";
649 os << (R->canPrintPretty() ?
"initialized" :
"Initialized")
655 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
656 const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
662 os <<
"nil object reference";
664 os <<
"null pointer value";
665 }
else if (V.isUndef()) {
666 os <<
"uninitialized value";
669 os <<
"the value " << CI->getValue();
676 os <<
" via " << Idx << llvm::getOrdinalSuffix(Idx) <<
" parameter";
677 if (R->canPrintPretty()) {
684 if (os.str().empty()) {
687 if (R->isBoundable()) {
689 if (TR->getValueType()->isObjCObjectPointerType()) {
690 os <<
"nil object reference stored";
696 if (R->canPrintPretty())
697 os <<
"Null pointer value stored";
699 os <<
"Storing null pointer value";
702 }
else if (V.isUndef()) {
703 if (R->canPrintPretty())
704 os <<
"Uninitialized value stored";
706 os <<
"Storing uninitialized value";
710 if (R->canPrintPretty())
711 os <<
"The value " << CV->getValue() <<
" is assigned";
713 os <<
"Assigning " << CV->getValue();
716 if (R->canPrintPretty())
717 os <<
"Value assigned";
719 os <<
"Assigning value";
722 if (R->canPrintPretty()) {
741 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
747 ID.AddBoolean(Assumption);
754 return "TrackConstraintBRVisitor";
757 bool TrackConstraintBRVisitor::isUnderconstrained(
const ExplodedNode *N)
const {
759 return N->
getState()->isNull(Constraint).isUnderconstrained();
760 return (
bool)N->
getState()->assume(Constraint, !Assumption);
763 std::shared_ptr<PathDiagnosticPiece>
772 if (!IsTrackingTurnedOn)
773 if (!isUnderconstrained(N))
774 IsTrackingTurnedOn =
true;
775 if (!IsTrackingTurnedOn)
780 if (isUnderconstrained(PrevN)) {
787 assert(!isUnderconstrained(N));
792 llvm::raw_svector_ostream os(sbuf);
794 if (Constraint.getAs<
Loc>()) {
795 os <<
"Assuming pointer value is ";
796 os << (Assumption ?
"non-null" :
"null");
799 if (os.str().empty())
809 auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
819 : V(Value), IsSatisfied(
false), IsTrackingTurnedOn(
false) {
823 assert(Eng &&
"Cannot file a bug report without an owning engine");
828 assert(N->
getState()->isNull(V).isConstrainedTrue() &&
829 "The visitor only tracks the cases where V is constrained to 0");
842 std::shared_ptr<PathDiagnosticPiece>
851 if (!IsTrackingTurnedOn)
852 if (Succ->
getState()->isNull(V).isConstrainedTrue())
853 IsTrackingTurnedOn =
true;
854 if (!IsTrackingTurnedOn)
859 if (!Pred->
getState()->isNull(V).isConstrainedTrue()) {
862 assert(Succ->
getState()->isNull(V).isConstrainedTrue());
867 if (CurLC != ReportLC && !CurLC->
isParentOf(ReportLC)) {
886 const Stmt *CurTerminatorStmt =
nullptr;
888 CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
890 const Stmt *CurStmt = SP->getStmt();
894 CFGStmtMap *Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap();
900 if (!CurTerminatorStmt)
920 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
921 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
922 if (!VD->getType()->isReferenceType())
946 if (
auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
948 if (PropRef && PropRef->isMessagingGetter()) {
949 const Expr *GetterMessageSend =
950 POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
964 const CFGBlock *srcBlk = BE->getSrc();
967 bool TookTrueBranch = (*(srcBlk->
succ_begin()) == BE->getDst());
984 bool EnableNullFPSuppression) {
988 if (
const Expr *Ex = dyn_cast<Expr>(S))
991 const Expr *Inner =
nullptr;
992 if (
const Expr *Ex = dyn_cast<Expr>(S)) {
1006 if (
const auto *Op = dyn_cast<UnaryOperator>(Ex))
1007 if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
1015 if (IsArg && !Inner) {
1024 if (ps->getStmt() == S || ps->getStmt() == Inner)
1027 if (CEE->getCalleeContext()->getCallSite() == S ||
1028 CEE->getCalleeContext()->getCallSite() == Inner)
1057 if (
P->getStmt() == Inner)
1062 assert(LVNode &&
"Unable to find the lvalue node.");
1066 if (LVState->isNull(LVal).isConstrainedTrue()) {
1081 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1082 *KV, RR, EnableNullFPSuppression));
1092 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(R));
1096 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1101 if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() &&
1102 EnableNullFPSuppression) {
1104 llvm::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV,
1110 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1111 *KV, R, EnableNullFPSuppression));
1122 if (
const Expr *E = dyn_cast<Expr>(S))
1123 S = E->IgnoreParenCasts();
1125 ReturnVisitor::addVisitorIfNecessary(N, S, report, EnableNullFPSuppression);
1136 if (
const Expr *E = dyn_cast<Expr>(S))
1137 RVal = state->getRawSVal(L.getValue(), E->getType());
1139 RVal = state->getSVal(L->getRegion());
1141 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
1143 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1144 *KV, L->getRegion(), EnableNullFPSuppression));
1147 if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
1149 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1165 if (state->isNull(V).isConstrainedTrue())
1171 std::shared_ptr<PathDiagnosticPiece>
1179 const Stmt *S = P->getStmt();
1180 const Expr *Receiver = getNilReceiver(S, N);
1185 llvm::raw_svector_ostream OS(Buf);
1189 ME->getSelector().print(OS);
1190 OS <<
"' not called";
1193 OS <<
"No method is called";
1195 OS <<
" because the receiver is nil";
1205 return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
1211 bool EnableNullFPSuppression) {
1214 WorkList.push_back(S);
1216 while (!WorkList.empty()) {
1217 const Stmt *Head = WorkList.front();
1218 WorkList.pop_front();
1223 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
1224 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1233 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1240 WorkList.push_back(SubStmt);
1251 return "ConditionBRVisitor";
1254 std::shared_ptr<PathDiagnosticPiece>
1257 auto piece = VisitNodeImpl(N, Prev, BRC, BR);
1260 if (
auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
1261 ev->setPrunable(
true,
false);
1266 std::shared_ptr<PathDiagnosticPiece>
1278 if (CurrentState->getGDM().getRoot() ==
1279 PrevState->getGDM().getRoot())
1285 const CFGBlock *srcBlk = BE->getSrc();
1287 return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
1294 const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
1296 getEngine().geteagerlyAssumeBinOpBifurcationTags();
1299 if (tag == tags.first)
1300 return VisitTrueTest(cast<Expr>(PS->getStmt()),
true,
1302 if (tag == tags.second)
1303 return VisitTrueTest(cast<Expr>(PS->getStmt()),
false,
1315 const Expr *Cond =
nullptr;
1335 case Stmt::IfStmtClass:
1336 Cond = cast<IfStmt>(Term)->getCond();
1338 case Stmt::ConditionalOperatorClass:
1339 Cond = cast<ConditionalOperator>(Term)->getCond();
1341 case Stmt::BinaryOperatorClass:
1345 const auto *BO = cast<BinaryOperator>(Term);
1346 assert(BO->isLogicalOp() &&
1347 "CFG terminator is not a short-circuit operator!");
1348 Cond = BO->getLHS();
1355 while (
const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
1356 if (!InnerBO->isLogicalOp())
1363 const bool tookTrue = *(srcBlk->
succ_begin()) == dstBlk;
1364 return VisitTrueTest(Cond, tookTrue, BRC, R, N);
1367 std::shared_ptr<PathDiagnosticPiece>
1373 const Expr *CondTmp = Cond;
1374 bool tookTrueTmp = tookTrue;
1381 case Stmt::BinaryOperatorClass:
1382 if (
auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
1383 tookTrueTmp, BRC, R, N))
1386 case Stmt::DeclRefExprClass:
1387 if (
auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
1388 tookTrueTmp, BRC, R, N))
1391 case Stmt::UnaryOperatorClass: {
1394 tookTrueTmp = !tookTrueTmp;
1408 if (!
Loc.isValid() || !
Loc.asLocation().isValid())
1411 return std::make_shared<PathDiagnosticEventPiece>(
1412 Loc, tookTrue ? GenericTrueMessage : GenericFalseMessage);
1416 const Expr *ParentEx,
1422 const Expr *OriginalExpr = Ex;
1430 (isa<GNUNullExpr>(Ex) ||
1431 isa<ObjCBoolLiteralExpr>(Ex) ||
1432 isa<CXXBoolLiteralExpr>(Ex) ||
1433 isa<IntegerLiteral>(Ex) ||
1434 isa<FloatingLiteral>(Ex))) {
1440 bool beginAndEndAreTheSameMacro = StartName.equals(EndName);
1442 bool partOfParentMacro =
false;
1447 partOfParentMacro = PName.equals(StartName);
1450 if (beginAndEndAreTheSameMacro && !partOfParentMacro ) {
1466 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
1467 const bool quotes = isa<VarDecl>(DR->getDecl());
1484 Out << DR->getDecl()->getDeclName().getAsString();
1493 if (IL->getValue() == 0) {
1499 if (IL->getValue() == 0) {
1505 Out << IL->getValue();
1512 std::shared_ptr<PathDiagnosticPiece>
1517 bool shouldInvert =
false;
1522 llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
1523 const bool isVarLHS = patternMatch(BExpr->
getLHS(), BExpr, OutLHS,
1524 BRC, R, N, shouldPrune);
1525 const bool isVarRHS = patternMatch(BExpr->
getRHS(), BExpr, OutRHS,
1526 BRC, R, N, shouldPrune);
1528 shouldInvert = !isVarLHS && isVarRHS;
1536 return VisitConditionVariable(LhsString, BExpr->
getLHS(), tookTrue,
1542 if (LhsString.empty() || RhsString.empty() ||
1548 llvm::raw_svector_ostream Out(buf);
1549 Out <<
"Assuming " << (shouldInvert ? RhsString : LhsString) <<
" is ";
1555 case BO_LT: Op = BO_GT;
break;
1556 case BO_GT: Op = BO_LT;
break;
1557 case BO_LE: Op = BO_GE;
break;
1558 case BO_GE: Op = BO_LE;
break;
1563 case BO_EQ: Op = BO_NE;
break;
1564 case BO_NE: Op = BO_EQ;
break;
1565 case BO_LT: Op = BO_GE;
break;
1566 case BO_GT: Op = BO_LE;
break;
1567 case BO_LE: Op = BO_GT;
break;
1568 case BO_GE: Op = BO_LT;
break;
1578 Out <<
"not equal to ";
1585 Out << (shouldInvert ? LhsString : RhsString);
1588 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1589 if (shouldPrune.hasValue())
1590 event->setPrunable(shouldPrune.getValue());
1595 StringRef LhsString,
const Expr *CondVarExpr,
const bool tookTrue,
1601 llvm::raw_svector_ostream Out(buf);
1602 Out <<
"Assuming " << LhsString <<
" is ";
1607 Out << (tookTrue ?
"not null" :
"null");
1609 Out << (tookTrue ?
"not nil" :
"nil");
1611 Out << (tookTrue ?
"true" :
"false");
1613 Out << (tookTrue ?
"non-zero" :
"zero");
1619 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1621 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1622 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1626 event->setPrunable(
false);
1634 std::shared_ptr<PathDiagnosticPiece>
1644 llvm::raw_svector_ostream Out(Buf);
1646 Out <<
"Assuming '" << VD->
getDeclName() <<
"' is ";
1651 Out << (tookTrue ?
"non-null" :
"null");
1653 Out << (tookTrue ?
"non-nil" :
"nil");
1655 Out << (tookTrue ?
"not equal to 0" :
"0");
1661 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1664 if (
const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1666 event->setPrunable(
false);
1668 SVal V = state->getSVal(R);
1670 event->setPrunable(
false);
1673 return std::move(event);
1676 const char *
const ConditionBRVisitor::GenericTrueMessage =
1677 "Assuming the condition is true";
1678 const char *
const ConditionBRVisitor::GenericFalseMessage =
1679 "Assuming the condition is false";
1683 return Piece->
getString() == GenericTrueMessage ||
1684 Piece->
getString() == GenericFalseMessage;
1687 std::unique_ptr<PathDiagnosticPiece>
1715 if (CD->
getName() ==
"list") {
1725 if (CD->
getName() ==
"__independent_bits_engine") {
1744 if (CD->
getName() ==
"basic_string") {
1752 if (CD->
getName() ==
"shared_ptr") {
1766 if (SM.
getFilename(Loc).endswith(
"sys/queue.h")) {
1775 std::shared_ptr<PathDiagnosticPiece>
1795 I != E; ++I, ++Idx) {
1796 const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1804 assert(ParamDecl &&
"Formal parameter has no decl?");
1819 SVal BoundVal = State->getSVal(R);
1828 std::shared_ptr<PathDiagnosticPiece>
1836 if (!Edge.hasValue())
1839 auto Tag = Edge->
getTag();
1843 if (Tag->getTagDescription() !=
"cplusplus.SelfAssignment")
1850 assert(Met &&
"Not a C++ method.");
1851 assert((Met->isCopyAssignmentOperator() || Met->isMoveAssignmentOperator()) &&
1852 "Not a copy/move assignment operator.");
1854 const auto *LCtx = Edge->getLocationContext();
1857 auto &SVB =
State->getStateManager().getSValBuilder();
1860 State->getSVal(
State->getRegion(Met->getParamDecl(0), LCtx));
1862 State->getSVal(SVB.getCXXThis(Met, LCtx->getCurrentStackFrame()));
1866 if (!L.isValid() || !L.asLocation().isValid())
1870 llvm::raw_svector_ostream Out(Buf);
1872 Out <<
"Assuming " << Met->getParamDecl(0)->getName() <<
1873 ((Param == This) ?
" == " :
" != ") <<
"*this";
1875 auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
1876 Piece->addRange(Met->getSourceRange());
1878 return std::move(Piece);
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
TypedValueRegion - An abstract class representing regions having a typed value.
const Expr * getDerefExpr(const Stmt *S)
Given that expression S represents a pointer that would be dereferenced, try to find a sub-expression...
This is a discriminated union of FileInfo and ExpansionInfo.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
ASTContext & getASTContext()
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
bool isInteresting(SymbolRef sym)
succ_iterator succ_begin()
Stmt - This represents one statement.
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.
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.
virtual void Profile(llvm::FoldingSetNodeID &ID) const =0
ParenExpr - This represents a parethesized expression, e.g.
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded...
Loc getLValue(const VarDecl *D, const LocationContext *LC) const
Get the lvalue for a variable reference.
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
std::shared_ptr< PathDiagnosticPiece > VisitNodeImpl(const ExplodedNode *N, const ExplodedNode *Prev, BugReporterContext &BRC, BugReport &BR)
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...
const Stmt * GetDenomExpr(const ExplodedNode *N)
Represents a C++ constructor within a class.
Value representing integer constant.
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
unsigned succ_size() const
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
VarDecl - An instance of this class is created to represent 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 Decl & getCodeDecl() const
static const Expr * peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N)
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
ParmVarDecl - Represents a parameter to a function.
bool isParentOf(const LocationContext *LC) const
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
void Profile(llvm::FoldingSetNodeID &ID) const override
std::shared_ptr< PathDiagnosticPiece > VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
Represents a program point after a store evaluation.
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
MemRegionManager & getRegionManager()
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
const Expr * getRetValue() const
bool isReferenceType() const
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.
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
StringRef getOpcodeStr() const
std::unique_ptr< PathDiagnosticPiece > getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR) override
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
virtual std::unique_ptr< PathDiagnosticPiece > getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR)
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
BlockDataRegion - A region that represents a block instance.
static bool isInStdNamespace(const Decl *D)
Returns true if the root namespace of the given declaration is the 'std' C++ namespace.
const StackFrameContext * getCurrentStackFrame() const
const LocationContext * getLocationContext() const
std::shared_ptr< PathDiagnosticPiece > VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, const bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
const LocationContext * getParent() const
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
static void registerStatementVarDecls(BugReport &BR, const Stmt *S, bool EnableNullFPSuppression)
Creates a visitor for every VarDecl inside a Stmt and registers it with the BugReport.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N)
ExplodedNode * getFirstPred()
bool isScalarType() const
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given 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.
ConditionalOperator - The ?: ternary operator.
bool shouldSuppressInlinedDefensiveChecks()
Returns whether or not diagnostics containing inlined defensive NULL checks should be suppressed...
const Stmt * getCallSite() const
Represents a ValueDecl that came out of a declarator.
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
SourceLocation getLocEnd() const LLVM_READONLY
CFGBlock - Represents a single basic block in a source-level CFG.
static const char * getTag()
Return the tag associated with this visitor.
Represents a point when we finish the call exit sequence (for inlined call).
ProgramState - This class encapsulates:
Expr - This represents one expression.
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
const FunctionProtoType * T
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece)
CFGBlock * getBlock(Stmt *S)
Returns the CFGBlock the specified Stmt* appears in.
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
static const Expr * getNilReceiver(const Stmt *S, const ExplodedNode *N)
If the statement is a message send expression with nil receiver, returns the receiver expression...
bool patternMatch(const Expr *Ex, const Expr *ParentEx, raw_ostream &Out, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N, Optional< bool > &prunable)
void Profile(llvm::FoldingSetNodeID &ID) const override
SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N)
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
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.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
void markInteresting(SymbolRef sym)
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *N, const ExplodedNode *Prev, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
const ExpansionInfo & getExpansion() const
const StackFrameContext * getStackFrame() 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...
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isComparisonOp() const
std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
const MemRegion * StripCasts(bool StripBaseCasts=true) const
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
CFGTerminator getTerminator()
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
static std::unique_ptr< PathDiagnosticPiece > getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR)
Generates the default final diagnostic piece.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Encodes a location in the source.
std::shared_ptr< PathDiagnosticPiece > VisitTerminator(const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R, BugReporterContext &BRC)
Expr * getSubExpr() const
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...
AnalysisManager & getAnalysisManager() override
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
void Profile(llvm::FoldingSetNodeID &ID) const override
const MemRegion * getAsRegion() const
CallEventManager & getCallEventManager()
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
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
AnalyzerOptions & options
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
ast_type_traits::DynTypedNode Node
virtual std::shared_ptr< PathDiagnosticPiece > VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred, BugReporterContext &BRC, BugReport &BR)=0
Return a diagnostic piece which should be associated with the given node.
bool isDeclRefExprToReference(const Expr *E)
Dataflow Directional Tag Classes.
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...
static const char * getTag()
Return the tag associated with this visitor.
const Expr * getInit() const
StmtClass getStmtClass() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
bool isBooleanType() const
GRBugReporter & getBugReporter()
const Stmt * GetRetValExpr(const ExplodedNode *N)
const Decl * getSingleDecl() const
const ProgramPointTag * getTag() const
const Decl * getDecl() const
Represents an SVal that is guaranteed to not be UnknownVal.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
ProgramStateManager & getStateManager()
const ExplodedNode * getErrorNode() const
bool isStaticLocal() const
isStaticLocal - 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...
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Represents a C++ struct/union/class.
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
Attempts to add visitors to trace a null or undefined value back to its point of origin, whether it is a symbol constrained to null or an explicit assignment.
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
Create a location corresponding to the next valid ExplodedNode as end of path location.
void removeInvalidation(const void *Tag, const void *Data)
Reverses the effects of a previous invalidation.
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.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
A reference to a declared variable, function, enum, etc.
bool isFunctionMacroExpansion() const
bool isPointerType() 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
SourceLocation getLocStart() const LLVM_READONLY
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.
virtual AnalysisManager & getAnalysisManager()=0
ExprEngine & getEngine()
getEngine - Return the analysis engine used to analyze a given function or method.
static const char * getTag()
Return the tag associated with this visitor.