protected:
const void *getData1() const { return Data.first; }
const void *getData2() const { return Data.second; }
+ void setData2(const void *d) { Data.second = d; }
public:
/// Create a new ProgramPoint object that is the same as the original
class PostStmt : public StmtPoint {
protected:
PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
- const ProgramPointTag *tag =0)
+ const ProgramPointTag *tag = 0)
: StmtPoint(S, data, k, L, tag) {}
public:
}
};
+/// \class Represents a program point after a store evaluation.
class PostStore : public PostStmt {
public:
- PostStore(const Stmt *S, const LocationContext *L,
+ /// Construct the post store point.
+ /// \param Loc can be used to store the information about the location
+ /// used in the form it was uttered in the code.
+ PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
const ProgramPointTag *tag = 0)
- : PostStmt(S, PostStoreKind, L, tag) {}
+ : PostStmt(S, PostStoreKind, L, tag) {
+ assert(getData2() == 0);
+ setData2(Loc);
+ }
static bool classof(const ProgramPoint* Location) {
return Location->getKind() == PostStoreKind;
}
+
+ /// \brief Returns the information about the location used in the store,
+ /// how it was uttered in the code.
+ const void *getLocationValue() const {
+ return getData2();
+ }
+
};
class PostLValue : public PostStmt {
return Pred->getLocationContext()->getAnalysisDeclContext();
}
+ /// \brief If the given node corresponds to a PostStore program point, retrieve
+ /// the location region as it was uttered in the code.
+ ///
+ /// This utility can be useful for generating extensive diagnostics, for
+ /// example, for finding variables that the given symbol was assigned to.
+ static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
+ ProgramPoint L = N->getLocation();
+ if (const PostStore *PSL = dyn_cast<PostStore>(&L))
+ return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
+ return 0;
+ }
+
/// \brief Generates a new transition in the program state graph
/// (ExplodedGraph). Uses the default CheckerContext predecessor node.
///
/// evalBind - Handle the semantics of binding a value to a specific location.
/// This method is used by evalStore, VisitDeclStmt, and others.
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
- SVal location, SVal Val, bool atDeclInit = false,
- ProgramPoint::Kind PP = ProgramPoint::PostStmtKind);
+ SVal location, SVal Val, bool atDeclInit = false);
public:
// FIXME: 'tag' should be removed, and a LocationContext should be used
virtual MemRegionManager* getMemRegionManager() const = 0;
- std::string getString() const;
-
const MemSpaceRegion *getMemorySpace() const;
const MemRegion *getBaseRegion() const;
/// Compute the offset within the top level memory object.
RegionOffset getAsOffset() const;
+ /// \brief Get a string representation of a region for debug use.
+ std::string getString() const;
+
virtual void dumpToStream(raw_ostream &os) const;
void dump() const;
+ /// \brief Print the region for use in diagnostics.
+ virtual void dumpPretty(raw_ostream &os) const;
+
Kind getKind() const { return kind; }
template<typename RegionTy> const RegionTy* getAs() const;
static bool classof(const MemRegion* R) {
return R->getKind() == VarRegionKind;
}
+
+ void dumpPretty(raw_ostream &os) const;
};
/// CXXThisRegion - Represents the region for the implicit 'this' parameter
: DeclRegion(fd, sReg, FieldRegionKind) {}
public:
-
- void dumpToStream(raw_ostream &os) const;
-
const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
QualType getValueType() const {
static bool classof(const MemRegion* R) {
return R->getKind() == FieldRegionKind;
}
+
+ void dumpToStream(raw_ostream &os) const;
+ void dumpPretty(raw_ostream &os) const;
};
class ObjCIvarRegion : public DeclRegion {
return PostLoad(S, LC, tag);
case ProgramPoint::PreStoreKind:
return PreStore(S, LC, tag);
- case ProgramPoint::PostStoreKind:
- return PostStore(S, LC, tag);
case ProgramPoint::PostLValueKind:
return PostLValue(S, LC, tag);
case ProgramPoint::PostPurgeDeadSymbolsKind:
}
};
+typedef std::pair<const Stmt*, const MemRegion*> LeakInfo;
+
class MallocChecker : public Checker<check::DeadSymbols,
check::EndPath,
check::PreStmt<ReturnStmt>,
/// Find the location of the allocation for Sym on the path leading to the
/// exploded node N.
- const Stmt *getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
- CheckerContext &C) const;
+ LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
+ CheckerContext &C) const;
void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
return MallocMemAux(C, CE, TotalSize, zeroVal, state);
}
-const Stmt *
+LeakInfo
MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
CheckerContext &C) const {
const LocationContext *LeakContext = N->getLocationContext();
// Walk the ExplodedGraph backwards and find the first node that referred to
// the tracked symbol.
const ExplodedNode *AllocNode = N;
+ const MemRegion *ReferenceRegion = 0;
while (N) {
- if (!N->getState()->get<RegionState>(Sym))
+ ProgramStateRef State = N->getState();
+ if (!State->get<RegionState>(Sym))
break;
+
+ // Find the most recent expression bound to the symbol in the current
+ // context.
+ ProgramPoint L = N->getLocation();
+ if (!ReferenceRegion) {
+ const MemRegion *MR = C.getLocationRegionIfPostStore(N);
+ if (MR) {
+ SVal Val = State->getSVal(MR);
+ if (Val.getAsLocSymbol() == Sym)
+ ReferenceRegion = MR;
+ }
+ }
+
// Allocation node, is the last node in the current context in which the
// symbol was tracked.
if (N->getLocationContext() == LeakContext)
}
ProgramPoint P = AllocNode->getLocation();
- if (!isa<StmtPoint>(P))
- return 0;
+ const Stmt *AllocationStmt = 0;
+ if (isa<StmtPoint>(P))
+ AllocationStmt = cast<StmtPoint>(P).getStmt();
- return cast<StmtPoint>(P).getStmt();
+ return LeakInfo(AllocationStmt, ReferenceRegion);
}
void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
// With leaks, we want to unique them by the location where they were
// allocated, and only report a single path.
PathDiagnosticLocation LocUsedForUniqueing;
- if (const Stmt *AllocStmt = getAllocationSite(N, Sym, C))
+ const Stmt *AllocStmt = 0;
+ const MemRegion *Region = 0;
+ llvm::tie(AllocStmt, Region) = getAllocationSite(N, Sym, C);
+ if (AllocStmt)
LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt,
C.getSourceManager(), N->getLocationContext());
- BugReport *R = new BugReport(*BT_Leak,
- "Memory is never released; potential memory leak", N, LocUsedForUniqueing);
+ SmallString<200> buf;
+ llvm::raw_svector_ostream os(buf);
+ os << "Memory is never released; potential leak";
+ if (Region) {
+ os << " of memory pointed to by '";
+ Region->dumpPretty(os);
+ os <<'\'';
+ }
+
+ BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing);
R->markInteresting(Sym);
// FIXME: This is a hack to make sure the MallocBugVisitor gets to look at
// the ExplodedNode chain first, in order to mark any failed realloc symbols
/// This method is used by evalStore and (soon) VisitDeclStmt, and others.
void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
ExplodedNode *Pred,
- SVal location, SVal Val, bool atDeclInit,
- ProgramPoint::Kind PointKind) {
+ SVal location, SVal Val, bool atDeclInit) {
// Do a previsit of the bind.
ExplodedNodeSet CheckedSet;
getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
- StoreE, *this, PointKind);
+ StoreE, *this,
+ ProgramPoint::PostStmtKind);
- // TODO:AZ Remove TmpDst after NB refactoring is done.
ExplodedNodeSet TmpDst;
StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currentBuilderContext);
+ const LocationContext *LC = Pred->getLocationContext();
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
I!=E; ++I) {
- ProgramStateRef state = (*I)->getState();
+ ExplodedNode *PredI = *I;
+ ProgramStateRef state = PredI->getState();
if (atDeclInit) {
const VarRegion *VR =
state = state->bindLoc(location, Val);
}
- Bldr.generateNode(StoreE, *I, state, false, 0, PointKind);
+ const MemRegion *LocReg = 0;
+ if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location))
+ LocReg = LocRegVal->getRegion();
+
+ const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
+ Bldr.generateNode(L, PredI, state, false);
}
Dst.insert(TmpDst);
return;
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
- evalBind(Dst, StoreE, *NI, location, Val, false,
- ProgramPoint::PostStoreKind);
+ evalBind(Dst, StoreE, *NI, location, Val, false);
}
void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
os << "GlobalImmutableSpaceRegion";
}
+void MemRegion::dumpPretty(raw_ostream &os) const {
+ return;
+}
+
+void VarRegion::dumpPretty(raw_ostream &os) const {
+ os << getDecl()->getName();
+}
+
+void FieldRegion::dumpPretty(raw_ostream &os) const {
+ superRegion->dumpPretty(os);
+ os << "->" << getDecl();
+}
+
//===----------------------------------------------------------------------===//
// MemRegionManager methods.
//===----------------------------------------------------------------------===//
void f1() {
int *p = malloc(12);
- return; // expected-warning{{Memory is never released; potential memory leak}}
+ return; // expected-warning{{Memory is never released; potential leak}}
}
void f2() {
void n2af1() {
int *p = my_malloc2(12);
- return; // expected-warning{{Memory is never released; potential memory leak}}
+ return; // expected-warning{{Memory is never released; potential leak}}
}
void af1() {
int *p = my_malloc(12);
- return; // expected-warning{{Memory is never released; potential memory leak}}
+ return; // expected-warning{{Memory is never released; potential leak}}
}
void af1_b() {
- int *p = my_malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
+ int *p = my_malloc(12); // expected-warning{{Memory is never released; potential leak}}
}
void af1_c() {
static void test1() {
void *data = 0;
- my_malloc1(&data, 4); // expected-warning {{Memory is never released; potential memory leak}}
+ my_malloc1(&data, 4); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
}
static void test11() {
static void testUniqueingByallocationSiteInTopLevelFunction() {
void *data = my_malloc2(1, 4);
data = 0;
- int x = 5;// expected-warning {{Memory is never released; potential memory leak}}
- data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential memory leak}}
+ int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
+ data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
}
static void test3() {
void testThatRemoveDeadBindingsRunBeforeEachCall() {
char *v = malloc(12);
v = reshape(v);
- v = reshape(v);// expected-warning {{Memory is never released; potential memory leak}}
+ v = reshape(v);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'v'}}
}
// Test that we keep processing after 'return;'
v = malloc_wrapper_ret();
}
+// Test that we refer to the last symbol used in the leak diagnostic.
+void LeakedSymbol(int in) {
+ int *m = 0;
+ int *p;
+ p = (int*)malloc(12);
+ (*p)++;
+ m = p;
+ p = 0;
+ (*m)++;
+ in++;
+}
// CHECK: <?xml version="1.0" encoding="UTF-8"?>
// CHECK: <plist version="1.0">
// CHECK: </array>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'p'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'p'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'p'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: </dict>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'A'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'A'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'A'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: </array>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: </dict>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: </array>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'buf'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: </dict>
// CHECK: <key>depth</key><integer>0</integer>
// CHECK: <key>extended_message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'v'</string>
// CHECK: <key>message</key>
-// CHECK: <string>Memory is never released; potential memory leak</string>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'v'</string>
// CHECK: </dict>
// CHECK: </array>
-// CHECK: <key>description</key><string>Memory is never released; potential memory leak</string>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'v'</string>
// CHECK: <key>category</key><string>Memory Error</string>
// CHECK: <key>type</key><string>Memory leak</string>
// CHECK: <key>location</key>
// CHECK: <key>file</key><integer>0</integer>
// CHECK: </dict>
// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>path</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>90</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>90</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>15</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>24</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>15</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>15</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>24</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Memory is allocated</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Memory is allocated</string>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>control</string>
+// CHECK: <key>edges</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>start</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>15</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>92</integer>
+// CHECK: <key>col</key><integer>24</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>end</key>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>kind</key><string>event</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <key>ranges</key>
+// CHECK: <array>
+// CHECK: <array>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>8</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: </array>
+// CHECK: <key>depth</key><integer>0</integer>
+// CHECK: <key>extended_message</key>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string>
+// CHECK: <key>message</key>
+// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string>
+// CHECK: </dict>
+// CHECK: </array>
+// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'm'</string>
+// CHECK: <key>category</key><string>Memory Error</string>
+// CHECK: <key>type</key><string>Memory leak</string>
+// CHECK: <key>location</key>
+// CHECK: <dict>
+// CHECK: <key>line</key><integer>97</integer>
+// CHECK: <key>col</key><integer>5</integer>
+// CHECK: <key>file</key><integer>0</integer>
+// CHECK: </dict>
+// CHECK: </dict>
// CHECK: </array>
// CHECK: </dict>
// CHECK: </plist>
void f1() {
int *p = malloc(12);
- return; // expected-warning{{Memory is never released; potential memory leak}}
+ return; // expected-warning{{Memory is never released; potential leak}}
}
void f2() {
char *p = (char*)malloc(size);
if (p) {
char *q = (char*)realloc(p, sizeIn);
- char x = *q; // expected-warning {{Memory is never released; potential memory leak}}
+ char x = *q; // expected-warning {{Memory is never released; potential leak}}
}
}
}
void reallocPtrZero1() {
- char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential memory leak}}
+ char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}}
}
void reallocPtrZero2() {
char *buf = malloc(100);
buf = (char*)realloc(buf, 0x1000000);
if (!buf) {
- return;// expected-warning {{Memory is never released; potential memory leak}}
+ return;// expected-warning {{Memory is never released; potential leak}}
}
free(buf);
}
void reallocRadar6337483_2() {
char *buf = malloc(100);
char *buf2 = (char*)realloc(buf, 0x1000000);
- if (!buf2) { // expected-warning {{Memory is never released; potential memory leak}}
+ if (!buf2) { // expected-warning {{Memory is never released; potential leak}}
;
} else {
free(buf2);
char *buf = malloc(100);
char *buf2 = (char*)realloc(buf, 0x1000000);
if (!buf2) {
- return; // expected-warning {{Memory is never released; potential memory leak}}
+ return; // expected-warning {{Memory is never released; potential leak}}
} else {
free(buf2);
}
}
void reallocfPtrZero1() {
- char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential memory leak}}
+ char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential leak}}
}
void mallocEscapeMalloc() {
int *p = malloc(12);
myfoo(p);
- p = malloc(12); // expected-warning{{Memory is never released; potential memory leak}}
+ p = malloc(12); // expected-warning{{Memory is never released; potential leak}}
}
void mallocMalloc() {
int *p = malloc(12);
- p = malloc(12); // expected-warning 2 {{Memory is never released; potential memory leak}}
+ p = malloc(12); // expected-warning 2 {{Memory is never released; potential leak}}
}
void mallocFreeMalloc() {
if (p == 0)
return; // no warning
else
- return; // expected-warning {{Memory is never released; potential memory leak}}
+ return; // expected-warning {{Memory is never released; potential leak}}
}
void mallocAssignment() {
int vallocTest() {
char *mem = valloc(12);
- return 0; // expected-warning {{Memory is never released; potential memory leak}}
+ return 0; // expected-warning {{Memory is never released; potential leak}}
}
void vallocEscapeFreeUse() {
struct X *px= malloc(sizeof(struct X));
px->p = 0;
px = s2;
- return px; // expected-warning {{Memory is never released; potential memory leak}}
+ return px; // expected-warning {{Memory is never released; potential leak}}
}
struct X* RegInvalidationGiveUp1() {
int *p = malloc(12);
pp = &p;
pp++;
- return 0;// expected-warning {{Memory is never released; potential memory leak}}
+ return 0;// expected-warning {{Memory is never released; potential leak}}
}
extern void exit(int) __attribute__ ((__noreturn__));
void testStrdup(const char *s, unsigned validIndex) {
char *s2 = strdup(s);
- s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential memory leak}}
+ s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential leak}}
}
int testStrndup(const char *s, unsigned validIndex, unsigned size) {
if (s2[validIndex] != 'a')
return 0;
else
- return 1;// expected-warning {{Memory is never released; potential memory leak}}
+ return 1;// expected-warning {{Memory is never released; potential leak}}
}
void testStrdupContentIsDefined(const char *s, unsigned validIndex) {
if (p != g)
free(p);
else
- return; // expected-warning{{Memory is never released; potential memory leak}}
+ return; // expected-warning{{Memory is never released; potential leak}}
return;
}