29 #include "llvm/ADT/ImmutableMap.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringExtras.h"
35 using namespace clang;
71 RefState(
Kind k,
const Stmt *s,
unsigned family)
72 :
S(s), K(k), Family(family) {
73 assert(family != AF_None);
76 bool isAllocated()
const {
return K == Allocated; }
77 bool isAllocatedOfSizeZero()
const {
return K == AllocatedOfSizeZero; }
78 bool isReleased()
const {
return K == Released; }
79 bool isRelinquished()
const {
return K == Relinquished; }
80 bool isEscaped()
const {
return K == Escaped; }
84 const Stmt *getStmt()
const {
return S; }
87 return K == X.K &&
S == X.S && Family == X.Family;
90 static RefState getAllocated(
unsigned family,
const Stmt *s) {
91 return RefState(Allocated, s, family);
93 static RefState getAllocatedOfSizeZero(
const RefState *RS) {
94 return RefState(AllocatedOfSizeZero, RS->getStmt(),
95 RS->getAllocationFamily());
97 static RefState getReleased(
unsigned family,
const Stmt *s) {
98 return RefState(Released, s, family);
100 static RefState getRelinquished(
unsigned family,
const Stmt *s) {
101 return RefState(Relinquished, s, family);
103 static RefState getEscaped(
const RefState *RS) {
104 return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
107 void Profile(llvm::FoldingSetNodeID &
ID)
const {
110 ID.AddInteger(Family);
113 void dump(raw_ostream &OS)
const {
114 switch (static_cast<Kind>(K)) {
115 #define CASE(ID) case ID: OS << #ID; break;
117 CASE(AllocatedOfSizeZero)
124 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs()); }
128 RPToBeFreedAfterFailure,
132 RPDoNotTrackAfterFailure
144 ReallocatedSym(S),
Kind(K) {}
145 void Profile(llvm::FoldingSetNodeID &ID)
const {
147 ID.AddPointer(ReallocatedSym);
150 return ReallocatedSym == X.ReallocatedSym &&
155 typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
157 class MallocChecker :
public Checker<check::DeadSymbols,
158 check::PointerEscape,
159 check::ConstPointerEscape,
160 check::PreStmt<ReturnStmt>,
162 check::PostStmt<CallExpr>,
163 check::PostStmt<CXXNewExpr>,
164 check::PreStmt<CXXDeleteExpr>,
165 check::PostStmt<BlockExpr>,
166 check::PostObjCMessage,
172 : II_alloca(nullptr), II_malloc(nullptr), II_free(nullptr),
173 II_realloc(nullptr), II_calloc(nullptr), II_valloc(nullptr),
174 II_reallocf(nullptr), II_strndup(nullptr), II_strdup(nullptr),
175 II_kmalloc(nullptr), II_if_nameindex(nullptr),
176 II_if_freenameindex(nullptr) {}
183 CK_NewDeleteLeaksChecker,
184 CK_MismatchedDeallocatorChecker,
188 enum class MemoryOperationKind {
208 bool Assumption)
const;
209 void checkLocation(
SVal l,
bool isLoad,
const Stmt *
S,
222 const char *NL,
const char *Sep)
const override;
225 mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
226 mutable std::unique_ptr<BugType> BT_DoubleDelete;
227 mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
228 mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
229 mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
230 mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
231 mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
232 mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
233 mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
234 mutable IdentifierInfo *II_alloca, *II_malloc, *II_free, *II_realloc,
235 *II_calloc, *II_valloc, *II_reallocf, *II_strndup,
236 *II_strdup, *II_kmalloc, *II_if_nameindex,
237 *II_if_freenameindex;
238 mutable Optional<uint64_t> KernelZeroFlagVal;
249 const Expr *E)
const;
254 const Expr *DeallocExpr)
const;
257 void printExpectedDeallocName(raw_ostream &os,
AllocationFamily Family)
const;
266 MemoryOperationKind MemKind)
const;
272 const unsigned AllocationSizeArg,
277 const OwnershipAttr* Att,
300 const OwnershipAttr* Att,
305 bool &ReleasedAllocated,
306 bool ReturnsNullOnFailure =
false)
const;
308 const Expr *ParentExpr,
311 bool &ReleasedAllocated,
312 bool ReturnsNullOnFailure =
false)
const;
315 bool FreesMemOnFailure,
326 const Stmt *
S)
const;
340 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
const CallEvent *Call,
349 bool(*CheckRefState)(
const RefState*))
const;
356 bool IsALeakCheck =
false)
const;
358 const Stmt *AllocDeallocStmt,
359 bool IsALeakCheck =
false)
const;
361 bool IsALeakCheck =
false)
const;
363 static bool SummarizeValue(raw_ostream &os,
SVal V);
364 static bool SummarizeRegion(raw_ostream &os,
const MemRegion *MR);
366 const Expr *DeallocExpr)
const;
370 const Expr *DeallocExpr,
const RefState *RS,
371 SymbolRef Sym,
bool OwnershipTransferred)
const;
373 const Expr *DeallocExpr,
374 const Expr *AllocExpr =
nullptr)
const;
397 enum NotificationMode {
406 NotificationMode Mode;
414 MallocBugVisitor(
SymbolRef S,
bool isLeak =
false)
415 : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
417 ~MallocBugVisitor()
override {}
419 void Profile(llvm::FoldingSetNodeID &ID)
const override {
425 inline bool isAllocated(
const RefState *
S,
const RefState *SPrev,
428 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
429 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
430 (!SPrev || !(SPrev->isAllocated() ||
431 SPrev->isAllocatedOfSizeZero())));
434 inline bool isReleased(
const RefState *S,
const RefState *SPrev,
437 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
438 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
441 inline bool isRelinquished(
const RefState *S,
const RefState *SPrev,
444 return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
445 isa<ObjCPropertyRefExpr>(Stmt)) &&
446 (S && S->isRelinquished()) &&
447 (!SPrev || !SPrev->isRelinquished()));
450 inline bool isReallocFailedCheck(
const RefState *S,
const RefState *SPrev,
456 return ((!Stmt || !isa<CallExpr>(Stmt)) &&
457 (S && (S->isAllocated() || S->isAllocatedOfSizeZero())) &&
458 (SPrev && !(SPrev->isAllocated() ||
459 SPrev->isAllocatedOfSizeZero())));
467 std::unique_ptr<PathDiagnosticPiece>
477 return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.
getDescription(),
482 class StackHintGeneratorForReallocationFailed
485 StackHintGeneratorForReallocationFailed(
SymbolRef S, StringRef M)
488 std::string getMessageForArg(
const Expr *ArgE,
489 unsigned ArgIndex)
override {
494 llvm::raw_svector_ostream os(buf);
496 os <<
"Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
497 <<
" parameter failed";
503 return "Reallocation of returned value failed";
524 bool VisitSymbol(SymbolRef sym)
override {
525 state = state->remove<RegionState>(sym);
531 void MallocChecker::initIdentifierInfo(
ASTContext &Ctx)
const {
538 II_reallocf = &Ctx.
Idents.
get(
"reallocf");
544 II_if_nameindex = &Ctx.
Idents.
get(
"if_nameindex");
545 II_if_freenameindex = &Ctx.
Idents.
get(
"if_freenameindex");
549 if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any))
552 if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
555 if (isCMemFunction(FD, C, AF_Alloca, MemoryOperationKind::MOK_Any))
558 if (isStandardNewDelete(FD, C))
564 bool MallocChecker::isCMemFunction(
const FunctionDecl *FD,
567 MemoryOperationKind MemKind)
const {
571 bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any ||
572 MemKind == MemoryOperationKind::MOK_Free);
573 bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any ||
574 MemKind == MemoryOperationKind::MOK_Allocate);
576 if (FD->
getKind() == Decl::Function) {
578 initIdentifierInfo(C);
580 if (Family == AF_Malloc && CheckFree) {
581 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
585 if (Family == AF_Malloc && CheckAlloc) {
586 if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
587 FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
588 FunI == II_strndup || FunI == II_kmalloc)
592 if (Family == AF_IfNameIndex && CheckFree) {
593 if (FunI == II_if_freenameindex)
597 if (Family == AF_IfNameIndex && CheckAlloc) {
598 if (FunI == II_if_nameindex)
602 if (Family == AF_Alloca && CheckAlloc) {
603 if (FunI == II_alloca)
608 if (Family != AF_Malloc)
611 if (IsOptimistic && FD->
hasAttrs()) {
613 OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
614 if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
617 }
else if (OwnKind == OwnershipAttr::Returns) {
631 bool MallocChecker::isStandardNewDelete(
const FunctionDecl *FD,
637 if (Kind != OO_New && Kind != OO_Array_New &&
638 Kind != OO_Delete && Kind != OO_Array_Delete)
642 if (isa<CXXMethodDecl>(FD))
649 return II->getName().equals(
"nothrow_t");
681 if (!KernelZeroFlagVal.hasValue()) {
682 if (OS == llvm::Triple::FreeBSD)
683 KernelZeroFlagVal = 0x0100;
684 else if (OS == llvm::Triple::NetBSD)
685 KernelZeroFlagVal = 0x0002;
686 else if (OS == llvm::Triple::OpenBSD)
687 KernelZeroFlagVal = 0x0008;
688 else if (OS == llvm::Triple::Linux)
690 KernelZeroFlagVal = 0x8000;
727 std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
730 if (TrueState && !FalseState) {
732 return MallocMemAux(C, CE, CE->
getArg(0), ZeroVal, TrueState);
747 bool ReleasedAllocatedMemory =
false;
749 if (FD->
getKind() == Decl::Function) {
753 if (FunI == II_malloc) {
759 State = ProcessZeroAllocation(C, CE, 0, State);
762 performKernelMalloc(CE, C, State);
763 if (MaybeState.hasValue())
764 State = MaybeState.getValue();
768 }
else if (FunI == II_kmalloc) {
770 performKernelMalloc(CE, C, State);
771 if (MaybeState.hasValue())
772 State = MaybeState.getValue();
775 }
else if (FunI == II_valloc) {
779 State = ProcessZeroAllocation(C, CE, 0, State);
780 }
else if (FunI == II_realloc) {
781 State = ReallocMem(C, CE,
false, State);
782 State = ProcessZeroAllocation(C, CE, 1, State);
783 }
else if (FunI == II_reallocf) {
784 State = ReallocMem(C, CE,
true, State);
785 State = ProcessZeroAllocation(C, CE, 1, State);
786 }
else if (FunI == II_calloc) {
787 State = CallocMem(C, CE, State);
788 State = ProcessZeroAllocation(C, CE, 0, State);
789 State = ProcessZeroAllocation(C, CE, 1, State);
790 }
else if (FunI == II_free) {
791 State = FreeMemAux(C, CE, State, 0,
false, ReleasedAllocatedMemory);
792 }
else if (FunI == II_strdup) {
793 State = MallocUpdateRefState(C, CE, State);
794 }
else if (FunI == II_strndup) {
795 State = MallocUpdateRefState(C, CE, State);
796 }
else if (FunI == II_alloca) {
799 State = ProcessZeroAllocation(C, CE, 0, State);
809 State = ProcessZeroAllocation(C, CE, 0, State);
811 else if (K == OO_Array_New) {
814 State = ProcessZeroAllocation(C, CE, 0, State);
816 else if (K == OO_Delete || K == OO_Array_Delete)
817 State = FreeMemAux(C, CE, State, 0,
false, ReleasedAllocatedMemory);
819 llvm_unreachable(
"not a new/delete operator");
820 }
else if (FunI == II_if_nameindex) {
825 }
else if (FunI == II_if_freenameindex) {
826 State = FreeMemAux(C, CE, State, 0,
false, ReleasedAllocatedMemory);
830 if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
835 switch (I->getOwnKind()) {
836 case OwnershipAttr::Returns:
837 State = MallocMemReturnsAttr(C, CE, I, State);
839 case OwnershipAttr::Takes:
840 case OwnershipAttr::Holds:
841 State = FreeMemAttr(C, CE, I, State);
852 const unsigned AllocationSizeArg,
857 const Expr *Arg =
nullptr;
859 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
860 Arg = CE->
getArg(AllocationSizeArg);
862 else if (
const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
864 Arg = NE->getArraySize();
869 llvm_unreachable(
"not a CallExpr or CXXNewExpr");
873 Optional<DefinedSVal> DefArgVal =
885 std::tie(TrueState, FalseState) =
886 State->assume(SvalBuilder.
evalEQ(State, *DefArgVal, Zero));
888 if (TrueState && !FalseState) {
894 const RefState *RS = State->get<RegionState>(Sym);
899 if (!RS->isAllocated())
902 return TrueState->set<RegionState>(Sym,
903 RefState::getAllocatedOfSizeZero(RS));
913 while (!PointeeType.isNull()) {
914 Result = PointeeType;
932 for (
const auto *CtorParam : CtorD->
params()) {
935 if (CtorParamPointeeT.
isNull())
947 void MallocChecker::checkPostStmt(
const CXXNewExpr *NE,
954 checkUseAfterFree(Sym, C, *I);
968 State = MallocUpdateRefState(C, NE, State, NE->
isArray() ? AF_CXXNewArray
970 State = ProcessZeroAllocation(C, NE, 0, State);
977 if (!ChecksEnabled[CK_NewDeleteChecker])
985 bool ReleasedAllocated;
987 false, ReleasedAllocated);
999 if (FirstSlot ==
"dataWithBytesNoCopy" ||
1000 FirstSlot ==
"initWithBytesNoCopy" ||
1001 FirstSlot ==
"initWithCharactersNoCopy")
1011 for (
unsigned i = 1; i < S.
getNumArgs(); ++i)
1013 return !Call.getArgSVal(i).isZeroConstant();
1018 void MallocChecker::checkPostObjCMessage(
const ObjCMethodCall &Call,
1030 bool ReleasedAllocatedMemory;
1033 true, ReleasedAllocatedMemory,
1041 const OwnershipAttr *Att,
1046 if (Att->getModule() != II_malloc)
1049 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
1065 Init, State, Family);
1091 State = State->bindDefault(RetVal, Init);
1095 dyn_cast_or_null<SymbolicRegion>(RetVal.
getAsRegion());
1098 if (Optional<DefinedOrUnknownSVal> DefinedSize =
1103 svalBuilder.
evalEQ(State, Extent, *DefinedSize);
1105 State = State->assume(extentMatchesSize,
true);
1109 return MallocUpdateRefState(C, CE, State, Family);
1130 return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
1135 const OwnershipAttr *Att,
1140 if (Att->getModule() != II_malloc)
1143 bool ReleasedAllocated =
false;
1145 for (
const auto &Arg : Att->args()) {
1147 Att->getOwnKind() == OwnershipAttr::Holds,
1160 bool &ReleasedAllocated,
1161 bool ReturnsNullOnFailure)
const {
1168 return FreeMemAux(C, CE->
getArg(Num), CE,
State, Hold,
1169 ReleasedAllocated, ReturnsNullOnFailure);
1176 const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
1178 assert(*Ret &&
"We should not store the null return symbol");
1181 RetStatusSymbol = *Ret;
1188 const Stmt *S)
const {
1192 if (
const CallExpr *CE = dyn_cast<CallExpr>(S)) {
1200 if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any))
1203 if (isStandardNewDelete(FD, Ctx)) {
1205 if (Kind == OO_New || Kind == OO_Delete)
1207 else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
1208 return AF_CXXNewArray;
1211 if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
1212 return AF_IfNameIndex;
1214 if (isCMemFunction(FD, Ctx, AF_Alloca, MemoryOperationKind::MOK_Any))
1220 if (
const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
1221 return NE->
isArray() ? AF_CXXNewArray : AF_CXXNew;
1224 return DE->
isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
1226 if (isa<ObjCMessageExpr>(S))
1232 bool MallocChecker::printAllocDeallocName(raw_ostream &os,
CheckerContext &C,
1233 const Expr *E)
const {
1234 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1241 if (!FD->isOverloadedOperator())
1247 if (Msg->isInstanceMessage())
1251 Msg->getSelector().
print(os);
1255 if (
const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1272 void MallocChecker::printExpectedAllocName(raw_ostream &os,
CheckerContext &C,
1273 const Expr *E)
const {
1277 case AF_Malloc: os <<
"malloc()";
return;
1278 case AF_CXXNew: os <<
"'new'";
return;
1279 case AF_CXXNewArray: os <<
"'new[]'";
return;
1280 case AF_IfNameIndex: os <<
"'if_nameindex()'";
return;
1282 case AF_None: llvm_unreachable(
"not a deallocation expression");
1286 void MallocChecker::printExpectedDeallocName(raw_ostream &os,
1289 case AF_Malloc: os <<
"free()";
return;
1290 case AF_CXXNew: os <<
"'delete'";
return;
1291 case AF_CXXNewArray: os <<
"'delete[]'";
return;
1292 case AF_IfNameIndex: os <<
"'if_freenameindex()'";
return;
1294 case AF_None: llvm_unreachable(
"suspicious argument");
1299 const Expr *ArgExpr,
1300 const Expr *ParentExpr,
1303 bool &ReleasedAllocated,
1304 bool ReturnsNullOnFailure)
const {
1320 std::tie(notNullState, nullState) = State->assume(location);
1321 if (nullState && !notNullState)
1334 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1341 if (isa<BlockDataRegion>(R)) {
1342 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1350 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1359 if (isa<AllocaRegion>(R))
1360 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1362 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1374 const RefState *RsBase = State->get<RegionState>(SymBase);
1375 SymbolRef PreviousRetStatusSymbol =
nullptr;
1380 if (RsBase->getAllocationFamily() == AF_Alloca) {
1381 ReportFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1386 if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
1388 ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1389 SymBase, PreviousRetStatusSymbol);
1394 }
else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
1395 RsBase->isEscaped()) {
1398 bool DeallocMatchesAlloc =
1399 RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1400 if (!DeallocMatchesAlloc) {
1401 ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
1402 ParentExpr, RsBase, SymBase, Hold);
1412 const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
1413 ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1420 ReleasedAllocated = (RsBase !=
nullptr) && (RsBase->isAllocated() ||
1421 RsBase->isAllocatedOfSizeZero());
1424 State = State->remove<FreeReturnValue>(SymBase);
1428 if (ReturnsNullOnFailure) {
1431 if (RetStatusSymbol) {
1433 State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
1438 : getAllocationFamily(C, ParentExpr);
1441 return State->set<RegionState>(SymBase,
1442 RefState::getRelinquished(Family,
1445 return State->set<RegionState>(SymBase,
1446 RefState::getReleased(Family, ParentExpr));
1449 Optional<MallocChecker::CheckKind>
1451 bool IsALeakCheck)
const {
1455 case AF_IfNameIndex: {
1456 if (ChecksEnabled[CK_MallocChecker])
1457 return CK_MallocChecker;
1459 return Optional<MallocChecker::CheckKind>();
1462 case AF_CXXNewArray: {
1464 if (ChecksEnabled[CK_NewDeleteLeaksChecker])
1465 return CK_NewDeleteLeaksChecker;
1468 if (ChecksEnabled[CK_NewDeleteChecker])
1469 return CK_NewDeleteChecker;
1471 return Optional<MallocChecker::CheckKind>();
1474 llvm_unreachable(
"no family");
1477 llvm_unreachable(
"unhandled family");
1480 Optional<MallocChecker::CheckKind>
1482 const Stmt *AllocDeallocStmt,
1483 bool IsALeakCheck)
const {
1484 return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt),
1488 Optional<MallocChecker::CheckKind>
1490 bool IsALeakCheck)
const {
1491 const RefState *RS = C.
getState()->get<RegionState>(Sym);
1493 return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
1496 bool MallocChecker::SummarizeValue(raw_ostream &os,
SVal V) {
1498 os <<
"an integer (" << IntVal->getValue() <<
")";
1500 os <<
"a constant address (" << ConstAddr->getValue() <<
")";
1502 os <<
"the address of the label '" << Label->getLabel()->getName() <<
"'";
1509 bool MallocChecker::SummarizeRegion(raw_ostream &os,
1513 const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
1515 os <<
"the address of the function '" << *FD <<
'\'';
1517 os <<
"the address of a function";
1530 if (isa<StackLocalsSpaceRegion>(MS)) {
1539 os <<
"the address of the local variable '" << VD->
getName() <<
"'";
1541 os <<
"the address of a local stack variable";
1545 if (isa<StackArgumentsSpaceRegion>(MS)) {
1554 os <<
"the address of the parameter '" << VD->
getName() <<
"'";
1556 os <<
"the address of a parameter";
1560 if (isa<GlobalsSpaceRegion>(MS)) {
1569 if (VD->isStaticLocal())
1570 os <<
"the address of the static variable '" << VD->
getName() <<
"'";
1572 os <<
"the address of the global variable '" << VD->getName() <<
"'";
1574 os <<
"the address of a global variable";
1585 const Expr *DeallocExpr)
const {
1587 if (!ChecksEnabled[CK_MallocChecker] &&
1588 !ChecksEnabled[CK_NewDeleteChecker])
1591 Optional<MallocChecker::CheckKind> CheckKind =
1592 getCheckIfTracked(C, DeallocExpr);
1593 if (!CheckKind.hasValue())
1597 if (!BT_BadFree[*CheckKind])
1598 BT_BadFree[*CheckKind].reset(
1599 new BugType(CheckNames[*CheckKind],
"Bad free",
"Memory Error"));
1602 llvm::raw_svector_ostream os(buf);
1605 while (
const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1606 MR = ER->getSuperRegion();
1608 os <<
"Argument to ";
1609 if (!printAllocDeallocName(os, C, DeallocExpr))
1610 os <<
"deallocator";
1613 bool Summarized = MR ? SummarizeRegion(os, MR)
1614 : SummarizeValue(os, ArgVal);
1616 os <<
", which is not memory allocated by ";
1618 os <<
"not memory allocated by ";
1620 printExpectedAllocName(os, C, DeallocExpr);
1622 auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], os.str(), N);
1623 R->markInteresting(MR);
1632 Optional<MallocChecker::CheckKind> CheckKind;
1634 if (ChecksEnabled[CK_MallocChecker])
1635 CheckKind = CK_MallocChecker;
1636 else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
1637 CheckKind = CK_MismatchedDeallocatorChecker;
1642 if (!BT_FreeAlloca[*CheckKind])
1643 BT_FreeAlloca[*CheckKind].reset(
1644 new BugType(CheckNames[*CheckKind],
"Free alloca()",
"Memory Error"));
1646 auto R = llvm::make_unique<BugReport>(
1647 *BT_FreeAlloca[*CheckKind],
1648 "Memory allocated by alloca() should not be deallocated", N);
1657 const Expr *DeallocExpr,
1660 bool OwnershipTransferred)
const {
1662 if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
1666 if (!BT_MismatchedDealloc)
1667 BT_MismatchedDealloc.reset(
1668 new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
1669 "Bad deallocator",
"Memory Error"));
1672 llvm::raw_svector_ostream os(buf);
1674 const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1676 llvm::raw_svector_ostream AllocOs(AllocBuf);
1678 llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1680 if (OwnershipTransferred) {
1681 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1682 os << DeallocOs.str() <<
" cannot";
1686 os <<
" take ownership of memory";
1688 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1689 os <<
" allocated by " << AllocOs.str();
1692 if (printAllocDeallocName(AllocOs, C, AllocExpr))
1693 os <<
" allocated by " << AllocOs.str();
1695 os <<
" should be deallocated by ";
1696 printExpectedDeallocName(os, RS->getAllocationFamily());
1698 if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1699 os <<
", not " << DeallocOs.str();
1702 auto R = llvm::make_unique<BugReport>(*BT_MismatchedDealloc, os.str(), N);
1703 R->markInteresting(Sym);
1705 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1712 const Expr *AllocExpr)
const {
1715 if (!ChecksEnabled[CK_MallocChecker] &&
1716 !ChecksEnabled[CK_NewDeleteChecker])
1719 Optional<MallocChecker::CheckKind> CheckKind =
1720 getCheckIfTracked(C, AllocExpr);
1721 if (!CheckKind.hasValue())
1728 if (!BT_OffsetFree[*CheckKind])
1729 BT_OffsetFree[*CheckKind].reset(
1730 new BugType(CheckNames[*CheckKind],
"Offset free",
"Memory Error"));
1733 llvm::raw_svector_ostream os(buf);
1735 llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
1738 assert(MR &&
"Only MemRegion based symbols can have offset free errors");
1744 "Only symbols with a valid offset can have offset free errors");
1748 os <<
"Argument to ";
1749 if (!printAllocDeallocName(os, C, DeallocExpr))
1750 os <<
"deallocator";
1751 os <<
" is offset by "
1754 << ((abs(offsetBytes) > 1) ?
"bytes" :
"byte")
1755 <<
" from the start of ";
1756 if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1757 os <<
"memory allocated by " << AllocNameOs.str();
1759 os <<
"allocated memory";
1761 auto R = llvm::make_unique<BugReport>(*BT_OffsetFree[*CheckKind], os.str(), N);
1770 if (!ChecksEnabled[CK_MallocChecker] &&
1771 !ChecksEnabled[CK_NewDeleteChecker])
1774 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1775 if (!CheckKind.hasValue())
1779 if (!BT_UseFree[*CheckKind])
1780 BT_UseFree[*CheckKind].reset(
new BugType(
1781 CheckNames[*CheckKind],
"Use-after-free",
"Memory Error"));
1783 auto R = llvm::make_unique<BugReport>(*BT_UseFree[*CheckKind],
1784 "Use of memory after it is freed", N);
1786 R->markInteresting(Sym);
1788 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1797 if (!ChecksEnabled[CK_MallocChecker] &&
1798 !ChecksEnabled[CK_NewDeleteChecker])
1801 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1802 if (!CheckKind.hasValue())
1806 if (!BT_DoubleFree[*CheckKind])
1807 BT_DoubleFree[*CheckKind].reset(
1808 new BugType(CheckNames[*CheckKind],
"Double free",
"Memory Error"));
1810 auto R = llvm::make_unique<BugReport>(
1811 *BT_DoubleFree[*CheckKind],
1812 (Released ?
"Attempt to free released memory"
1813 :
"Attempt to free non-owned memory"),
1816 R->markInteresting(Sym);
1818 R->markInteresting(PrevSym);
1819 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1826 if (!ChecksEnabled[CK_NewDeleteChecker])
1829 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1830 if (!CheckKind.hasValue())
1834 if (!BT_DoubleDelete)
1835 BT_DoubleDelete.reset(
new BugType(CheckNames[CK_NewDeleteChecker],
1836 "Double delete",
"Memory Error"));
1838 auto R = llvm::make_unique<BugReport>(
1839 *BT_DoubleDelete,
"Attempt to delete released memory", N);
1841 R->markInteresting(Sym);
1842 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1851 if (!ChecksEnabled[CK_MallocChecker] &&
1852 !ChecksEnabled[CK_NewDeleteChecker])
1855 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1857 if (!CheckKind.hasValue())
1861 if (!BT_UseZerroAllocated[*CheckKind])
1862 BT_UseZerroAllocated[*CheckKind].reset(
new BugType(
1863 CheckNames[*CheckKind],
"Use of zero allocated",
"Memory Error"));
1865 auto R = llvm::make_unique<BugReport>(*BT_UseZerroAllocated[*CheckKind],
1866 "Use of zero-allocated memory", N);
1870 R->markInteresting(Sym);
1871 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1889 SVal Arg0Val = State->getSVal(arg0Expr, LCtx);
1897 svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull());
1905 SVal Arg1ValG = State->getSVal(Arg1, LCtx);
1912 svalBuilder.evalEQ(State, Arg1Val,
1913 svalBuilder.makeIntValWithPtrWidth(0,
false));
1916 std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
1918 std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
1921 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
1922 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
1926 if ( PrtIsNull && !SizeIsZero) {
1932 if (PrtIsNull && SizeIsZero)
1938 SVal RetVal = State->getSVal(CE, LCtx);
1940 if (!FromPtr || !ToPtr)
1943 bool ReleasedAllocated =
false;
1948 false, ReleasedAllocated)){
1958 FreeMemAux(C, CE, State, 0,
false, ReleasedAllocated)) {
1967 Kind = RPIsFreeOnFailure;
1968 else if (!ReleasedAllocated)
1969 Kind = RPDoNotTrackAfterFailure;
1973 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
1974 ReallocPair(FromPtr, Kind));
1977 return stateRealloc;
1992 SVal count = State->getSVal(CE->
getArg(0), LCtx);
1993 SVal elementSize = State->getSVal(CE->
getArg(1), LCtx);
1998 return MallocMemAux(C, CE, TotalSize, zeroVal, State);
2008 const MemRegion *ReferenceRegion =
nullptr;
2012 if (!State->get<RegionState>(Sym))
2017 if (!ReferenceRegion) {
2019 SVal Val = State->getSVal(MR);
2026 ReferenceRegion = MR;
2034 if (NContext == LeakContext ||
2040 return LeakInfo(AllocNode, ReferenceRegion);
2046 if (!ChecksEnabled[CK_MallocChecker] &&
2047 !ChecksEnabled[CK_NewDeleteLeaksChecker])
2050 const RefState *RS = C.
getState()->get<RegionState>(Sym);
2051 assert(RS &&
"cannot leak an untracked symbol");
2054 if (Family == AF_Alloca)
2057 Optional<MallocChecker::CheckKind>
2058 CheckKind = getCheckIfTracked(Family,
true);
2060 if (!CheckKind.hasValue())
2064 if (!BT_Leak[*CheckKind]) {
2065 BT_Leak[*CheckKind].reset(
2066 new BugType(CheckNames[*CheckKind],
"Memory leak",
"Memory Error"));
2072 BT_Leak[*CheckKind]->setSuppressOnSink(
true);
2081 std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
2084 const Stmt *AllocationStmt =
nullptr;
2086 AllocationStmt = Exit->getCalleeContext()->getCallSite();
2088 AllocationStmt = SP->getStmt();
2095 llvm::raw_svector_ostream os(buf);
2097 os <<
"Potential leak of memory pointed to by ";
2100 os <<
"Potential memory leak";
2103 auto R = llvm::make_unique<BugReport>(
2104 *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2106 R->markInteresting(Sym);
2107 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym,
true));
2111 void MallocChecker::checkDeadSymbols(
SymbolReaper &SymReaper,
2118 RegionStateTy RS = state->get<RegionState>();
2119 RegionStateTy::Factory &F = state->get_context<RegionState>();
2122 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2123 if (SymReaper.
isDead(I->first)) {
2124 if (I->second.isAllocated() || I->second.isAllocatedOfSizeZero())
2125 Errors.push_back(I->first);
2127 RS = F.remove(RS, I->first);
2133 ReallocPairsTy RP = state->get<ReallocPairs>();
2134 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2135 if (SymReaper.
isDead(I->first) ||
2136 SymReaper.
isDead(I->second.ReallocatedSym)) {
2137 state = state->remove<ReallocPairs>(I->first);
2142 FreeReturnValueTy FR = state->get<FreeReturnValue>();
2143 for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
2144 if (SymReaper.
isDead(I->first) ||
2145 SymReaper.
isDead(I->second)) {
2146 state = state->remove<FreeReturnValue>(I->first);
2152 if (!Errors.empty()) {
2156 I = Errors.begin(), E = Errors.end(); I != E; ++I) {
2157 reportLeak(*I, N, C);
2164 void MallocChecker::checkPreCall(
const CallEvent &Call,
2168 SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2169 if (!Sym || checkDoubleDelete(Sym, C))
2180 if (ChecksEnabled[CK_MallocChecker] &&
2181 (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
2182 isCMemFunction(FD, Ctx, AF_IfNameIndex,
2183 MemoryOperationKind::MOK_Free)))
2186 if (ChecksEnabled[CK_NewDeleteChecker] &&
2187 isStandardNewDelete(FD, Ctx))
2193 SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2194 if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
2199 for (
unsigned I = 0, E = Call.
getNumArgs(); I != E; ++I) {
2205 if (checkUseAfterFree(Sym, C, Call.
getArgExpr(I)))
2225 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
2228 Sym = BMR->getSymbol();
2232 checkUseAfterFree(Sym, C, E);
2238 void MallocChecker::checkPostStmt(
const BlockExpr *BE,
2248 cast<BlockDataRegion>(state->getSVal(BE,
2261 for ( ; I != E; ++I) {
2262 const VarRegion *VR = I.getCapturedRegion();
2266 Regions.push_back(VR);
2270 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2271 Regions.data() + Regions.size()).getState();
2277 const RefState *RS = C.
getState()->get<RegionState>(Sym);
2278 return (RS && RS->isReleased());
2282 const Stmt *S)
const {
2284 if (isReleased(Sym, C)) {
2285 ReportUseAfterFree(C, S->getSourceRange(), Sym);
2293 const Stmt *S)
const {
2295 const RefState *RS = C.
getState()->get<RegionState>(Sym);
2297 if (RS && RS->isAllocatedOfSizeZero())
2298 ReportUseZeroAllocated(C, RS->getStmt()->getSourceRange(), Sym);
2303 if (isReleased(Sym, C)) {
2304 ReportDoubleDelete(C, Sym);
2311 void MallocChecker::checkLocation(
SVal l,
bool isLoad,
const Stmt *S,
2315 checkUseAfterFree(Sym, C, S);
2316 checkUseZeroAllocated(Sym, C, S);
2324 bool Assumption)
const {
2325 RegionStateTy RS = state->get<RegionState>();
2326 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2331 state = state->remove<RegionState>(I.getKey());
2336 ReallocPairsTy RP = state->get<ReallocPairs>();
2337 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2344 SymbolRef ReallocSym = I.getData().ReallocatedSym;
2345 if (
const RefState *RS = state->get<RegionState>(ReallocSym)) {
2346 if (RS->isReleased()) {
2347 if (I.getData().Kind == RPToBeFreedAfterFailure)
2348 state = state->set<RegionState>(ReallocSym,
2349 RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
2350 else if (I.getData().Kind == RPDoNotTrackAfterFailure)
2351 state = state->remove<RegionState>(ReallocSym);
2353 assert(I.getData().Kind == RPIsFreeOnFailure);
2356 state = state->remove<ReallocPairs>(I.getKey());
2362 bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
2367 EscapingSymbol =
nullptr;
2373 if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
2377 if (
const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
2393 return *FreeWhenDone;
2399 StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
2400 if (FirstSlot.endswith(
"NoCopy"))
2407 if (FirstSlot.startswith(
"addPointer") ||
2408 FirstSlot.startswith(
"insertPointer") ||
2409 FirstSlot.startswith(
"replacePointer") ||
2410 FirstSlot.equals(
"valueWithPointer")) {
2417 if (Msg->getMethodFamily() ==
OMF_init) {
2418 EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2428 const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
2432 ASTContext &ASTC = State->getStateManager().getContext();
2436 if (isMemFunction(FD, ASTC))
2447 StringRef FName = II->
getName();
2451 if (FName.endswith(
"NoCopy")) {
2455 for (
unsigned i = 1; i < Call->
getNumArgs(); ++i) {
2457 if (
const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
2458 StringRef DeallocatorName = DE->getFoundDecl()->getName();
2459 if (DeallocatorName ==
"kCFAllocatorNull")
2470 if (FName ==
"funopen")
2477 if (FName ==
"setbuf" || FName ==
"setbuffer" ||
2478 FName ==
"setlinebuf" || FName ==
"setvbuf") {
2481 if (
const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
2482 if (
const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
2483 if (D->getCanonicalDecl()->getName().find(
"std") != StringRef::npos)
2493 if (FName ==
"CGBitmapContextCreate" ||
2494 FName ==
"CGBitmapContextCreateWithData" ||
2495 FName ==
"CVPixelBufferCreateWithBytes" ||
2496 FName ==
"CVPixelBufferCreateWithPlanarBytes" ||
2497 FName ==
"OSAtomicEnqueue") {
2518 return (RS->getAllocationFamily() == AF_CXXNewArray ||
2519 RS->getAllocationFamily() == AF_CXXNew);
2526 return checkPointerEscapeAux(State, Escaped, Call, Kind, &
retTrue);
2533 return checkPointerEscapeAux(State, Escaped, Call, Kind,
2541 bool(*CheckRefState)(
const RefState*))
const {
2546 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2552 for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
2557 if (EscapingSymbol && EscapingSymbol != sym)
2560 if (
const RefState *RS = State->get<RegionState>(sym)) {
2561 if ((RS->isAllocated() || RS->isAllocatedOfSizeZero()) &&
2562 CheckRefState(RS)) {
2563 State = State->remove<RegionState>(sym);
2564 State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2573 ReallocPairsTy currMap = currState->get<ReallocPairs>();
2574 ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
2576 for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
2579 if (!currMap.lookup(sym))
2587 MallocChecker::MallocBugVisitor::VisitNode(
const ExplodedNode *N,
2594 const RefState *RS = state->get<RegionState>(Sym);
2595 const RefState *RSPrev = statePrev->get<RegionState>(Sym);
2599 const Stmt *S =
nullptr;
2600 const char *Msg =
nullptr;
2608 S = Exit->getCalleeContext()->getCallSite();
2609 }
else if (Optional<BlockEdge> Edge = ProgLoc.
getAs<
BlockEdge>()) {
2612 S = Edge->getSrc()->getTerminator();
2622 if (Mode == Normal) {
2623 if (isAllocated(RS, RSPrev, S)) {
2624 Msg =
"Memory is allocated";
2626 "Returned allocated memory");
2627 }
else if (isReleased(RS, RSPrev, S)) {
2628 Msg =
"Memory is released";
2630 "Returning; memory was released");
2631 }
else if (isRelinquished(RS, RSPrev, S)) {
2632 Msg =
"Memory ownership is transferred";
2634 }
else if (isReallocFailedCheck(RS, RSPrev, S)) {
2635 Mode = ReallocationFailed;
2636 Msg =
"Reallocation failed";
2637 StackHint =
new StackHintGeneratorForReallocationFailed(Sym,
2638 "Reallocation failed");
2642 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
2643 "We only support one failed realloc at a time.");
2645 FailedReallocSymbol = sym;
2650 }
else if (Mode == ReallocationFailed) {
2651 assert(FailedReallocSymbol &&
"No symbol to look for.");
2654 if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
2656 Msg =
"Attempt to reallocate memory";
2658 "Returned reallocated memory");
2659 FailedReallocSymbol =
nullptr;
2674 void MallocChecker::printState(raw_ostream &Out,
ProgramStateRef State,
2675 const char *NL,
const char *Sep)
const {
2677 RegionStateTy RS = State->get<RegionState>();
2679 if (!RS.isEmpty()) {
2680 Out << Sep <<
"MallocChecker :" << NL;
2681 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2682 const RefState *RefS = State->get<RegionState>(I.getKey());
2684 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2685 if (!CheckKind.hasValue())
2686 CheckKind = getCheckIfTracked(Family,
true);
2688 I.getKey()->dumpToStream(Out);
2690 I.getData().dump(Out);
2691 if (CheckKind.hasValue())
2692 Out <<
" (" << CheckNames[*CheckKind].getName() <<
")";
2702 "Optimistic",
false, checker);
2703 checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] =
true;
2704 checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
2708 if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
2709 checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] =
true;
2712 #define REGISTER_CHECKER(name) \
2713 void ento::register##name(CheckerManager &mgr) { \
2714 registerCStringCheckerBasic(mgr); \
2715 MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \
2716 checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption( \
2717 "Optimistic", false, checker); \
2718 checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
2719 checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
StringRef getName() const
Smart pointer class that efficiently represents Objective-C method names.
MemRegion - The root abstract class for all memory regions.
bool isInSystemHeader() const
Returns true if the callee is known to be from a system header.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool hasDeadSymbols() const
bool operator==(CanQual< T > x, CanQual< U > y)
IdentifierInfo * getIdentifier() const
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
A helper class which wraps a boolean value set to false by default.
virtual bool argumentsMayEscape() const
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
const StackFrameContext * getStackFrame() const
Defines the SourceManager interface.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph). Uses the default CheckerContex...
const RegionTy * getAs() const
Constructs a Stack hint for the given symbol.
Represents a call to a C++ constructor.
SymbolRef getLocSymbolInBase() const
Get the symbol in the SVal or its base region.
Represents a C++ constructor within a class.
Value representing integer constant.
referenced_vars_iterator referenced_vars_begin() const
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
const MemRegion * getBaseRegion() const
referenced_vars_iterator referenced_vars_end() const
Symbolic value. These values used to capture symbolic execution of the program.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym)
const MemSpaceRegion * getMemorySpace() const
static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call)
MemRegionManager & getRegionManager()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const FunctionDecl * getCalleeDecl(const CallExpr *CE) const
Get the declaration of the called function (path-sensitive).
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef. Otherwise return 0...
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent)
Add artificial symbol dependency.
const VarDecl * getDecl() const
static bool isLocType(QualType T)
void registerCStringCheckerBasic(CheckerManager &Mgr)
Register the checker which evaluates CString API calls.
Represents any expression that calls an Objective-C method.
const TargetInfo & getTargetInfo() const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
SymbolRef getSymbol() const
bool isUnknownOrUndef() const
bool isParentOf(const LocationContext *LC) const
Expr * IgnoreParenCasts() LLVM_READONLY
bool isVariadic() const
Whether this function is variadic.
StringRef getDescription() const
Represent a region's offset within the top level base region.
static bool didPreviousFreeFail(ProgramStateRef State, SymbolRef Sym, SymbolRef &RetStatusSymbol)
arg_iterator placement_arg_end()
const MemRegion * getSuperRegion() const
const LocationContext * getLocationContext() const
FunctionDecl * getOperatorDelete() const
ExplodedNode * generateSink(ProgramStateRef State=nullptr, ExplodedNode *Pred=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a sink node. Generating a sink stops exploration of the given path.
Represents a non-static C++ member function call, no matter how it is written.
const MemRegion * StripCasts(bool StripBaseCasts=true) const
ID
Defines the set of possible language-specific address spaces.
QualType getPointeeType() const
bool isDead(SymbolRef sym) const
Returns whether or not a symbol has been confirmed dead.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument. May be null if this expression does not appe...
const ProgramStateRef & getState() const
StringRef getName() const
Return the actual identifier string.
const ProgramStateRef & getState() const
unsigned getNumArgs() const
CheckName getCurrentCheckName() const
Represents an implicit call to a C++ destructor.
DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override
getExtent - Returns the size of the region in bytes.
static bool retTrue(const RefState *RS)
ParentMap & getParentMap() const
bool hasSymbolicOffset() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
The pointer has been passed to a function call directly.
Represents a call to any sort of function that might have a FunctionDecl.
const ParmVarDecl * getParamDecl(unsigned i) const
SymbolManager & getSymbolManager()
QualType getAllocatedType() const
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
An expression that sends a message to the given Objective-C object or class.
const IdentifierInfo * getBaseTypeIdentifier() const
Retrieves a pointer to the name of the base type.
void markInteresting(SymbolRef sym)
The result type of a method or function.
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
bool isConsumedExpr(Expr *E) const
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
CHECKER * registerChecker()
Used to register checkers.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
unsigned getNumParams() const
const StackFrameContext * getCurrentStackFrame() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
ASTContext & getContext()
static bool checkIfNewOrNewArrayFamily(const RefState *RS)
Selector getSelector() const
const Decl * getDecl() const
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
A class responsible for cleaning up unused symbols.
static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, ProgramStateRef prevState)
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
REGISTER_MAP_WITH_PROGRAMSTATE(AllocatedData, SymbolRef, MacOSKeychainAPIChecker::AllocationState) static bool isEnclosingFunctionParam(const Expr *E)
const BlockDecl * getBlockDecl() const
static bool treatUnusedNewEscaped(const CXXNewExpr *NE)
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
ASTContext & getASTContext()
Represents a delete expression for memory deallocation and destructor calls, e.g. "delete[] pArray"...
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
static QualType getDeepPointeeType(QualType T)
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
unsigned getNumPlacementArgs() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const MemRegion * getAsRegion() const
const Expr * getRetValue() const
bool isConstrainedTrue() const
Return true if the constraint is perfectly constrained to 'true'.
unsigned getNumArgs() const
Represents an abstract call to a function or method along a particular path.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
AnalyzerOptions & getAnalyzerOptions()
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
FunctionDecl * getOperatorNew() const
#define REGISTER_CHECKER(name)
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
int64_t getOffset() const
static Optional< bool > getFreeWhenDoneArg(const ObjCMethodCall &Call)
CXXConstructorDecl * getConstructor() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
arg_iterator placement_arg_begin()
const CXXConstructExpr * getConstructExpr() const
Returns the CXXConstructExpr from this new-expression, or null.
const Expr * getArgExpr(unsigned Index) const override
DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs, DefinedOrUnknownSVal rhs)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
pred_iterator pred_begin()
SourceManager & getSourceManager()
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef. Otherwise, return 0.
SValBuilder & getSValBuilder()
Defines the clang::TargetInfo interface.
ElementRegin is used to represent both array elements and casts.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static const MemRegion * getLocationRegionIfPostStore(const ExplodedNode *N)
If the given node corresponds to a PostStore program point, retrieve the location region as it was ut...
A trivial tuple used to represent a source range.
bool hasNonZeroCallbackArg() const
Returns true if any of the arguments appear to represent callbacks.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
virtual const ObjCMessageExpr * getOriginExpr() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SourceManager & getSourceManager()
const LocationContext * getLocationContext() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
OverloadedOperatorKind getOverloadedOperator() const