From 68957a919084ab8bbd1f01d534db1d6f31d0f459 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 4 Aug 2010 20:01:07 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaChecking.cpp | 18 +++++++++++++++--- test/Analysis/stack-addr-ps.cpp | 8 ++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/Analysis/stack-addr-ps.cpp 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(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(E)->getSubExpr()); + E = cast(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}} +} -- 2.40.0