r200494 - Don't produce a 'returning reference to local' warning if a lambda returns a
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jan 30 14:05:38 PST 2014
Author: rsmith
Date: Thu Jan 30 16:05:38 2014
New Revision: 200494
URL: http://llvm.org/viewvc/llvm-project?rev=200494&view=rev
Log:
Don't produce a 'returning reference to local' warning if a lambda returns a
reference (or pointer) to a variable from the closure object or from the
surrounding function scope.
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/SemaCXX/return-stack-addr.cpp
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=200494&r1=200493&r2=200494&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Jan 30 16:05:38 2014
@@ -4136,6 +4136,10 @@ static Expr *EvalAddr(Expr *E, SmallVect
case Stmt::DeclRefExprClass: {
DeclRefExpr *DR = cast<DeclRefExpr>(E);
+ // If we leave the immediate function, the lifetime isn't about to end.
+ if (DR->refersToEnclosingLocal())
+ return 0;
+
if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
// If this is a reference variable, follow through to the expression that
// it points to.
@@ -4292,6 +4296,10 @@ do {
// local storage within the function, and if so, return the expression.
DeclRefExpr *DR = cast<DeclRefExpr>(E);
+ // If we leave the immediate function, the lifetime isn't about to end.
+ if (DR->refersToEnclosingLocal())
+ return 0;
+
if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) {
// Check if it refers to itself, e.g. "int& i = i;".
if (V == ParentDecl)
Modified: cfe/trunk/test/SemaCXX/return-stack-addr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return-stack-addr.cpp?rev=200494&r1=200493&r2=200494&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/return-stack-addr.cpp (original)
+++ cfe/trunk/test/SemaCXX/return-stack-addr.cpp Thu Jan 30 16:05:38 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
int* ret_local() {
int x = 1;
@@ -108,6 +108,11 @@ int* ret_cpp_const_cast(const int x) {
return const_cast<int*>(&x); // expected-warning {{address of stack memory}}
}
+struct A { virtual ~A(); }; struct B : A {};
+A* ret_cpp_dynamic_cast(B b) {
+ return dynamic_cast<A*>(&b); // expected-warning {{address of stack memory}}
+}
+
// PR 7999 - handle the case where a field is itself a reference.
template <typename T> struct PR7999 {
PR7999(T& t) : value(t) {}
@@ -137,5 +142,17 @@ namespace PR8774 {
}
}
-// TODO: test case for dynamic_cast. clang does not yet have
-// support for C++ classes to write such a test case.
+// Don't warn about returning a local variable from a surrounding function if
+// we're within a lambda-expression.
+void ret_from_lambda() {
+ int a;
+ int &b = a;
+ (void) [&]() -> int& { return a; };
+ (void) [&]() -> int& { return b; };
+ (void) [=]() mutable -> int& { return a; };
+ (void) [=]() mutable -> int& { return b; };
+ (void) [&]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [=]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [&]() -> int& { int &a = b; return a; };
+ (void) [=]() mutable -> int& { int &a = b; return a; };
+}
More information about the cfe-commits
mailing list