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();
55 assert(B->isAssignmentOp());
59 else if (
const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
60 if (U->getOpcode() == UO_Deref)
63 else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
64 if (ME->isImplicitAccess()) {
74 else if (
const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
80 else if (isa<DeclRefExpr>(E)) {
98 if (
const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
99 return RS->getRetValue();
107 std::unique_ptr<PathDiagnosticPiece>
122 auto P = llvm::make_unique<PathDiagnosticEventPiece>(
147 bool EnableNullFPSuppression;
151 : StackFrame(Frame), Mode(Initial), EnableNullFPSuppression(Suppressed) {}
153 static void *getTag() {
155 return static_cast<void *
>(&Tag);
158 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
159 ID.AddPointer(ReturnVisitor::getTag());
160 ID.AddPointer(StackFrame);
161 ID.AddBoolean(EnableNullFPSuppression);
173 bool InEnableNullFPSuppression) {
180 if (CEE->getCalleeContext()->getCallSite() ==
S)
183 if (SP->getStmt() ==
S)
209 if (cast<Expr>(S)->isGLValue())
211 RetVal = State->getSVal(*LValue);
214 SubEngine *Eng = State->getStateManager().getOwningEngine();
215 assert(Eng &&
"Cannot file a bug report without an owning engine");
218 bool EnableNullFPSuppression =
false;
221 EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
224 BR.
addVisitor(llvm::make_unique<ReturnVisitor>(CalleeContext,
225 EnableNullFPSuppression));
234 std::shared_ptr<PathDiagnosticPiece>
252 SVal V = State->getSVal(Ret, StackFrame);
260 assert(RetE &&
"Tracking a return value for a void function");
266 SVal RValue = State->getRawSVal(*LValue, RetE->
getType());
281 if (!State->isNull(V).isConstrainedTrue()) {
283 ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
284 EnableNullFPSuppression);
290 EnableNullFPSuppression);
294 llvm::raw_svector_ostream Out(Msg);
302 if (EnableNullFPSuppression && hasCounterSuppression(Options))
303 Mode = MaybeUnsuppress;
306 Out <<
"Returning nil";
308 Out <<
"Returning null pointer";
310 Out <<
"Returning zero";
314 if (
const MemRegion *MR = LValue->getAsRegion()) {
315 if (MR->canPrintPretty()) {
316 Out <<
" (reference to ";
317 MR->printPretty(Out);
323 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
324 if (
const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
325 Out <<
" (loaded from '" << *DD <<
"')";
329 if (!L.isValid() || !L.asLocation().isValid())
332 return std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
335 std::shared_ptr<PathDiagnosticPiece>
341 assert(hasCounterSuppression(Options));
349 if (CE->getCalleeContext() != StackFrame)
362 for (
unsigned I = 0,
E = Call->getNumArgs();
I !=
E; ++
I) {
367 const Expr *ArgE = Call->getArgExpr(
I);
372 if (!State->isNull(*ArgV).isConstrainedTrue())
376 EnableNullFPSuppression))
387 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *N,
393 return visitNodeInitial(N, PrevN, BRC, BR);
394 case MaybeUnsuppress:
395 return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
400 llvm_unreachable(
"Invalid visit mode!");
406 if (EnableNullFPSuppression)
407 BR.
markInvalid(ReturnVisitor::getTag(), StackFrame);
419 ID.AddBoolean(EnableNullFPSuppression);
451 std::shared_ptr<PathDiagnosticPiece>
460 const Expr *InitE =
nullptr;
461 bool IsParam =
false;
464 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
467 InitE = VR->getDecl()->getInit();
475 if (FieldReg && FieldReg == R) {
477 InitE = PIP->getInitializer()->getInit();
487 if (Succ->
getState()->getSVal(R) != V)
490 if (Pred->
getState()->getSVal(R) == V) {
492 if (!PS || PS->getLocationValue() != R)
502 if (BO->isAssignmentOp())
503 InitE = BO->getRHS();
510 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
511 const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
526 InitE = TmpR->getExpr();
541 EnableNullFPSuppression);
544 BR, EnableNullFPSuppression);
550 llvm::raw_svector_ostream os(sbuf);
553 const Stmt *S = PS->getStmt();
554 const char *action =
nullptr;
561 }
else if (isa<BlockExpr>(S)) {
563 "Captured by block as ";
567 SVal V = State->getSVal(S, PS->getLocationContext());
569 dyn_cast_or_null<BlockDataRegion>(V.
getAsRegion())) {
570 if (
const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
572 State->getSVal(OriginalR).getAs<
KnownSVal>())
573 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
574 *KV, OriginalR, EnableNullFPSuppression));
590 if (TR->getValueType()->isObjCObjectPointerType()) {
591 os << action <<
"nil";
598 os << action <<
"a null pointer value";
601 os << action << CVal->getValue();
605 if (isa<VarRegion>(R)) {
609 <<
" to a garbage value";
612 <<
" without an initial value";
623 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
624 const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
630 os <<
"nil object reference";
632 os <<
"null pointer value";
634 os <<
"uninitialized value";
637 os <<
"the value " << CI->getValue();
644 os <<
" via " << Idx << llvm::getOrdinalSuffix(Idx) <<
" parameter";
652 if (os.str().empty()) {
657 if (TR->getValueType()->isObjCObjectPointerType()) {
658 os <<
"nil object reference stored";
665 os <<
"Null pointer value stored";
667 os <<
"Storing null pointer value";
672 os <<
"Uninitialized value stored";
674 os <<
"Storing uninitialized value";
679 os <<
"The value " << CV->getValue() <<
" is assigned";
681 os <<
"Assigning " << CV->getValue();
685 os <<
"Value assigned";
687 os <<
"Assigning value";
709 return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
715 ID.AddBoolean(Assumption);
722 return "TrackConstraintBRVisitor";
725 bool TrackConstraintBRVisitor::isUnderconstrained(
const ExplodedNode *N)
const {
727 return N->
getState()->isNull(Constraint).isUnderconstrained();
728 return (
bool)N->
getState()->assume(Constraint, !Assumption);
731 std::shared_ptr<PathDiagnosticPiece>
740 if (!IsTrackingTurnedOn)
741 if (!isUnderconstrained(N))
742 IsTrackingTurnedOn =
true;
743 if (!IsTrackingTurnedOn)
748 if (isUnderconstrained(PrevN)) {
755 assert(!isUnderconstrained(N));
760 llvm::raw_svector_ostream os(sbuf);
763 os <<
"Assuming pointer value is ";
764 os << (Assumption ?
"non-null" :
"null");
767 if (os.str().empty())
777 auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
787 : V(Value), IsSatisfied(
false), IsTrackingTurnedOn(
false) {
791 assert(Eng &&
"Cannot file a bug report without an owning engine");
796 assert(N->
getState()->isNull(V).isConstrainedTrue() &&
797 "The visitor only tracks the cases where V is constrained to 0");
810 std::shared_ptr<PathDiagnosticPiece>
819 if (!IsTrackingTurnedOn)
820 if (Succ->
getState()->isNull(V).isConstrainedTrue())
821 IsTrackingTurnedOn =
true;
822 if (!IsTrackingTurnedOn)
827 if (!Pred->
getState()->isNull(V).isConstrainedTrue()) {
830 assert(Succ->
getState()->isNull(V).isConstrainedTrue());
835 if (CurLC != ReportLC && !CurLC->
isParentOf(ReportLC)) {
854 const Stmt *CurTerminatorStmt =
nullptr;
856 CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
858 const Stmt *CurStmt = SP->getStmt();
862 CFGStmtMap *
Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap();
868 if (!CurTerminatorStmt)
888 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
889 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
890 if (!VD->getType()->isReferenceType())
914 if (
auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
916 if (PropRef && PropRef->isMessagingGetter()) {
917 const Expr *GetterMessageSend =
918 POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
932 const CFGBlock *srcBlk = BE->getSrc();
935 bool TookTrueBranch = (*(srcBlk->
succ_begin()) == BE->getDst());
952 bool EnableNullFPSuppression) {
956 if (
const Expr *Ex = dyn_cast<Expr>(S)) {
957 Ex = Ex->IgnoreParenCasts();
963 const Expr *Inner =
nullptr;
964 if (
const Expr *Ex = dyn_cast<Expr>(S)) {
978 if (
const auto *Op = dyn_cast<UnaryOperator>(Ex))
979 if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue())
987 if (IsArg && !Inner) {
996 if (ps->getStmt() == S || ps->getStmt() == Inner)
999 if (CEE->getCalleeContext()->getCallSite() == S ||
1000 CEE->getCalleeContext()->getCallSite() == Inner)
1029 if (
P->getStmt() == Inner)
1034 assert(LVNode &&
"Unable to find the lvalue node.");
1038 if (LVState->isNull(LVal).isConstrainedTrue()) {
1053 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1054 *KV, RR, EnableNullFPSuppression));
1064 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(R));
1068 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1073 if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() &&
1074 EnableNullFPSuppression) {
1076 llvm::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV,
1082 report.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1083 *KV, R, EnableNullFPSuppression));
1094 if (
const Expr *
E = dyn_cast<Expr>(S))
1095 S =
E->IgnoreParenCasts();
1097 ReturnVisitor::addVisitorIfNecessary(N, S, report, EnableNullFPSuppression);
1108 if (
const Expr *
E = dyn_cast<Expr>(S))
1109 RVal = state->getRawSVal(L.getValue(),
E->getType());
1111 RVal = state->getSVal(L->getRegion());
1114 report.
addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
1116 if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
1118 report.
addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1134 if (state->isNull(V).isConstrainedTrue())
1140 std::shared_ptr<PathDiagnosticPiece>
1148 const Stmt *S = P->getStmt();
1154 llvm::raw_svector_ostream OS(Buf);
1158 ME->getSelector().print(OS);
1159 OS <<
"' not called";
1162 OS <<
"No method is called";
1164 OS <<
" because the receiver is nil";
1174 return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
1180 bool EnableNullFPSuppression) {
1183 WorkList.push_back(S);
1185 while (!WorkList.empty()) {
1186 const Stmt *Head = WorkList.front();
1187 WorkList.pop_front();
1192 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
1193 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1202 BR.
addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1209 WorkList.push_back(SubStmt);
1220 return "ConditionBRVisitor";
1223 std::shared_ptr<PathDiagnosticPiece>
1229 if (
auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
1230 ev->setPrunable(
true,
false);
1235 std::shared_ptr<PathDiagnosticPiece>
1247 if (CurrentState->getGDM().getRoot() ==
1248 PrevState->getGDM().getRoot())
1254 const CFGBlock *srcBlk = BE->getSrc();
1263 const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
1265 getEngine().geteagerlyAssumeBinOpBifurcationTags();
1268 if (tag == tags.first)
1271 if (tag == tags.second)
1284 const Expr *Cond =
nullptr;
1304 case Stmt::IfStmtClass:
1305 Cond = cast<IfStmt>(Term)->getCond();
1307 case Stmt::ConditionalOperatorClass:
1308 Cond = cast<ConditionalOperator>(Term)->getCond();
1310 case Stmt::BinaryOperatorClass:
1314 const auto *BO = cast<BinaryOperator>(Term);
1315 assert(BO->isLogicalOp() &&
1316 "CFG terminator is not a short-circuit operator!");
1317 Cond = BO->getLHS();
1324 while (
const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
1325 if (!InnerBO->isLogicalOp())
1332 const bool tookTrue = *(srcBlk->
succ_begin()) == dstBlk;
1336 std::shared_ptr<PathDiagnosticPiece>
1342 const Expr *CondTmp = Cond;
1343 bool tookTrueTmp = tookTrue;
1350 case Stmt::BinaryOperatorClass:
1352 tookTrueTmp, BRC, R, N))
1355 case Stmt::DeclRefExprClass:
1357 tookTrueTmp, BRC, R, N))
1360 case Stmt::UnaryOperatorClass: {
1363 tookTrueTmp = !tookTrueTmp;
1377 if (!
Loc.isValid() || !
Loc.asLocation().isValid())
1380 return std::make_shared<PathDiagnosticEventPiece>(
1381 Loc, tookTrue ? GenericTrueMessage : GenericFalseMessage);
1385 const Expr *ParentEx,
1391 const Expr *OriginalExpr = Ex;
1399 (isa<GNUNullExpr>(Ex) ||
1400 isa<ObjCBoolLiteralExpr>(Ex) ||
1401 isa<CXXBoolLiteralExpr>(Ex) ||
1402 isa<IntegerLiteral>(Ex) ||
1403 isa<FloatingLiteral>(Ex))) {
1409 bool beginAndEndAreTheSameMacro = StartName.equals(EndName);
1411 bool partOfParentMacro =
false;
1416 partOfParentMacro = PName.equals(StartName);
1419 if (beginAndEndAreTheSameMacro && !partOfParentMacro ) {
1435 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
1436 const bool quotes = isa<VarDecl>(DR->getDecl());
1453 Out << DR->getDecl()->getDeclName().getAsString();
1462 if (IL->getValue() == 0) {
1468 if (IL->getValue() == 0) {
1474 Out << IL->getValue();
1481 std::shared_ptr<PathDiagnosticPiece>
1486 bool shouldInvert =
false;
1491 llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
1493 BRC, R, N, shouldPrune);
1495 BRC, R, N, shouldPrune);
1497 shouldInvert = !isVarLHS && isVarRHS;
1511 if (LhsString.empty() || RhsString.empty() ||
1517 llvm::raw_svector_ostream Out(buf);
1518 Out <<
"Assuming " << (shouldInvert ? RhsString : LhsString) <<
" is ";
1524 case BO_LT: Op = BO_GT;
break;
1525 case BO_GT: Op = BO_LT;
break;
1526 case BO_LE: Op = BO_GE;
break;
1527 case BO_GE: Op = BO_LE;
break;
1532 case BO_EQ: Op = BO_NE;
break;
1533 case BO_NE: Op = BO_EQ;
break;
1534 case BO_LT: Op = BO_GE;
break;
1535 case BO_GT: Op = BO_LE;
break;
1536 case BO_LE: Op = BO_GT;
break;
1537 case BO_GE: Op = BO_LT;
break;
1547 Out <<
"not equal to ";
1554 Out << (shouldInvert ? LhsString : RhsString);
1557 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1558 if (shouldPrune.hasValue())
1559 event->setPrunable(shouldPrune.getValue());
1564 StringRef LhsString,
const Expr *CondVarExpr,
const bool tookTrue,
1570 llvm::raw_svector_ostream Out(buf);
1571 Out <<
"Assuming " << LhsString <<
" is ";
1576 Out << (tookTrue ?
"not null" :
"null");
1578 Out << (tookTrue ?
"not nil" :
"nil");
1580 Out << (tookTrue ?
"true" :
"false");
1582 Out << (tookTrue ?
"non-zero" :
"zero");
1588 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1590 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1591 if (
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1595 event->setPrunable(
false);
1603 std::shared_ptr<PathDiagnosticPiece>
1613 llvm::raw_svector_ostream Out(Buf);
1615 Out <<
"Assuming '" << VD->
getDeclName() <<
"' is ";
1620 Out << (tookTrue ?
"non-null" :
"null");
1622 Out << (tookTrue ?
"non-nil" :
"nil");
1624 Out << (tookTrue ?
"not equal to 0" :
"0");
1630 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
1633 if (
const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1635 event->setPrunable(
false);
1637 SVal V = state->getSVal(R);
1639 event->setPrunable(
false);
1642 return std::move(event);
1645 const char *
const ConditionBRVisitor::GenericTrueMessage =
1646 "Assuming the condition is true";
1647 const char *
const ConditionBRVisitor::GenericFalseMessage =
1648 "Assuming the condition is false";
1652 return Piece->
getString() == GenericTrueMessage ||
1653 Piece->
getString() == GenericFalseMessage;
1656 std::unique_ptr<PathDiagnosticPiece>
1684 if (CD->
getName() ==
"list") {
1694 if (CD->
getName() ==
"__independent_bits_engine") {
1713 if (CD->
getName() ==
"basic_string") {
1721 if (CD->
getName() ==
"shared_ptr") {
1735 if (SM.
getFilename(Loc).endswith(
"sys/queue.h")) {
1744 std::shared_ptr<PathDiagnosticPiece>
1764 I !=
E; ++
I, ++Idx) {
1765 const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1773 assert(ParamDecl &&
"Formal parameter has no decl?");
1788 SVal BoundVal = State->getSVal(R);
1797 std::shared_ptr<PathDiagnosticPiece>
1805 if (!Edge.hasValue())
1808 auto Tag = Edge->
getTag();
1812 if (Tag->getTagDescription() !=
"cplusplus.SelfAssignment")
1819 assert(Met &&
"Not a C++ method.");
1820 assert((Met->isCopyAssignmentOperator() || Met->isMoveAssignmentOperator()) &&
1821 "Not a copy/move assignment operator.");
1823 const auto *LCtx = Edge->getLocationContext();
1825 const auto &State = Succ->
getState();
1826 auto &SVB = State->getStateManager().getSValBuilder();
1829 State->getSVal(State->getRegion(Met->getParamDecl(0), LCtx));
1831 State->getSVal(SVB.getCXXThis(Met, LCtx->getCurrentStackFrame()));
1835 if (!L.isValid() || !L.asLocation().isValid())
1839 llvm::raw_svector_ostream Out(Buf);
1841 Out <<
"Assuming " << Met->getParamDecl(0)->getName() <<
1842 ((Param == This) ?
" == " :
" != ") <<
"*this";
1844 auto Piece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
1845 Piece->addRange(Met->getSourceRange());
1847 return std::move(Piece);
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
StmtClass getStmtClass() const
TypedValueRegion - An abstract class representing regions having a typed value.
const Expr * getDerefExpr(const Stmt *S)
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
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()
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
const ExplodedNode * getErrorNode() const
Stmt - This represents one statement.
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
bool shouldSuppressNullReturnPaths()
Returns whether or not paths that go through null returns should be suppressed.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
Decl - This represents one declaration (or definition), e.g.
Represents a point when we begin processing an inlined call.
virtual bool isBoundable() const
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
Manages the lifetime of CallEvent objects.
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded...
const ExpansionInfo & getExpansion() const
const Expr * getInit() const
bool isBooleanType() const
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)
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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
unsigned succ_size() 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 en...
ParmVarDecl - Represents a parameter to a function.
bool isZeroConstant() const
FullSourceLoc asLocation() const
bool isComparisonOp() const
const MemSpaceRegion * getMemorySpace() const
void Profile(llvm::FoldingSetNodeID &ID) const override
bool isScalarType() const
std::shared_ptr< PathDiagnosticPiece > VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
bool isReferenceType() const
bool isAnyPointerType() const
Represents a program point after a store evaluation.
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
MemRegionManager & getRegionManager()
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef.
StringRef getString() 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
const VarDecl * getDecl() const
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
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 LangOptions & getLangOpts() const
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
std::shared_ptr< PathDiagnosticPiece > VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, const bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
bool isUnknownOrUndef() const
A builtin binary operation expression such as "x + y" or "x <= y".
const Stmt * getCallSite() const
bool isParentOf(const LocationContext *LC) const
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.
static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N)
StringRef getDescription() const
ExplodedNode * getFirstPred()
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
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.
detail::InMemoryDirectory::const_iterator I
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
const LocationContext * getLocationContext() const
const StackFrameContext * getStackFrame() const
ConditionalOperator - The ?: ternary operator.
bool isAssignmentOp() const
bool shouldSuppressInlinedDefensiveChecks()
Returns whether or not diagnostics containing inlined defensive NULL checks should be suppressed...
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
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
CFGBlock - Represents a single basic block in a source-level CFG.
const MemRegion * StripCasts(bool StripBaseCasts=true) const
static const char * getTag()
Return the tag associated with this visitor.
Represents a point when we finish the call exit sequence (for inlined call).
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
ProgramState - This class encapsulates:
Expr - This represents one expression.
const ProgramStateRef & getState() const
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)
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
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.
Expr * getSubExpr() const
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.
unsigned Map[FirstTargetAddressSpace]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
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.
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 MatchFinder::MatchFinderOptions & Options
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.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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)
const StackFrameContext * getCurrentStackFrame() 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
void Profile(llvm::FoldingSetNodeID &ID) const override
bool isValid() const
Return true if this is a valid SourceLocation object.
CallEventManager & getCallEventManager()
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Represents a static or instance method of a struct/union/class.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
AnalyzerOptions & options
const Decl * getDecl() const
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
const Decl * getSingleDecl() const
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
bool isDeclRefExprToReference(const Expr *E)
const LocationContext * getParent() const
StringRef getOpcodeStr() const
const Decl & getCodeDecl() const
const LocationContext * getLocationContext() 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.
GRBugReporter & getBugReporter()
const Stmt * GetRetValExpr(const ExplodedNode *N)
detail::InMemoryDirectory::const_iterator E
const MemRegion * getAsRegion() const
const Expr * getRetValue() const
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Represents an SVal that is guaranteed to not be UnknownVal.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
ProgramStateManager & getStateManager()
bool shouldSuppressFromCXXStandardLibrary()
Returns whether or not diagnostics reported within the C++ standard library should be suppressed...
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.
const ProgramPointTag * getTag() const
Represents a C++ struct/union/class.
bool isObjCObjectPointerType() const
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.
bool isFunctionMacroExpansion() const
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.
Loc getLValue(const VarDecl *D, const LocationContext *LC) const
Get the lvalue for a variable reference.
A SourceLocation and its associated SourceManager.
A reference to a declared variable, function, enum, etc.
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
A trivial tuple used to represent a source range.
This class provides an interface through which checkers can create individual bug reports...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isConstQualified() const
Determine whether this type is const-qualified.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SourceLocation getLocStart() const LLVM_READONLY
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
This class handles loading and caching of source files into memory.
SourceManager & getSourceManager()
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
FullSourceLoc getSpellingLoc() const
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.
bool isPointerType() const