[cfe-commits] r153725 - in /cfe/trunk: docs/AutomaticReferenceCounting.html include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaObjC/arc-invalid.m test/SemaObjCXX/arc-0x.mm
John McCall
rjmccall at apple.com
Thu Mar 29 22:23:48 PDT 2012
Author: rjmccall
Date: Fri Mar 30 00:23:48 2012
New Revision: 153725
URL: http://llvm.org/viewvc/llvm-project?rev=153725&view=rev
Log:
Forbid the block and lambda copy-capture of __autoreleasing variables
in ARC, under the usual reasoning limiting the use of __autoreleasing.
Modified:
cfe/trunk/docs/AutomaticReferenceCounting.html
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/SemaObjC/arc-invalid.m
cfe/trunk/test/SemaObjCXX/arc-0x.mm
Modified: cfe/trunk/docs/AutomaticReferenceCounting.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/AutomaticReferenceCounting.html?rev=153725&r1=153724&r2=153725&view=diff
==============================================================================
--- cfe/trunk/docs/AutomaticReferenceCounting.html (original)
+++ cfe/trunk/docs/AutomaticReferenceCounting.html Fri Mar 30 00:23:48 2012
@@ -1006,7 +1006,9 @@
<h1>Storage duration of <tt>__autoreleasing</tt> objects</h1>
<p>A program is ill-formed if it declares an <tt>__autoreleasing</tt>
-object of non-automatic storage duration.</p>
+object of non-automatic storage duration. A program is ill-formed
+if it captures an <tt>__autoreleasing</tt> object in a block or,
+unless by reference, in a C++11 lambda.</p>
<div class="rationale"><p>Rationale: autorelease pools are tied to the
current thread and scope by their nature. While it is possible to
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=153725&r1=153724&r2=153725&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Mar 30 00:23:48 2012
@@ -3270,6 +3270,9 @@
def err_arc_autoreleasing_var : Error<
"%select{__block variables|global variables|fields|ivars}0 cannot have "
"__autoreleasing ownership">;
+def err_arc_autoreleasing_capture : Error<
+ "cannot capture __autoreleasing variable in a "
+ "%select{block|lambda by copy}0">;
def err_arc_thread_ownership : Error<
"thread-local variable has non-trivial ownership: type is %0">;
def err_arc_indirect_no_ownership : Error<
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=153725&r1=153724&r2=153725&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Mar 30 00:23:48 2012
@@ -10087,6 +10087,17 @@
return true;
}
+ // Forbid the block-capture of autoreleasing variables.
+ if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
+ if (BuildAndDiagnose) {
+ Diag(Loc, diag::err_arc_autoreleasing_capture)
+ << /*block*/ 0;
+ Diag(Var->getLocation(), diag::note_previous_decl)
+ << Var->getDeclName();
+ }
+ return true;
+ }
+
if (HasBlocksAttr || CaptureType->isReferenceType()) {
// Block capture by reference does not change the capture or
// declaration reference types.
@@ -10179,6 +10190,16 @@
if (!RefType->getPointeeType()->isFunctionType())
CaptureType = RefType->getPointeeType();
}
+
+ // Forbid the lambda copy-capture of autoreleasing variables.
+ if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
+ if (BuildAndDiagnose) {
+ Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1;
+ Diag(Var->getLocation(), diag::note_previous_decl)
+ << Var->getDeclName();
+ }
+ return true;
+ }
}
// Capture this variable in the lambda.
Modified: cfe/trunk/test/SemaObjC/arc-invalid.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-invalid.m?rev=153725&r1=153724&r2=153725&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-invalid.m (original)
+++ cfe/trunk/test/SemaObjC/arc-invalid.m Fri Mar 30 00:23:48 2012
@@ -11,3 +11,8 @@
void test0(id p) {
takeBlock(^{ [p foo] + p; }); // expected-error {{invalid operands to binary expression}}
}
+
+void test1(void) {
+ __autoreleasing id p; // expected-note {{'p' declared here}}
+ takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}}
+}
Modified: cfe/trunk/test/SemaObjCXX/arc-0x.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-0x.mm?rev=153725&r1=153724&r2=153725&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-0x.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-0x.mm Fri Mar 30 00:23:48 2012
@@ -30,3 +30,24 @@
} @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
}
}
+
+// rdar://problem/11068137
+void test1a() {
+ __autoreleasing id p; // expected-note 2 {{'p' declared here}}
+ (void) [&p] {};
+ (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+ (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+}
+void test1b() {
+ __autoreleasing id v;
+ __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}}
+ (void) [&p] {};
+ (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+ (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+}
+void test1c() {
+ __autoreleasing id v; // expected-note {{'v' declared here}}
+ __autoreleasing id &p = v;
+ (void) ^{ (void) p; };
+ (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
+}
More information about the cfe-commits
mailing list