From: Ted Kremenek Date: Thu, 31 Jul 2008 20:31:27 +0000 (+0000) Subject: Enhanced path-sensitive return-of-stack-address check to print out the name of the... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22bda887aacd0e591978541a799aa43835652ec9;p=clang Enhanced path-sensitive return-of-stack-address check to print out the name of the variable whose address was returned. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54253 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index 803a70397d..f3e0208d6a 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -107,14 +107,21 @@ public: class RangedBugReport : public BugReport { std::vector Ranges; + const char* desc; public: - RangedBugReport(BugType& D, ExplodedNode *n) - : BugReport(D, n) {} + RangedBugReport(BugType& D, ExplodedNode *n, + const char* description = 0) + : BugReport(D, n), desc(description) {} virtual ~RangedBugReport(); + + virtual const char* getDescription() const { + return desc ? desc : BugReport::getDescription(); + } void addRange(SourceRange R) { Ranges.push_back(R); } + virtual void getRanges(BugReporter& BR,const SourceRange*& beg, const SourceRange*& end) { diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index 853c6544e8..05c4400126 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -15,7 +15,7 @@ #include "clang/Analysis/PathSensitive/BugReporter.h" #include "clang/Analysis/PathSensitive/GRExprEngine.h" #include "llvm/Support/Compiler.h" - +#include using namespace clang; @@ -42,9 +42,12 @@ class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation { const char* name; const char* desc; public: - BuiltinBug(const char* n, const char* d) : name(n), desc(d) {} + BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {} virtual const char* getName() const { return name; } - virtual const char* getDescription() const { return desc; } + virtual const char* getDescription() const { + return desc ? desc : name; + } + virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0; virtual void EmitWarnings(BugReporter& BR) { EmitBuiltinWarnings(BR, cast(BR).getEngine()); @@ -177,20 +180,29 @@ public: class VISIBILITY_HIDDEN RetStack : public BuiltinBug { public: - RetStack() : BuiltinBug("return of stack address", - "Address of stack-allocated variable returned.") {} + RetStack() : BuiltinBug("return of stack address") {} virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) { for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(), End = Eng.ret_stackaddr_end(); I!=End; ++I) { - - // Generate a report for this bug. - RangedBugReport report(*this, *I); - + ExplodedNode* N = *I; Stmt *S = cast(N->getLocation()).getStmt(); Expr* E = cast(S)->getRetValue(); assert (E && "Return expression cannot be NULL"); + + // Get the value associated with E. + lval::DeclVal V = + cast(Eng.getStateManager().GetRVal(N->getState(), E)); + + // Generate a report for this bug. + std::ostringstream os; + os << "Address of stack memory associated with local variable '" + << V.getDecl()->getName() << "' returned."; + + std::string s = os.str(); + + RangedBugReport report(*this, N, s.c_str()); report.addRange(E->getSourceRange()); // Emit the warning. diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 964b3e4550..57e4718fe6 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -62,4 +62,19 @@ int f6(int *p) { return !p ? bar(p) : *p; // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}} } +int* qux(); + +int f7(int x) { + + int* p = 0; + + if (0 == x) + p = qux(); + + if (0 == x) + *p = 1; // no-warning + + return x; +} + diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c index c59df0904d..8e2a0c06af 100644 --- a/test/Analysis/stack-addr-ps.c +++ b/test/Analysis/stack-addr-ps.c @@ -2,11 +2,11 @@ int* f1() { int x = 0; - return &x; // expected-warning{{Address of stack-allocated variable returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}} + return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned.}} expected-warning{{address of stack memory associated with local variable 'x' returned}} } int* f2(int y) { - return &y; // expected-warning{{Address of stack-allocated variable returned.}} expected-warning{{address of stack memory associated with local variable 'y' returned}} + return &y; // expected-warning{{Address of stack memory associated with local variable 'y' returned.}} expected-warning{{address of stack memory associated with local variable 'y' returned}} } int* f3(int x, int *y) { @@ -15,7 +15,7 @@ int* f3(int x, int *y) { if (x) y = &w; - return y; // expected-warning{{Address of stack-allocated variable returned.}} + return y; // expected-warning{{Address of stack memory associated with local variable 'w' returned.}} }