A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/BugReporterVisitors_8cpp_source.html below:

clang: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Source File

48#include "llvm/ADT/ArrayRef.h" 49#include "llvm/ADT/STLExtras.h" 50#include "llvm/ADT/SmallPtrSet.h" 51#include "llvm/ADT/SmallString.h" 52#include "llvm/ADT/SmallVector.h" 53#include "llvm/ADT/StringExtras.h" 54#include "llvm/ADT/StringRef.h" 55#include "llvm/Support/Casting.h" 56#include "llvm/Support/ErrorHandling.h" 57#include "llvm/Support/raw_ostream.h" 66using namespace clang

;

68using namespace

bugreporter;

102 const auto

*

E

= dyn_cast<Expr>(S);

107 if

(

const auto

*CE = dyn_cast<CastExpr>(

E

)) {

108 if

(CE->getCastKind() == CK_LValueToRValue) {

112 E

= CE->getSubExpr();

113

}

else if

(

const auto

*B = dyn_cast<BinaryOperator>(

E

)) {

117

}

else if

(B->isAssignmentOp()) {

125

}

else if

(

const auto

*

U

= dyn_cast<UnaryOperator>(

E

)) {

126 if

(

U

->getOpcode() == UO_Deref ||

U

->getOpcode() == UO_AddrOf ||

127

(

U

->isIncrementDecrementOp() &&

U

->getType()->isPointerType())) {

130 E

=

U

->getSubExpr();

138 else if

(

const auto

*ME = dyn_cast<MemberExpr>(

E

)) {

147 if

(ME->getMemberDecl()->getType()->isReferenceType())

150

}

else if

(

const auto

*IvarRef = dyn_cast<ObjCIvarRefExpr>(

E

)) {

151 E

= IvarRef->getBase();

152

}

else if

(

const auto

*AE = dyn_cast<ArraySubscriptExpr>(

E

)) {

154

}

else if

(

const auto

*PE = dyn_cast<ParenExpr>(

E

)) {

155 E

= PE->getSubExpr();

156

}

else if

(

const auto

*FE = dyn_cast<FullExpr>(

E

)) {

157 E

= FE->getSubExpr();

167 if

(

const auto

*CE = dyn_cast<ImplicitCastExpr>(

E

))

168 if

(CE->getCastKind() == CK_LValueToRValue)

169 E

= CE->getSubExpr();

175 if

(

const auto

*DR = dyn_cast<DeclRefExpr>(

E

))

176 return

dyn_cast<VarDecl>(DR->getDecl());

182 bool

LookingForReference =

true

) {

183 if

(

const auto

*ME = dyn_cast<MemberExpr>(

E

)) {

193 const auto

*FD = dyn_cast<FieldDecl>(ME->getMemberDecl());

197 if

(FD->getType()->isReferenceType()) {

199 return

N->

getState

()->getLValue(FD, StructSVal).getAsRegion();

222 if

(LeftVal == RightVal)

233 return

LLCV->

getRegion

() == RLCV->getRegion() &&

234

LLCV->getStore() == LeftNode->

getState

()->getStore() &&

235

RLCV->getStore() == RightNode->

getState

()->getStore();

250 if

(

const auto

*DRE = dyn_cast<DeclRefExpr>(CondVarExpr))

251 if

(

const auto

*VD = dyn_cast<VarDecl>(DRE->getDecl()))

252 return

State->getSVal(State->getLValue(VD, LCtx));

254 if

(

const auto

*ME = dyn_cast<MemberExpr>(CondVarExpr))

255 if

(

const auto

*FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))

256 if

(

auto

FieldL = State->getSVal(ME, LCtx).getAs<

Loc

>())

257 return

State->getRawSVal(*FieldL, FD->getType());

262static

std::optional<const llvm::APSInt *>

267 return

CI->getValue().get();

281 if

(std::optional<bugreporter::TrackingKind> K =

283 return

*K == bugreporter::TrackingKind::Condition;

308 if

(!

Loc

.isMacroID())

310 while

(

SM

.isMacroArgExpansion(

Loc

))

311 Loc

=

SM

.getImmediateExpansionRange(

Loc

).getBegin();

312

std::pair<FileID, unsigned> TLInfo =

SM

.getDecomposedLoc(

Loc

);

334 if

(BO->isAssignmentOp() && RegionOfInterest->

isSubRegionOf

(

339 SVal

ValueAtN = N->

getState

()->getSVal(RegionOfInterest);

341

.

areEqual

(State, ValueAtN, ValueAfter)

372 auto P

= std::make_shared<PathDiagnosticEventPiece>(

384bool

NoStateChangeFuncVisitor::isModifiedInFrame(

const ExplodedNode

*N) {

387 if

(!FramesModifyingCalculated.count(SCtx))

388

findModifyingFrames(N);

389 return

FramesModifying.count(SCtx);

392void

NoStateChangeFuncVisitor::markFrameAsModifying(

395 auto

p = FramesModifying.insert(SCtx);

411 auto

IsMatchingCallExitEnd = [OrigSCtx](

const ExplodedNode

*N) {

415 while

(N && !IsMatchingCallExitEnd(N)) {

417 "This function is to be used on the trimmed ExplodedGraph!"

);

423void

NoStateChangeFuncVisitor::findModifyingFrames(

431 const ExplodedNode

*CurrCallExitBeginN = CallExitBeginN;

434 for

(

const ExplodedNode

*CurrN = CallExitBeginN; CurrN;

438

CurrCallExitBeginN = CurrN;

440

FramesModifyingCalculated.insert(CurrentSCtx);

445 if

(

auto

CE = CurrN->getLocationAs<

CallEnter

>()) {

448

markFrameAsModifying(CurrentSCtx);

459 if

(CE->getCalleeContext() == OriginalSCtx) {

460

markFrameAsModifying(CurrentSCtx);

466

markFrameAsModifying(CurrentSCtx);

479 if

(!CallExitLoc || isModifiedInFrame(N))

494 if

(

Call

->isInSystemHeader()) {

509 if

(

const auto

*MC = dyn_cast<ObjCMethodCall>(

Call

)) {

516 if

(

const auto

*CCall = dyn_cast<CXXConstructorCall>(

Call

)) {

529 using namespace

ast_matchers;

530 const char

*IvarBind =

"Ivar"

;

534

hasOperatorName(

"="

),

535

hasLHS(ignoringParenImpCasts(

541 if

(IvarRef->isFreeIvar())

544 const Expr

*

Base

= IvarRef->getBase();

545 if

(

const auto

*ICE = dyn_cast<ImplicitCastExpr>(

Base

))

546 Base

= ICE->getSubExpr();

548 if

(

const auto

*DRE = dyn_cast<DeclRefExpr>(

Base

))

549 if

(

const auto

*ID = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))

564const

std::optional<NoStoreFuncVisitor::RegionVector>

565

NoStoreFuncVisitor::findRegionOfInterestInRecord(

570 if

(depth == DEREFERENCE_LIMIT)

573 if

(

const auto

*RDX = dyn_cast<CXXRecordDecl>(RD))

574 if

(!RDX->hasDefinition())

579 if

(

const auto

*RDX = dyn_cast<CXXRecordDecl>(RD))

580 for

(

const auto

&II : RDX->bases())

581 if

(

const RecordDecl

*RRD = II.getType()->getAsRecordDecl())

582 if

(std::optional<RegionVector> Out =

583

findRegionOfInterestInRecord(RRD, State, R, Vec, depth))

589 const SVal V

= State->getSVal(FR);

592

RegionVector VecF = Vec;

595 if

(RegionOfInterest == VR)

600

findRegionOfInterestInRecord(RRD, State, FR, VecF, depth + 1))

608 if

(std::optional<RegionVector> Out =

609

findRegionOfInterestInRecord(RRD, State, VR, VecF, depth + 1))

620 if

(

const auto

*IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest)) {

621 const MemRegion

*SelfRegion =

Call

.getReceiverSVal().getAsRegion();

625 return

maybeEmitNote(R,

Call

, N, {}, SelfRegion,

"self"

,

635 const MemRegion

*ThisR =

Call

.getCXXThisVal().getAsRegion();

637 return

maybeEmitNote(R,

Call

, N, {}, ThisR,

"this"

,

654 for

(

unsigned

I = 0; I <

Call

.getNumArgs() && I <

Parameters

.size(); ++I) {

660 unsigned

IndirectionLevel = 1;

662 while

(

const MemRegion

*MR =

V

.getAsRegion()) {

664 return

maybeEmitNote(R,

Call

, N, {}, MR, ParamName,

665

ParamIsReferenceType, IndirectionLevel);

668 if

(PT.isNull() || PT->isVoidType())

673 if

(

const RecordDecl

*RD = PT->getAsRecordDecl())

674 if

(std::optional<RegionVector>

P

=

675

findRegionOfInterestInRecord(RD, State, MR))

676 return

maybeEmitNote(R,

Call

, N, *

P

, RegionOfInterest, ParamName,

677

ParamIsReferenceType, IndirectionLevel);

679 V

= State->getSVal(MR, PT);

688bool

NoStoreFuncVisitor::wasModifiedBeforeCallExit(

690

return ::wasRegionOfInterestModifiedAt(

691

RegionOfInterest, CurrN,

692

CallExitBeginN->

getState

()->getSVal(RegionOfInterest));

696 ", which participates in a condition later"

;

700 const

RegionVector &FieldChain,

const MemRegion

*MatchedRegion,

701

StringRef FirstElement,

bool

FirstIsReferenceType,

702 unsigned

IndirectionLevel) {

714

llvm::raw_svector_ostream os(sbuf);

715

os <<

"Returning without writing to '"

;

718 if

(!prettyPrintRegionName(FieldChain, MatchedRegion, FirstElement,

719

FirstIsReferenceType, IndirectionLevel, os))

725 return

std::make_shared<PathDiagnosticEventPiece>(L, os.str());

728bool

NoStoreFuncVisitor::prettyPrintRegionName(

const

RegionVector &FieldChain,

730

StringRef FirstElement,

731 bool

FirstIsReferenceType,

732 unsigned

IndirectionLevel,

733

llvm::raw_svector_ostream &os) {

735 if

(FirstIsReferenceType)

738

RegionVector RegionSequence;

743 while

(R != MatchedRegion) {

744

RegionSequence.push_back(R);

745

R = cast<SubRegion>(R)->getSuperRegion();

747

std::reverse(RegionSequence.begin(), RegionSequence.end());

748

RegionSequence.append(FieldChain.begin(), FieldChain.end());

751 for

(

const MemRegion

*R : RegionSequence) {

755 if

(isa<CXXBaseObjectRegion, CXXTempObjectRegion>(R))

759

Sep = prettyPrintFirstElement(FirstElement,

761

IndirectionLevel, os);

766 if

(!isa<DeclRegion>(R))

769 const auto

*DR = cast<DeclRegion>(R);

770

Sep = DR->getValueType()->isAnyPointerType() ?

"->"

:

"."

;

771

DR->getDecl()->getDeclName().print(os, PP);

775

prettyPrintFirstElement(FirstElement,

776 false

, IndirectionLevel, os);

780

StringRef NoStoreFuncVisitor::prettyPrintFirstElement(

781

StringRef FirstElement,

bool

MoreItemsExpected,

int

IndirectionLevel,

782

llvm::raw_svector_ostream &os) {

783

StringRef Out =

"."

;

785 if

(IndirectionLevel > 0 && MoreItemsExpected) {

790 if

(IndirectionLevel > 0 && MoreItemsExpected)

793 for

(

int

i = 0; i < IndirectionLevel; i++)

797 if

(IndirectionLevel > 0 && MoreItemsExpected)

813 const SVal

ValueAtDereference;

817 bool

WasModified =

false

;

820

MacroNullReturnSuppressionVisitor(

const SubRegion

*R,

const SVal V

)

821

: RegionOfInterest(R), ValueAtDereference(

V

) {}

834 if

(

auto Loc

= matchAssignment(N)) {

849 static void

addMacroVisitorIfNecessary(

854 if

(EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths &&

860 void

* getTag()

const

{

862 return static_cast<void

*

>

(&

Tag

);

865 void

Profile(llvm::FoldingSetNodeID &

ID

)

const override

{

866 ID

.AddPointer(getTag());

872

std::optional<SourceLocation> matchAssignment(

const ExplodedNode

*N) {

879 if

(

const auto

*DS = dyn_cast<DeclStmt>(S)) {

880 if

(

const auto

*VD = dyn_cast<VarDecl>(DS->getSingleDecl()))

881 if

(

const Expr

*RHS = VD->getInit())

882 if

(RegionOfInterest->isSubRegionOf(

883

State->getLValue(VD, LCtx).getAsRegion()))

884 return

RHS->getBeginLoc();

885

}

else if

(

const auto

*BO = dyn_cast<BinaryOperator>(S)) {

887 const Expr

*RHS = BO->getRHS();

888 if

(BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) {

915 bool

EnableNullFPSuppression;

916 bool

ShouldInvalidate =

true

;

925

EnableNullFPSuppression(Suppressed), Options(Options), TKind(TKind) {}

927 static void

*getTag() {

929 return static_cast<void

*

>

(&

Tag

);

932 void

Profile(llvm::FoldingSetNodeID &

ID

)

const override

{

933 ID

.AddPointer(ReturnVisitor::getTag());

934 ID

.AddPointer(CalleeSFC);

935 ID

.AddBoolean(EnableNullFPSuppression);

949 const auto

*

Ret

= dyn_cast<ReturnStmt>(SP->getStmt());

956 SVal V

= State->getSVal(Ret, CalleeSFC);

957 if

(

V

.isUnknownOrUndef())

963 const Expr

*RetE =

Ret

->getRetValue();

964

assert(RetE &&

"Tracking a return value for a void function"

);

967

std::optional<Loc> LValue;

969 if

((LValue =

V

.getAs<

Loc

>())) {

970 SVal

RValue = State->getRawSVal(*LValue, RetE->

getType

());

971 if

(isa<DefinedSVal>(RValue))

977 if

(isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(

V

))

983

getParentTracker().track(RetE, N, {TKind, EnableNullFPSuppression});

987

llvm::raw_svector_ostream Out(Msg);

989 bool

WouldEventBeMeaningless =

false

;

991 if

(State->isNull(

V

).isConstrainedTrue()) {

997 if

(EnableNullFPSuppression &&

998

Options.ShouldAvoidSuppressingNullArgumentPaths)

999

Mode = MaybeUnsuppress;

1002

Out <<

"Returning nil"

;

1004

Out <<

"Returning null pointer"

;

1007

Out <<

"Returning zero"

;

1012

Out <<

"Returning the value "

<< CI->getValue();

1020

WouldEventBeMeaningless =

true

;

1022

Out << (isa<Loc>(

V

) ?

"Returning pointer"

:

"Returning value"

);

1027 if

(

const MemRegion

*MR = LValue->getAsRegion()) {

1028 if

(MR->canPrintPretty()) {

1029

Out <<

" (reference to "

;

1030

MR->printPretty(Out);

1036 if

(

const auto

*DR = dyn_cast<DeclRefExpr>(RetE))

1037 if

(

const auto

*DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))

1038

Out <<

" (loaded from '"

<< *DD <<

"')"

;

1042 if

(!L.isValid() || !L.asLocation().isValid())

1045 if

(TKind == bugreporter::TrackingKind::Condition)

1048 auto

EventPiece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());

1052 if

(WouldEventBeMeaningless)

1053

EventPiece->setPrunable(

true

);

1063

assert(Options.ShouldAvoidSuppressingNullArgumentPaths);

1070 if

(CE->getCalleeContext() != CalleeSFC)

1083 for

(

unsigned

I = 0,

E

=

Call

->getNumArgs(); I !=

E

; ++I) {

1084

std::optional<Loc> ArgV =

Call

->getArgSVal(I).getAs<

Loc

>();

1088 const Expr

*ArgE =

Call

->getArgExpr(I);

1093 if

(!State->isNull(*ArgV).isConstrainedTrue())

1096 if

(getParentTracker()

1097

.track(ArgE, N, {TKind, EnableNullFPSuppression})

1098

.FoundSomethingToTrack)

1099

ShouldInvalidate =

false

;

1114 return

visitNodeInitial(N, BRC, BR);

1115 case

MaybeUnsuppress:

1116 return

visitNodeMaybeUnsuppress(N, BRC, BR);

1121

llvm_unreachable(

"Invalid visit mode!"

);

1126 if

(EnableNullFPSuppression && ShouldInvalidate)

1127

BR.

markInvalid

(ReturnVisitor::getTag(), CalleeSFC);

1140 bool

Satisfied =

false

;

1160

OriginSFC(OriginSFC) {

1164 void

Profile(llvm::FoldingSetNodeID &

ID

)

const override

;

1172void

StoreSiteFinder::Profile(llvm::FoldingSetNodeID &ID)

const

{

1174 ID

.AddPointer(&tag);

1177 ID

.AddInteger(

static_cast<int>

(Options.Kind));

1178 ID

.AddBoolean(Options.EnableNullFPSuppression);

1196 const auto

*FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace);

1201

[[maybe_unused]]

bool

IsLocalStaticOrLocalExtern =

1203

assert(IsLocalStaticOrLocalExtern &&

1204 "Declared a variable on the stack without Stack memspace?"

);

1215 if

(

const auto

*TR = dyn_cast<TypedValueRegion>(R))

1216 return

TR->getValueType()->isObjCObjectPointerType();

1222 return D

->getType()->isObjCObjectPointerType();

1234 const char

*Action =

nullptr

;

1238

Action = HasPrefix ?

"initialized to "

:

"Initializing to "

;

1241

Action = HasPrefix ?

"captured by block as "

:

"Captured by block as "

;

1244

llvm_unreachable(

"Unexpected store kind"

);

1247 if

(isa<loc::ConcreteInt>(SI.

Value

)) {

1251 OS

<< Action << CVal->getValue();

1254 OS

<< Action <<

"the value of "

;

1265 if

(isa<VarRegion>(SI.

Dest

)) {

1266 const auto

*VD = cast<VarDecl>(DS->getSingleDecl());

1268 if

(VD->getInit()) {

1269 OS

<< (HasPrefix ?

"initialized"

:

"Initializing"

)

1270

<<

" to a garbage value"

;

1272 OS

<< (HasPrefix ?

"declared"

:

"Declaring"

)

1273

<<

" without an initial value"

;

1277 OS

<< (HasPrefix ?

"initialized"

:

"Initialized"

) <<

" here"

;

1285 const auto

*VR = cast<VarRegion>(SI.

Dest

);

1286 const auto

*

D

= VR->getDecl();

1290 if

(isa<loc::ConcreteInt>(SI.

Value

)) {

1291 OS

<< (

isObjCPointer

(

D

) ?

"nil object reference"

:

"null pointer value"

);

1294 OS

<<

"uninitialized value"

;

1297 OS

<<

"the value "

<< CI->getValue();

1306 if

(

const auto

*Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {

1308 unsigned

Idx = Param->getFunctionScopeIndex() + 1;

1309 OS

<<

" via "

<< Idx << llvm::getOrdinalSuffix(Idx) <<

" parameter"

;

1314

}

else if

(

const auto

*ImplParam = dyn_cast<ImplicitParamDecl>(

D

)) {

1316 OS

<<

" via implicit parameter 'self'"

;

1326 if

(isa<loc::ConcreteInt>(SI.

Value

)) {

1328

: (HasSuffix ?

"Null pointer value stored" 1329

:

"Storing null pointer value"

));

1332 OS

<< (HasSuffix ?

"Uninitialized value stored" 1333

:

"Storing uninitialized value"

);

1337 OS

<<

"The value "

<< CV->getValue() <<

" is assigned"

;

1339 OS

<<

"Assigning "

<< CV->getValue();

1343 OS

<<

"The value of "

;

1345 OS

<<

" is assigned"

;

1347 OS

<<

"Assigning the value of "

;

1352 OS

<< (HasSuffix ?

"Value assigned"

:

"Assigning value"

);

1373 const auto

*TVR = dyn_cast_or_null<TypedValueRegion>(R);

1381

std::stack<const TypedValueRegion *> TVRStack;

1382 while

(isa<FieldRegion>(TVR) || isa<ElementRegion>(TVR)) {

1387 if

(ITy == TVR->getValueType().getCanonicalType())

1391

TVR = cast<TypedValueRegion>(TVR->getSuperRegion());

1396 if

(ITy != TVR->getValueType().getCanonicalType())

1400 while

(!TVRStack.empty()) {

1401

TVR = TVRStack.top();

1406 if

(!isa<InitListExpr>(

Init

))

1409

ILE = cast<InitListExpr>(

Init

);

1412 if

(

const auto

*FR = dyn_cast<FieldRegion>(TVR)) {

1413 const auto

*FD = FR->

getDecl

();

1415 if

(FD->getFieldIndex() >= NumInits)

1419

}

else if

(

const auto

*ER = dyn_cast<ElementRegion>(TVR)) {

1420 const auto

Ind = ER->getIndex();

1424 if

(!Ind.isConstant())

1427 const auto

IndVal = Ind.getAsInteger()->getLimitedValue();

1428 if

(IndVal >= NumInits)

1446 const Expr

*InitE =

nullptr

;

1447 bool

IsParam =

false

;

1450 if

(

const auto

*VR = dyn_cast<VarRegion>(R)) {

1453

InitE = VR->getDecl()->getInit();

1459 if

(std::optional<PostInitializer> PIP =

1462 if

(FieldReg == R) {

1464

InitE = PIP->getInitializer()->getInit();

1474 if

(Succ->

getState

()->getSVal(R) !=

V

)

1479 if

(!PS || PS->getLocationValue() != R)

1489 if

(BO->isAssignmentOp())

1490

InitE = BO->getRHS();

1494 else if

(

const auto

*DS =

P

->getStmtAs<

DeclStmt

>()) {

1495 const auto

*

Decl

= DS->getSingleDecl();

1496 if

(isa<VarDecl>(

Decl

)) {

1497 const auto

*VD = cast<VarDecl>(

Decl

);

1505 if

(

const auto

*ILE = dyn_cast<InitListExpr>(VD->getInit()))

1510 const auto

State = Succ->

getState

();

1521

std::stack<const SubRegion *> SRStack;

1522 const SubRegion

*SR = cast<SubRegion>(R);

1523 while

(isa<FieldRegion>(SR) || isa<ElementRegion>(SR)) {

1529 const auto

*OriginEx = CE->getArg(0);

1530 const auto

OriginVal =

1536 SVal

OriginField = OriginVal;

1537 while

(!SRStack.empty()) {

1538 const auto

*TopR = SRStack.top();

1541 if

(

const auto

*FR = dyn_cast<FieldRegion>(TopR)) {

1542

OriginField = State->getLValue(FR->

getDecl

(), OriginField);

1543

}

else if

(

const auto

*ER = dyn_cast<ElementRegion>(TopR)) {

1544

OriginField = State->getLValue(ER->getElementType(),

1545

ER->getIndex(), OriginField);

1552

getParentTracker().track(

V

, OriginField.

getAsRegion

(), Options);

1557 else if

(

const auto

*ILE =

P

->getStmtAs<

InitListExpr

>()) {

1573 if

(

const auto

*VR = dyn_cast<VarRegion>(R)) {

1575 if

(

const auto

*Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {

1581

InitE =

Call

->getArgExpr(Param->getFunctionScopeIndex());

1584

assert(isa<ImplicitParamDecl>(VR->getDecl()));

1585

InitE = cast<ObjCMessageExpr>(CE->getCalleeContext()->getCallSite())

1594 if

(

const auto

*TmpR = dyn_cast<CXXTempObjectRegion>(R))

1595

InitE = TmpR->getExpr();

1609

getParentTracker().track(InitE, StoreSite, Options);

1633 if

(

SM

.includedInBindings(N->

getState

()->getStore(), Candidate)) {

1635 if

(N->

getState

()->getSVal(Candidate) ==

V

) {

1636

OldRegion = Candidate;

1655 if

(!OldRegion && StoreSite->

getState

()->getSVal(R) ==

V

) {

1660

NodeWithoutBinding && NodeWithoutBinding->

getState

()->getSVal(R) ==

V

;

1661

NodeWithoutBinding = NodeWithoutBinding->

getFirstPred

()) {

1664 if

(NodeWithoutBinding) {

1676

OldRegion = FB.getRegion();

1680 if

(Options.Kind == TrackingKind::Condition && OriginSFC &&

1686

llvm::raw_svector_ostream os(sbuf);

1696 const Stmt

*S = PS->getStmt();

1697 const auto

*DS = dyn_cast<DeclStmt>(S);

1698 const auto

*VR = dyn_cast<VarRegion>(R);

1702

}

else if

(isa<BlockExpr>(S)) {

1708 if

(

const auto

*BDR =

1709

dyn_cast_or_null<BlockDataRegion>(

V

.getAsRegion())) {

1710 if

(

const VarRegion

*OriginalR = BDR->getOriginalRegion(VR)) {

1711

getParentTracker().track(State->getSVal(OriginalR), OriginalR,

1712

Options, OriginSFC);

1718

isa<VarRegion>(SI.

Dest

)) {

1722 return

getParentTracker().handle(SI, BRC, Options);

1731

ID.AddPointer(&tag);

1732

ID.AddString(Message);

1733

ID.AddBoolean(Assumption);

1740 return "TrackConstraintBRVisitor"

;

1743bool

TrackConstraintBRVisitor::isZeroCheck()

const

{

1744 return

!Assumption && Constraint.

getAs

<

Loc

>();

1747bool

TrackConstraintBRVisitor::isUnderconstrained(

const ExplodedNode

*N)

const

{

1749 return

N->

getState

()->isNull(Constraint).isUnderconstrained();

1750 return

(

bool

)N->

getState

()->assume(Constraint, !Assumption);

1761 if

(!IsTrackingTurnedOn)

1762 if

(!isUnderconstrained(N))

1763

IsTrackingTurnedOn =

true

;

1764 if

(!IsTrackingTurnedOn)

1769 if

(isUnderconstrained(PrevN)) {

1770

IsSatisfied =

true

;

1776

assert(!isUnderconstrained(N));

1784 if

(isa_and_nonnull<NoteTag>(

P

.getTag()))

1792 auto X

= std::make_shared<PathDiagnosticEventPiece>(L, Message);

1794 return

std::move(

X

);

1809 if

(!Options.ShouldSuppressInlinedDefensiveChecks)

1810

IsSatisfied =

true

;

1814

llvm::FoldingSetNodeID &ID)

const

{

1816

ID.AddPointer(&

id

);

1821 return "IDCVisitor"

;

1833 if

(!IsTrackingTurnedOn)

1834 if

(Succ->

getState

()->isNull(

V

).isConstrainedTrue())

1835

IsTrackingTurnedOn =

true

;

1836 if

(!IsTrackingTurnedOn)

1841 if

(!Pred->

getState

()->isNull(

V

).isConstrainedTrue() &&

1842

Succ->

getState

()->isNull(

V

).isConstrainedTrue()) {

1843

IsSatisfied =

true

;

1848 if

(CurLC != ReportLC && !CurLC->

isParentOf

(ReportLC)) {

1863 const Stmt

*CurTerminatorStmt =

nullptr

;

1865

CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();

1867 const Stmt

*CurStmt = SP->getStmt();

1877 if

(!CurTerminatorStmt)

1911class

TrackControlDependencyCondBRVisitor final

1915

llvm::SmallSet<const CFGBlock *, 32> VisitedBlocks;

1918

TrackControlDependencyCondBRVisitor(

TrackerRef

ParentTracker,

1921

ControlDeps(&O->getCFG()) {}

1923 void

Profile(llvm::FoldingSetNodeID &

ID

)

const override

{

1934static

std::shared_ptr<PathDiagnosticEventPiece>

1947 return

std::make_shared<PathDiagnosticEventPiece>(

1950

(Twine() +

"Tracking condition '"

+ ConditionText +

"'"

).str());

1978 if

(

const auto

*BinOp = dyn_cast<BinaryOperator>(ElseCond))

1979 if

(BinOp->isLogicalOp())

1986

TrackControlDependencyCondBRVisitor::VisitNode(

const ExplodedNode

*N,

1996 if

(!VisitedBlocks.insert(NB).second)

2002 if

(!OriginB || !NB)

2008 if

(ControlDeps.isControlDependent(OriginB, NB)) {

2034 if

(isa<CallExpr>(InnerExpr))

2041

getParentTracker().track(InnerExpr, N,

2059 if

(

const auto

*FE = dyn_cast<FullExpr>(Ex))

2061 if

(

const auto

*OVE = dyn_cast<OpaqueValueExpr>(Ex))

2063 if

(

const auto

*POE = dyn_cast<PseudoObjectExpr>(Ex)) {

2064 const auto

*PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());

2065 if

(PropRef && PropRef->isMessagingGetter()) {

2066 const Expr

*GetterMessageSend =

2067

POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);

2074 if

(

const auto

*CO = dyn_cast<ConditionalOperator>(Ex)) {

2080 if

(std::optional<BlockEdge> BE = ProgPoint.

getAs

<

BlockEdge

>()) {

2081 const CFGBlock

*srcBlk = BE->getSrc();

2084 bool

TookTrueBranch = (*(srcBlk->

succ_begin

()) == BE->getDst());

2096 if

(

auto

*BO = dyn_cast<BinaryOperator>(Ex))

2100 if

(

auto

*UO = dyn_cast<UnaryOperator>(Ex)) {

2101 if

(UO->getOpcode() == UO_LNot)

2112 if

(UO->getOpcode() == UO_AddrOf && UO->getSubExpr()->isLValue())

2123 const Expr

*Inner) {

2138

StringRef NodeText) {

2144 P

.getLocationContext());

2152 return

std::make_shared<PathDiagnosticEventPiece>(L, NodeText);

2164

llvm::raw_svector_ostream OS(Buffer);

2179 if

(Opts.

Kind

== bugreporter::TrackingKind::Condition)

2182 return

constructNote(SI, BRC, OS.str());

2202

->getAnalysisManager()

2203

.getAnalyzerOptions()

2204

.ShouldTrackConditions) {

2205 Report

.addVisitor<TrackControlDependencyCondBRVisitor>(

2206

&getParentTracker(), InputNode);

2224 if

(

const Expr

*Receiver =

2226 return

getParentTracker().track(Receiver, LVNode, Opts);

2240 if

(

const auto

*Arr = dyn_cast<ArraySubscriptExpr>(Inner))

2241 return

getParentTracker().track(

2242

Arr->getIdx(), LVNode,

2243

{Opts.Kind,

false});

2268 bool

LVIsNull = LVState->isNull(LVal).isConstrainedTrue();

2273 if

(RR && !LVIsNull)

2274

Result.combineWith(getParentTracker().track(LVal, RR, Opts, SFC));

2291

Result.FoundSomethingToTrack =

true

;

2292

Result.WasInterrupted =

true

;

2294

MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(

2302 if

(

V

.getAsLocSymbol(

true

))

2303 if

(LVState->isNull(

V

).isConstrainedTrue())

2306 false

,

"Assuming pointer value is null"

);

2319

getParentTracker().track(

V

, R, Opts, SFC);

2347 const bool

BypassCXXNewExprEval = isa<CXXNewExpr>(

E

);

2354 if

(std::optional<CallExitEnd> CEE =

2356 if

(CEE->getCalleeContext()->getCallSite() ==

E

)

2369 if

(!BypassCXXNewExprEval)

2372 if

(SP->getStmt() ==

E

&& CurrentSFC == PredSFC)

2375

CurrentSFC = PredSFC;

2398 if

(cast<Expr>(

E

)->isGLValue())

2399 if

(std::optional<Loc> LValue = RetVal.

getAs

<

Loc

>())

2400

RetVal = State->getSVal(*LValue);

2405 bool

EnableNullFPSuppression =

false

;

2407 if

(std::optional<Loc> RetLoc = RetVal.

getAs

<

Loc

>())

2408

EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();

2411 Report

.addVisitor<ReturnVisitor>(&getParentTracker(), CalleeContext,

2412

EnableNullFPSuppression, Options,

2440 bool

CanDereference =

true

;

2442 if

(SR->getPointeeStaticType()->isVoidType())

2443

CanDereference =

false

;

2445

CanDereference =

false

;

2452

RVal = LVState->getRawSVal(*L, Inner->getType());

2453 else if

(CanDereference)

2454

RVal = LVState->getSVal(L->getRegion());

2456 if

(CanDereference) {

2458

Result.FoundSomethingToTrack =

true

;

2462

getParentTracker().track(RVal, L->getRegion(), Opts, SFC));

2466 if

(isa_and_nonnull<SymbolicRegion>(RegionRVal)) {

2467 Report

.markInteresting(RegionRVal, Opts.

Kind

);

2470 false

,

"Assuming pointer value is null"

);

2471

Result.FoundSomethingToTrack =

true

;

2498 const auto

track = [&CombinedResult, &

Parent

, ExprNode,

2499

Opts](

const Expr

*Inner) {

2508 if

(

const auto

*ILE = dyn_cast<InitListExpr>(

E

)) {

2509 if

(ILE->getNumInits() == 1) {

2510

track(ILE->getInit(0));

2512 return

CombinedResult;

2520 const auto

*BO = dyn_cast<BinaryOperator>(

E

);

2522 if

(!BO || !BO->isMultiplicativeOp() || !

V

.isZeroConstant())

2529 if

(BO->getOpcode() == BO_Mul) {

2531

track(BO->getLHS());

2533

track(BO->getRHS());

2536

track(BO->getLHS());

2539 return

CombinedResult;

2546

addLowPriorityHandler<ControlDependencyHandler>();

2547

addLowPriorityHandler<NilReceiverHandler>();

2548

addLowPriorityHandler<ArrayIndexHandler>();

2549

addLowPriorityHandler<InterestingLValueHandler>();

2550

addLowPriorityHandler<InlinedFunctionCallHandler>();

2551

addLowPriorityHandler<DefaultExpressionHandler>();

2552

addLowPriorityHandler<PRValueHandler>();

2554

addHighPriorityHandler<DefaultStoreHandler>();

2569 for

(ExpressionHandlerPtr &Handler : ExpressionHandlers) {

2570

CombinedResult.

combineWith

(Handler->handle(Inner, N, LVNode, Opts));

2579 return

CombinedResult;

2584 if

(!

V

.isUnknown()) {

2585 Report

.addVisitor<StoreSiteFinder>(

this

,

V

, R, Opts, Origin);

2594 for

(StoreHandlerPtr &Handler : StoreHandlers) {

2609

->track(

E

, InputNode, Opts)

2610

.FoundSomethingToTrack;

2626 const auto

*ME = dyn_cast<ObjCMessageExpr>(S);

2629 if

(

const Expr

*Receiver = ME->getInstanceReceiver()) {

2632 if

(state->isNull(

V

).isConstrainedTrue())

2645 const Stmt

*S =

P

->getStmt();

2646 const Expr

*Receiver = getNilReceiver(S, N);

2651

llvm::raw_svector_ostream

OS

(Buf);

2653 if

(

const auto

*ME = dyn_cast<ObjCMessageExpr>(S)) {

2655

ME->getSelector().print(

OS

);

2656 OS

<<

"' not called"

;

2659 OS

<<

"No method is called"

;

2661 OS

<<

" because the receiver is nil"

;

2672 return

std::make_shared<PathDiagnosticEventPiece>(L,

OS

.str());

2686 auto

piece = VisitNodeImpl(N, BRC, BR);

2688

piece->setTag(getTag());

2689 if

(

auto

*ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))

2690

ev->setPrunable(

true

,

false

);

2700 const

std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags =

2705 if

(std::optional<BlockEdge> BE = ProgPoint.

getAs

<

BlockEdge

>()) {

2706 const CFGBlock

*SrcBlock = BE->getSrc();

2714 if

(PreviousNodeTag == Tags.first || PreviousNodeTag == Tags.second)

2717 return

VisitTerminator(Term, N, SrcBlock, BE->getDst(), BR, BRC);

2722 if

(std::optional<PostStmt> PS = ProgPoint.

getAs

<

PostStmt

>()) {

2724 if

(CurrentNodeTag != Tags.first && CurrentNodeTag != Tags.second)

2727 bool

TookTrue = CurrentNodeTag == Tags.first;

2728 return

VisitTrueTest(cast<Expr>(PS->getStmt()), BRC, BR, N, TookTrue);

2738 const Expr

*Cond =

nullptr

;

2758 case

Stmt::IfStmtClass:

2759

Cond = cast<IfStmt>(Term)->getCond();

2761 case

Stmt::ConditionalOperatorClass:

2762

Cond = cast<ConditionalOperator>(Term)->getCond();

2764 case

Stmt::BinaryOperatorClass:

2768 const auto

*BO = cast<BinaryOperator>(Term);

2769

assert(BO->isLogicalOp() &&

2770 "CFG terminator is not a short-circuit operator!"

);

2771

Cond = BO->getLHS();

2780 while

(

const auto

*InnerBO = dyn_cast<BinaryOperator>(Cond)) {

2781 if

(!InnerBO->isLogicalOp())

2788 const bool

TookTrue = *(srcBlk->

succ_begin

()) == dstBlk;

2789 return

VisitTrueTest(Cond, BRC, R, N, TookTrue);

2816

CurrentState->getSVal(Cond, LCtx).isUnknownOrUndef();

2820 const Expr

*CondTmp = Cond;

2821 bool

TookTrueTmp = TookTrue;

2828 case

Stmt::BinaryOperatorClass:

2829 if

(

auto P

= VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),

2830

BRC, R, N, TookTrueTmp, IsAssuming))

2833 case

Stmt::DeclRefExprClass:

2834 if

(

auto P

= VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),

2835

BRC, R, N, TookTrueTmp, IsAssuming))

2838 case

Stmt::MemberExprClass:

2839 if

(

auto P

= VisitTrueTest(Cond, cast<MemberExpr>(CondTmp),

2840

BRC, R, N, TookTrueTmp, IsAssuming))

2843 case

Stmt::UnaryOperatorClass: {

2844 const auto

*UO = cast<UnaryOperator>(CondTmp);

2845 if

(UO->getOpcode() == UO_LNot) {

2846

TookTrueTmp = !TookTrueTmp;

2847

CondTmp = UO->getSubExpr();

2867 return

std::make_shared<PathDiagnosticEventPiece>(

2868 Loc

, TookTrue ? GenericTrueMessage : GenericFalseMessage);

2875

std::optional<bool> &prunable,

2876 bool

IsSameFieldName) {

2877 const Expr

*OriginalExpr = Ex;

2898 if

(

const auto

*DR = dyn_cast<DeclRefExpr>(Ex)) {

2899 const bool

quotes = isa<VarDecl>(DR->getDecl());

2916

Out << DR->getDecl()->getDeclName().getAsString();

2922 if

(

const auto

*IL = dyn_cast<IntegerLiteral>(Ex)) {

2925 if

(IL->getValue() == 0) {

2931 if

(IL->getValue() == 0) {

2937

Out << IL->getValue();

2941 if

(

const auto

*ME = dyn_cast<MemberExpr>(Ex)) {

2942 if

(!IsSameFieldName)

2943

Out <<

"field '"

<< ME->getMemberDecl()->getName() <<

'\''

;

2960 bool

shouldInvert =

false

;

2961

std::optional<bool> shouldPrune;

2965 bool

IsSameFieldName =

false

;

2971

LhsME->getMemberDecl()->getName() == RhsME->getMemberDecl()->getName();

2975

llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);

2976 const bool

isVarLHS = patternMatch(BExpr->

getLHS

(), BExpr, OutLHS, BRC, R,

2977

N, shouldPrune, IsSameFieldName);

2978 const bool

isVarRHS = patternMatch(BExpr->

getRHS

(), BExpr, OutRHS, BRC, R,

2979

N, shouldPrune, IsSameFieldName);

2981

shouldInvert = !isVarLHS && isVarRHS;

2989 return

VisitConditionVariable(LhsString, BExpr->

getLHS

(), BRC, R, N,

2995 if

(LhsString.empty() || RhsString.empty() ||

3001

llvm::raw_svector_ostream Out(buf);

3002

Out << (IsAssuming ?

"Assuming "

:

""

)

3003

<< (shouldInvert ? RhsString : LhsString) <<

" is "

;

3009 case

BO_LT: Op = BO_GT;

break

;

3010 case

BO_GT: Op = BO_LT;

break

;

3011 case

BO_LE: Op = BO_GE;

break

;

3012 case

BO_GE: Op = BO_LE;

break

;

3017 case

BO_EQ: Op = BO_NE;

break

;

3018 case

BO_NE: Op = BO_EQ;

break

;

3019 case

BO_LT: Op = BO_GE;

break

;

3020 case

BO_GT: Op = BO_LE;

break

;

3021 case

BO_LE: Op = BO_GT;

break

;

3022 case

BO_GE: Op = BO_LT;

break

;

3029

Out <<

"equal to "

;

3032

Out <<

"not equal to "

;

3039

Out << (shouldInvert ? LhsString : RhsString);

3048

std::string Message = std::string(Out.str());

3049

Message[0] = toupper(Message[0]);

3054 if

(!shouldInvert) {

3055 if

(LhsME && LhsME->getMemberLoc().isValid())

3060 if

(RhsME && RhsME->getMemberLoc().isValid())

3066 return

std::make_shared<PathDiagnosticPopUpPiece>(

Loc

, Message);

3070 auto event

= std::make_shared<PathDiagnosticEventPiece>(

Loc

, Message);

3072 event

->setPrunable(*shouldPrune);

3083

llvm::raw_svector_ostream Out(buf);

3084

Out <<

"Assuming "

<< LhsString <<

" is "

;

3086 if

(!printValue(CondVarExpr, Out, N, TookTrue,

true

))

3095 auto event

= std::make_shared<PathDiagnosticEventPiece>(

Loc

, Out.str());

3098 event

->setPrunable(

false

);

3107 const auto

*VD = dyn_cast<VarDecl>(DRE->

getDecl

());

3112

llvm::raw_svector_ostream Out(Buf);

3114

Out << (IsAssuming ?

"Assuming '"

:

"'"

) << VD->getDeclName() <<

"' is "

;

3116 if

(!printValue(DRE, Out, N, TookTrue, IsAssuming))

3127 return

std::make_shared<PathDiagnosticPopUpPiece>(

Loc

, Out.str());

3131 auto event

= std::make_shared<PathDiagnosticEventPiece>(

Loc

, Out.str());

3134 event

->setPrunable(

false

);

3136 return

std::move(event);

3144

llvm::raw_svector_ostream Out(Buf);

3146

Out << (IsAssuming ?

"Assuming field '"

:

"Field '"

)

3149 if

(!printValue(ME, Out, N, TookTrue, IsAssuming))

3169 return

std::make_shared<PathDiagnosticPopUpPiece>(

Loc

, Out.str());

3171 auto event

= std::make_shared<PathDiagnosticEventPiece>(

Loc

, Out.str());

3173 event

->setPrunable(

false

);

3183

Out << (TookTrue ?

"non-null"

:

"null"

);

3188

Out << (TookTrue ?

"non-nil"

:

"nil"

);

3195

std::optional<const llvm::APSInt *> IntValue;

3199 if

(IsAssuming || !IntValue) {

3201

Out << (TookTrue ?

"true"

:

"false"

);

3203

Out << (TookTrue ?

"not equal to 0"

:

"0"

);

3206

Out << ((*IntValue)->getBoolValue() ?

"true"

:

"false"

);

3214constexpr

llvm::StringLiteral ConditionBRVisitor::GenericTrueMessage;

3215constexpr

llvm::StringLiteral ConditionBRVisitor::GenericFalseMessage;

3219 return

Piece->

getString

() == GenericTrueMessage ||

3220

Piece->

getString

() == GenericFalseMessage;

3240 if

(Options.ShouldSuppressFromCXXStandardLibrary) {

3250 if

(

const auto

*MD = dyn_cast<CXXMethodDecl>(

D

)) {

3252 if

(CD->

getName

() ==

"list"

) {

3260 if

(

const auto

*MD = dyn_cast<CXXConstructorDecl>(

D

)) {

3262 if

(CD->

getName

() ==

"__independent_bits_engine"

) {

3270 const auto

*MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());

3281 if

(CD->

getName

() ==

"basic_string"

) {

3289 if

(CD->

getName

() ==

"shared_ptr"

) {

3301 while

(

Loc

.isMacroID()) {

3302 Loc

=

Loc

.getSpellingLoc();

3303 if

(

SM

.getFilename(

Loc

).ends_with(

"sys/queue.h"

)) {

3321

std::optional<CallEnter> CEnter = ProgLoc.

getAs

<

CallEnter

>();

3331 for

(

const auto

ParamDecl : parms) {

3332 const MemRegion

*ArgReg =

Call

->getArgSVal(Idx).getAsRegion();

3340

assert(ParamDecl &&

"Formal parameter has no decl?"

);

3355 SVal

BoundVal = State->getSVal(R);

3368int

NoteTag::Kind = 0;

3372

ID.AddPointer(&Tag);

3383 if

(std::optional<std::string> Msg =

T

->generateMessage(BRC, R)) {

3386 auto

Piece = std::make_shared<PathDiagnosticEventPiece>(

Loc

, *Msg);

3387

Piece->setPrunable(

T

->isPrunable());

Defines the clang::ASTContext interface.

This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...

static bool isInterestingExpr(const Expr *E, const ExplodedNode *N, const PathSensitiveBugReport *B)

static const ExplodedNode * findNodeForExpression(const ExplodedNode *N, const Expr *Inner)

Find the ExplodedNode where the lvalue (the value of 'Ex') was computed.

static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)

Display diagnostics for passing bad region as a parameter.

static const Expr * peelOffPointerArithmetic(const BinaryOperator *B)

static const Expr * tryExtractInitializerFromList(const InitListExpr *ILE, const MemRegion *R)

static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest, const ExplodedNode *N, SVal ValueAfter)

static llvm::StringLiteral WillBeUsedForACondition

static bool isFunctionMacroExpansion(SourceLocation Loc, const SourceManager &SM)

static std::shared_ptr< PathDiagnosticEventPiece > constructDebugPieceForTrackedCondition(const Expr *Cond, const ExplodedNode *N, BugReporterContext &BRC)

static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N, bool LookingForReference=true)

static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal, const ExplodedNode *RightNode, SVal RightVal)

Comparing internal representations of symbolic values (via SVal::operator==()) is a valid way to chec...

static bool potentiallyWritesIntoIvar(const Decl *Parent, const ObjCIvarDecl *Ivar)

static std::optional< const llvm::APSInt * > getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N)

static bool isVarAnInterestingCondition(const Expr *CondVarExpr, const ExplodedNode *N, const PathSensitiveBugReport *B)

static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)

Show default diagnostics for storing bad region.

static std::optional< SVal > getSValForVar(const Expr *CondVarExpr, const ExplodedNode *N)

static const Expr * peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N)

static const VarDecl * getVarDeclForExpression(const Expr *E)

static bool isTrivialCopyOrMoveCtor(const CXXConstructExpr *CE)

static StringRef getMacroName(SourceLocation Loc, BugReporterContext &BRC)

static bool isObjCPointer(const MemRegion *R)

static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context)

static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR)

Returns true if N represents the DeclStmt declaring and initializing VR.

static const ExplodedNode * getMatchingCallExitEnd(const ExplodedNode *N)

static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)

Show diagnostics for initializing or declaring a region R with a bad value.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

C Language Family Type Representation.

static bool isPointerToConst(const QualType &QT)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const LangOptions & getLangOpts() const

CFGStmtMap * getCFGStmtMap()

static bool isInStdNamespace(const Decl *D)

Stores options for the analyzer from the command line.

AnalysisDiagClients AnalysisDiagOpt

A builtin binary operation expression such as "x + y" or "x <= y".

bool isComparisonOp() const

StringRef getOpcodeStr() const

static bool isAdditiveOp(Opcode Opc)

bool isAssignmentOp() const

Represents a single basic block in a source-level CFG.

bool isInevitablySinking() const

Returns true if the block would eventually end with a sink (a noreturn node).

succ_iterator succ_begin()

Stmt * getTerminatorStmt()

const Expr * getLastCondition() const

Stmt * getTerminatorCondition(bool StripParens=true)

unsigned succ_size() const

CFGBlock * getBlock(Stmt *S)

Returns the CFGBlock the specified Stmt* appears in.

unsigned size() const

Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...

bool isLinear() const

Returns true if the CFG has no branches.

A boolean literal, per ([C++ lex.bool] Boolean literals).

Represents a call to a C++ constructor.

CXXConstructorDecl * getConstructor() const

Get the constructor that this expression will (ultimately) call.

bool isCopyOrMoveConstructor(unsigned &TypeQuals) const

Determine whether this is a copy or move constructor.

Represents a C++ struct/union/class.

Represents a point when we begin processing an inlined call.

Represents a point when we start the call exit sequence (for inlined call).

Represents a point when we finish the call exit sequence (for inlined call).

Represents a character-granular source range.

static CharSourceRange getTokenRange(SourceRange R)

DeclContext * getParent()

getParent - Returns the containing DeclContext.

A reference to a declared variable, function, enum, etc.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

const Decl * getSingleDecl() const

Decl - This represents one declaration (or definition), e.g.

bool isLocalExternDecl() const

Determine whether this is a block-scope declaration with linkage.

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

Represents a member of a struct/union/class.

A SourceLocation and its associated SourceManager.

GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...

Describes an C or C++ initializer list.

unsigned getNumInits() const

const Expr * getInit(unsigned Init) const

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)

Returns a string for the source that the range encompasses.

static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

Retrieve the name of the immediate macro expansion.

static CharSourceRange getAsCharRange(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)

Given a token range, produce a corresponding CharSourceRange that is not a token range.

static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)

Returns true if the given MacroID location points at the first token of the macro expansion.

static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)

Returns true if the given MacroID location points at the last token of the macro expansion.

It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...

bool isParentOf(const LocationContext *LC) const

const Decl * getDecl() const

LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const

const LocationContext * getParent() const

It might return null.

const StackFrameContext * getStackFrame() const

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

SourceLocation getMemberLoc() const

getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.

ValueDecl * getMemberDecl() const

Retrieve the member declaration to which this expression refers.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

ObjCBoolLiteralExpr - Objective-C Boolean Literal.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCIvarRefExpr - A reference to an ObjC instance variable.

Represents a parameter to a function.

Represents a program point after a store evaluation.

ProgramPoints can be "tagged" as representing points specific to a given analysis entity.

const ProgramPointTag * getTag() const

std::optional< T > getAs() const

Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

QualType getCanonicalType() const

bool isConstQualified() const

Determine whether this type is const-qualified.

Represents a struct/union/class.

field_range fields() const

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded,...

bool isFunctionMacroExpansion() const

This is a discriminated union of FileInfo and ExpansionInfo.

const ExpansionInfo & getExpansion() const

It represents a stack frame of the call stack (based on CallEvent).

const Stmt * getCallSite() const

bool inTopFrame() const override

const Stmt * getStmt() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

bool isBooleanType() const

bool isPointerType() const

bool isReferenceType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool isObjCObjectPointerType() const

bool isAnyPointerType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

bool hasLocalStorage() const

Returns true if a variable with function scope is a non-static local variable.

Maps string IDs to AST nodes matched by parts of a matcher.

AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.

StringRef getDescription() const

A verbose warning message that is appropriate for displaying next to the source code that introduces ...

ASTContext & getASTContext() const

ProgramStateManager & getStateManager() const

const SourceManager & getSourceManager() const

const AnalyzerOptions & getAnalyzerOptions() const

BugReporterVisitors are used to add custom diagnostics along a path.

static PathDiagnosticPieceRef getDefaultEndPath(const BugReporterContext &BRC, const ExplodedNode *N, const PathSensitiveBugReport &BR)

Generates the default final diagnostic piece.

virtual PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR)

Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...

virtual void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR)

Last function called on the visitor, no further calls to VisitNode would follow.

Represents a call to a C++ constructor.

Manages the lifetime of CallEvent objects.

CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)

Gets an outside caller given a callee context.

Represents an abstract call to a function or method along a particular path.

static bool isCallStmt(const Stmt *S)

Returns true if this is a statement is a function or method call of some kind.

PathDiagnosticPieceRef VisitTerminator(const Stmt *Term, const ExplodedNode *N, const CFGBlock *SrcBlk, const CFGBlock *DstBlk, PathSensitiveBugReport &R, BugReporterContext &BRC)

bool printValue(const Expr *CondVarExpr, raw_ostream &Out, const ExplodedNode *N, bool TookTrue, bool IsAssuming)

Tries to print the value of the given expression.

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override

Return a diagnostic piece which should be associated with the given node.

bool patternMatch(const Expr *Ex, const Expr *ParentEx, raw_ostream &Out, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, std::optional< bool > &prunable, bool IsSameFieldName)

static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece)

PathDiagnosticPieceRef VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)

PathDiagnosticPieceRef VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)

static const char * getTag()

Return the tag associated with this visitor.

PathDiagnosticPieceRef VisitNodeImpl(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR)

bool isConstrainedTrue() const

Return true if the constraint is perfectly constrained to 'true'.

bool isValid() const =delete

static bool isInterestingLValueExpr(const Expr *Ex)

Returns true if nodes for the given expression kind are always kept around.

const CFGBlock * getCFGBlock() const

const ProgramStateRef & getState() const

const Stmt * getStmtForDiagnostics() const

If the node's program point corresponds to a statement, retrieve that statement.

ProgramPoint getLocation() const

getLocation - Returns the edge associated with the given node.

ExplodedNode * getFirstSucc()

const StackFrameContext * getStackFrame() const

SVal getSVal(const Stmt *S) const

Get the value of an arbitrary expression at this node.

const LocationContext * getLocationContext() const

std::optional< T > getLocationAs() const &

ExplodedNode * getFirstPred()

unsigned succ_size() const

static std::pair< const ProgramPointTag *, const ProgramPointTag * > getEagerlyAssumeBifurcationTags()

LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override

void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override

Last function called on the visitor, no further calls to VisitNode would follow.

const FieldRegion * getFieldRegion(const FieldDecl *fd, const SubRegion *superRegion)

getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.

MemRegion - The root abstract class for all memory regions.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const

virtual bool isBoundable() const

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const

virtual bool isSubRegionOf(const MemRegion *R) const

Check if the region is a subregion of the given region.

virtual void printPretty(raw_ostream &os) const

Print the region for use in diagnostics.

const RegionTy * getAs() const

virtual bool canPrintPretty() const

Returns true if this region can be printed in a user-friendly way.

MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &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.

virtual bool wasModifiedBeforeCallExit(const ExplodedNode *CurrN, const ExplodedNode *CallExitBeginN)

virtual PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, const ObjCMethodCall &Call, const ExplodedNode *N)=0

Consume the information on the non-modifying stack frame in order to either emit a note or not.

virtual PathDiagnosticPieceRef maybeEmitNoteForCXXThis(PathSensitiveBugReport &R, const CXXConstructorCall &Call, const ExplodedNode *N)=0

Consume the information on the non-modifying stack frame in order to either emit a note or not.

bugreporter::TrackingKind TKind

virtual bool wasModifiedInFunction(const ExplodedNode *CallEnterN, const ExplodedNode *CallExitEndN)

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BR, PathSensitiveBugReport &R) final

Return a diagnostic piece which should be associated with the given node.

virtual PathDiagnosticPieceRef maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N)=0

Consume the information on the non-modifying stack frame in order to either emit a note or not.

Put a diagnostic on return statement of all inlined functions for which the region of interest Region...

The tag upon which the TagVisitor reacts.

Represents any expression that calls an Objective-C method.

static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)

Create a location for the beginning of the declaration.

FullSourceLoc asLocation() const

static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)

Create a location corresponding to the given declaration.

bool hasValidLocation() const

StringRef getString() const

void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)

Marks a symbol as interesting.

PathDiagnosticLocation getLocation() const override

The primary location of the bug report that points at the undesirable behavior in the code.

ArrayRef< SourceRange > getRanges() const override

Get the SourceRanges associated with the report.

const ExplodedNode * getErrorNode() const

bool addTrackedCondition(const ExplodedNode *Cond)

Notes that the condition of the CFGBlock associated with Cond is being tracked.

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...

void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)

Add custom or predefined bug report visitors to this report.

std::optional< bugreporter::TrackingKind > getInterestingnessKind(SymbolRef sym) const

bool isInteresting(SymbolRef sym) const

SValBuilder & getSValBuilder()

CallEventManager & getCallEventManager()

bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const

void iterBindings(ProgramStateRef state, StoreManager::BindingsHandler &F)

StoreManager & getStoreManager()

ProgramState - This class encapsulates:

Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const

Get the lvalue for a base class object reference.

SVal getSVal(const Stmt *S, const LocationContext *LCtx) const

Returns the SVal bound to the statement 'S' in the state's environment.

A Range represents the closed range [from, to].

ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs)

SVal - This represents a symbolic expression, which can be either an L-value or an R-value.

bool isZeroConstant() const

std::optional< T > getAs() const

Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.

const MemRegion * getAsRegion() const

SubRegion - A region that subsets another larger region.

LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const

bool isSubRegionOf(const MemRegion *R) const override

Check if the region is a subregion of the given region.

PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR) override

Return a diagnostic piece which should be associated with the given node.

SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N)

static const char * getTag()

Return the tag associated with this visitor.

void Profile(llvm::FoldingSetNodeID &ID) const override

SymbolicRegion - A special, "non-concrete" region.

void Profile(llvm::FoldingSetNodeID &ID) const override

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &R) override

Return a diagnostic piece which should be associated with the given node.

void Profile(llvm::FoldingSetNodeID &ID) const override

static const char * getTag()

Return the tag associated with this visitor.

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override

Return a diagnostic piece which should be associated with the given node.

When a region containing undefined value or '0' value is passed as an argument in a call,...

PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override

Return a diagnostic piece which should be associated with the given node.

const VarDecl * getDecl() const override=0

Handles expressions during the tracking.

ExpressionHandler(Tracker &ParentTracker)

Handles stores during the tracking.

StoreHandler(Tracker &ParentTracker)

PathDiagnosticPieceRef constructNote(StoreInfo SI, BugReporterContext &BRC, StringRef NodeText)

A generalized component for tracking expressions, values, and stores.

static TrackerRef create(PathSensitiveBugReport &Report)

virtual PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC, TrackingOptions Opts)

Handle the store operation and produce the note.

Tracker(PathSensitiveBugReport &Report)

virtual Result track(const Expr *E, const ExplodedNode *N, TrackingOptions Opts={})

Track expression value back to its point of origin.

Visitor that tracks expressions and values.

Value representing integer constant.

While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...

LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const

This function itself is immaterial.

const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCIvarRefExpr > objcIvarRefExpr

Matches a reference to an ObjCIvar.

const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant

Matches AST nodes that have descendant AST nodes that match the provided matcher.

SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)

Returns the results of matching Matcher on Node.

const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator > binaryOperator

Matches binary operator expressions.

internal::Matcher< Stmt > StatementMatcher

static std::string getMacroName(MacroType Macro, GtestCmp Cmp)

internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)

Matches a node if the declaration associated with that node matches the given matcher.

const internal::VariadicAllOfMatcher< Stmt > stmt

Matches statements.

const Expr * getDerefExpr(const Stmt *S)

Given that expression S represents a pointer that would be dereferenced, try to find a sub-expression...

bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})

Attempts to add visitors to track expression value back to its point of origin.

void trackStoredValue(SVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts={}, const StackFrameContext *Origin=nullptr)

Track how the value got stored into the given region and where it came from.

TrackingKind

Specifies the type of tracking for an expression.

@ Thorough

Default tracking kind – specifies that as much information should be gathered about the tracked expre...

@ Condition

Specifies that a more moderate tracking should be used for the expression value.

@ OS

Indicates that the tracking object is a descendant of a referenced-counted OSObject,...

std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef

bool Ret(InterpState &S, CodePtr &PC)

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

const FunctionProtoType * T

@ ObjCSelf

Parameter for Objective-C 'self' argument.

Describes an event when the value got stored into a memory region.

@ Assignment

The value got stored into the region during assignment: int x; x = 42;.

@ CallArgument

The value got stored into the parameter region as the result of a call.

@ BlockCapture

The value got stored into the region as block capture.

@ Initialization

The value got stored into the region during initialization: int x = 42;.

const Expr * SourceOfTheValue

The expression where the value comes from.

const ExplodedNode * StoreSite

The node where the store happened.

Kind StoreKind

The type of store operation.

SVal Value

Symbolic value that is being stored.

const MemRegion * Dest

Memory regions involved in the store operation.

Describes a tracking result with the most basic information of what was actually done (or not done).

void combineWith(const Result &Other)

Combines the current result with the given result.

bool WasInterrupted

Signifies that the tracking was interrupted at some point.

Defines a set of options altering tracking behavior.

bool EnableNullFPSuppression

Specifies whether we should employ false positive suppression (inlined defensive checks,...

TrackingKind Kind

Specifies the kind of tracking.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4