[analyzer] Tighten up the realloc() failure path note generation...make sure we get the right realloc()!
llvm-svn: 153370
This commit is contained in:
parent
43a9af7352
commit
21ff76e916
|
@ -201,16 +201,22 @@ private:
|
||||||
protected:
|
protected:
|
||||||
enum NotificationMode {
|
enum NotificationMode {
|
||||||
Normal,
|
Normal,
|
||||||
Complete,
|
|
||||||
ReallocationFailed
|
ReallocationFailed
|
||||||
};
|
};
|
||||||
|
|
||||||
// The allocated region symbol tracked by the main analysis.
|
// The allocated region symbol tracked by the main analysis.
|
||||||
SymbolRef Sym;
|
SymbolRef Sym;
|
||||||
NotificationMode Mode;
|
|
||||||
|
|
||||||
public:
|
// The mode we are in, i.e. what kind of diagnostics will be emitted.
|
||||||
MallocBugVisitor(SymbolRef S) : Sym(S), Mode(Normal) {}
|
NotificationMode Mode;
|
||||||
|
|
||||||
|
// A symbol from when the primary region should have been reallocated.
|
||||||
|
SymbolRef FailedReallocSymbol;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MallocBugVisitor(SymbolRef S)
|
||||||
|
: Sym(S), Mode(Normal), FailedReallocSymbol(0) {}
|
||||||
|
|
||||||
virtual ~MallocBugVisitor() {}
|
virtual ~MallocBugVisitor() {}
|
||||||
|
|
||||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||||
|
@ -1390,30 +1396,33 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
|
||||||
StackHint = new StackHintGeneratorForReallocationFailed(Sym,
|
StackHint = new StackHintGeneratorForReallocationFailed(Sym,
|
||||||
"Reallocation failed");
|
"Reallocation failed");
|
||||||
|
|
||||||
if (SymbolRef sym = findFailedReallocSymbol(state, statePrev))
|
if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
|
||||||
|
// Is it possible to fail two reallocs WITHOUT testing in between?
|
||||||
|
assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
|
||||||
|
"We only support one failed realloc at a time.");
|
||||||
BR.markInteresting(sym);
|
BR.markInteresting(sym);
|
||||||
|
FailedReallocSymbol = sym;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are in a special mode if a reallocation failed later in the path.
|
// We are in a special mode if a reallocation failed later in the path.
|
||||||
} else if (Mode == ReallocationFailed) {
|
} else if (Mode == ReallocationFailed) {
|
||||||
// Generate a special diagnostic for the first realloc we find.
|
assert(FailedReallocSymbol && "No symbol to look for.");
|
||||||
if (!isAllocated(RS, RSPrev, S) && !isReleased(RS, RSPrev, S))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Check that the name of the function is realloc.
|
// Is this is the first appearance of the reallocated symbol?
|
||||||
const CallExpr *CE = dyn_cast<CallExpr>(S);
|
if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
|
||||||
if (!CE)
|
// If we ever hit this assert, that means BugReporter has decided to skip
|
||||||
return 0;
|
// node pairs or visit them out of order.
|
||||||
const FunctionDecl *funDecl = CE->getDirectCallee();
|
assert(state->get<RegionState>(FailedReallocSymbol) &&
|
||||||
if (!funDecl)
|
"Missed the reallocation point");
|
||||||
return 0;
|
|
||||||
StringRef FunName = funDecl->getName();
|
// We're at the reallocation point.
|
||||||
if (!(FunName.equals("realloc") || FunName.equals("reallocf")))
|
Msg = "Attempt to reallocate memory";
|
||||||
return 0;
|
StackHint = new StackHintGeneratorForSymbol(Sym,
|
||||||
Msg = "Attempt to reallocate memory";
|
"Returned reallocated memory");
|
||||||
StackHint = new StackHintGeneratorForSymbol(Sym,
|
FailedReallocSymbol = NULL;
|
||||||
"Returned reallocated memory");
|
Mode = Normal;
|
||||||
Mode = Normal;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Msg)
|
if (!Msg)
|
||||||
|
|
Loading…
Reference in New Issue