diff options
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/BugReporter.h | 11 | ||||
-rw-r--r-- | clang/lib/Analysis/GRExprEngineInternalChecks.cpp | 30 | ||||
-rw-r--r-- | clang/test/Analysis/null-deref-ps.c | 15 | ||||
-rw-r--r-- | clang/test/Analysis/stack-addr-ps.c | 6 |
4 files changed, 48 insertions, 14 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h index 803a70397d3..f3e0208d6a2 100644 --- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/clang/include/clang/Analysis/PathSensitive/BugReporter.h @@ -107,14 +107,21 @@ public: class RangedBugReport : public BugReport { std::vector<SourceRange> Ranges; + const char* desc; public: - RangedBugReport(BugType& D, ExplodedNode<ValueState> *n) - : BugReport(D, n) {} + RangedBugReport(BugType& D, ExplodedNode<ValueState> *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/clang/lib/Analysis/GRExprEngineInternalChecks.cpp b/clang/lib/Analysis/GRExprEngineInternalChecks.cpp index 853c6544e83..05c44001266 100644 --- a/clang/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/clang/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 <sstream> 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<GRBugReporter>(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<ValueState>* N = *I; Stmt *S = cast<PostStmt>(N->getLocation()).getStmt(); Expr* E = cast<ReturnStmt>(S)->getRetValue(); assert (E && "Return expression cannot be NULL"); + + // Get the value associated with E. + lval::DeclVal V = + cast<lval::DeclVal>(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/clang/test/Analysis/null-deref-ps.c b/clang/test/Analysis/null-deref-ps.c index 964b3e45506..57e4718fe69 100644 --- a/clang/test/Analysis/null-deref-ps.c +++ b/clang/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/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c index c59df0904dd..8e2a0c06af4 100644 --- a/clang/test/Analysis/stack-addr-ps.c +++ b/clang/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.}} } |