aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-08-04 20:01:07 +0000
committerTed Kremenek <kremenek@apple.com>2010-08-04 20:01:07 +0000
commit68957a919084ab8bbd1f01d534db1d6f31d0f459 (patch)
treed462c36a2c98525cf56f2bf33443c2bf2ba06f62
parent44034db24bf59a53aa7699f4bbf59b939710bb3c (diff)
Teach SemaChecking::CheckReturnStackAddr about ImplicitCastExprs that convert values to an lvalue. This allows us to warn (again) about returning references to stack variables. (fixes PR 7812).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110242 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaChecking.cpp18
-rw-r--r--test/Analysis/stack-addr-ps.cpp8
2 files changed, 23 insertions, 3 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index d17ea43984..0fcc0a7559 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1952,7 +1952,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
/// EvalVal - This function is complements EvalAddr in the mutual recursion.
/// See the comments for EvalAddr for more details.
static DeclRefExpr* EvalVal(Expr *E) {
-
+do {
// We should only be called for evaluating non-pointer expressions, or
// expressions with a pointer type that are not used as references but instead
// are l-values (e.g., DeclRefExpr with a pointer type).
@@ -1961,6 +1961,15 @@ static DeclRefExpr* EvalVal(Expr *E) {
// viewed AST node. We then recursively traverse the AST by calling
// EvalAddr and EvalVal appropriately.
switch (E->getStmtClass()) {
+ case Stmt::ImplicitCastExprClass: {
+ ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
+ if (IE->getCategory() == ImplicitCastExpr::LValue) {
+ E = IE->getSubExpr();
+ continue;
+ }
+ return NULL;
+ }
+
case Stmt::DeclRefExprClass: {
// DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking
// at code that refers to a variable's name. We check if it has local
@@ -1973,9 +1982,11 @@ static DeclRefExpr* EvalVal(Expr *E) {
return NULL;
}
- case Stmt::ParenExprClass:
+ case Stmt::ParenExprClass: {
// Ignore parentheses.
- return EvalVal(cast<ParenExpr>(E)->getSubExpr());
+ E = cast<ParenExpr>(E)->getSubExpr();
+ continue;
+ }
case Stmt::UnaryOperatorClass: {
// The only unary operator that make sense to handle here
@@ -2024,6 +2035,7 @@ static DeclRefExpr* EvalVal(Expr *E) {
default:
return NULL;
}
+} while (true);
}
//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
new file mode 100644
index 0000000000..593ba1df94
--- /dev/null
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+
+// FIXME: Only the stack-address checking in Sema catches this right now, and
+// the stack analyzer doesn't handle the ImplicitCastExpr (lvalue).
+const int& g() {
+ int s;
+ return s; // expected-warning{{reference to stack memory associated with local variable 's' returned}}
+}