aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2012-07-11 22:50:15 +0000
committerNico Weber <nicolasweber@gmx.de>2012-07-11 22:50:15 +0000
commit8951067a2bc35fb2a535bc18432cb2d02a762b73 (patch)
treec2c68ef12f8fbbc5769acfa143961f48a59633a3
parente3f470a718ec00eb8b546e405fa59bc2df2d7c46 (diff)
Don't try to do RVO on block variables that refer to an enclosing local.
Fixes PR13314, clang crashing on blocks refering to an enclosing local when the enclosing function returns void. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160089 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaStmt.cpp2
-rw-r--r--test/CodeGenObjCXX/blocks.mm21
2 files changed, 19 insertions, 4 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9be1d34dae..54ec58af41 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2035,7 +2035,7 @@ const VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
// ... the expression is the name of a non-volatile automatic object
// (other than a function or catch-clause parameter)) ...
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
- if (!DR)
+ if (!DR || DR->refersToEnclosingLocal())
return 0;
const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
if (!VD)
diff --git a/test/CodeGenObjCXX/blocks.mm b/test/CodeGenObjCXX/blocks.mm
index 72af74f1eb..62ae428e5e 100644
--- a/test/CodeGenObjCXX/blocks.mm
+++ b/test/CodeGenObjCXX/blocks.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 %s -verify -emit-llvm -o %t
+// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 %s -verify -std=c++11 -emit-llvm -o %t
// rdar://8979379
@interface A
@@ -30,7 +30,7 @@ void foo(id <NSObject>(^objectCreationBlock)(void)) {
// Test4
struct S {
- S *(^a)() = ^{ // expected-warning {{C++11}}
+ S *(^a)() = ^{
return this;
};
};
@@ -40,7 +40,22 @@ S s;
struct X {
void f() {
^ {
- struct Nested { Nested *ptr = this; }; // expected-warning {{C++11}}
+ struct Nested { Nested *ptr = this; };
} ();
};
};
+
+// Regression test for PR13314
+class FooClass { };
+void fun() {
+ FooClass foovar;
+ ^() { // expected-warning {{expression result unused}}
+ return foovar;
+ };
+}
+void gun() {
+ FooClass foovar;
+ [=]() { // expected-warning {{expression result unused}}
+ return foovar;
+ };
+}