[cfe-commits] r133969 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/SemaObjC/arc.m test/SemaObjCXX/arc-overloading.mm
John McCall
rjmccall at apple.com
Mon Jun 27 16:59:58 PDT 2011
Author: rjmccall
Date: Mon Jun 27 18:59:58 2011
New Revision: 133969
URL: http://llvm.org/viewvc/llvm-project?rev=133969&view=rev
Log:
ARC writeback isn't supposed to apply to local indirect pointers,
only to pointers to locals. But it should work inside blocks, too.
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/SemaObjC/arc.m
cfe/trunk/test/SemaObjCXX/arc-overloading.mm
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Jun 27 18:59:58 2011
@@ -3195,24 +3195,24 @@
enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar };
/// Determines whether this expression is an acceptable ICR source.
-static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e) {
+static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e,
+ bool isAddressOf) {
// Skip parens.
e = e->IgnoreParens();
// Skip address-of nodes.
if (UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
if (op->getOpcode() == UO_AddrOf)
- return isInvalidICRSource(C, op->getSubExpr());
+ return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true);
// Skip certain casts.
- } else if (CastExpr *cast = dyn_cast<CastExpr>(e)) {
- switch (cast->getCastKind()) {
+ } else if (CastExpr *ce = dyn_cast<CastExpr>(e)) {
+ switch (ce->getCastKind()) {
case CK_Dependent:
case CK_BitCast:
case CK_LValueBitCast:
- case CK_LValueToRValue:
case CK_NoOp:
- return isInvalidICRSource(C, cast->getSubExpr());
+ return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf);
case CK_ArrayToPointerDecay:
return IIK_nonscalar;
@@ -3225,16 +3225,25 @@
}
// If we have a declaration reference, it had better be a local variable.
- } else if (DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(e)) {
- if (VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl()))
- return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
+ } else if (isa<DeclRefExpr>(e) || isa<BlockDeclRefExpr>(e)) {
+ if (!isAddressOf) return IIK_nonlocal;
+
+ VarDecl *var;
+ if (isa<DeclRefExpr>(e)) {
+ var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl());
+ if (!var) return IIK_nonlocal;
+ } else {
+ var = cast<BlockDeclRefExpr>(e)->getDecl();
+ }
+
+ return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
// If we have a conditional operator, check both sides.
} else if (ConditionalOperator *cond = dyn_cast<ConditionalOperator>(e)) {
- if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS()))
+ if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf))
return iik;
- return isInvalidICRSource(C, cond->getRHS());
+ return isInvalidICRSource(C, cond->getRHS(), isAddressOf);
// These are never scalar.
} else if (isa<ArraySubscriptExpr>(e)) {
@@ -3254,7 +3263,7 @@
static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) {
assert(src->isRValue());
- InvalidICRKind iik = isInvalidICRSource(S.Context, src);
+ InvalidICRKind iik = isInvalidICRSource(S.Context, src, false);
if (iik == IIK_okay) return;
S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Mon Jun 27 18:59:58 2011
@@ -592,3 +592,16 @@
@synthesize newName2;
@end
+void test35(void) {
+ extern void test36_helper(id*);
+ id x;
+ __strong id *xp = 0;
+
+ test36_helper(&x);
+ test36_helper(xp); // expected-error {{passing address of non-local object to __autoreleasing parameter for write-back}}
+
+ // rdar://problem/9665710
+ __block id y;
+ test36_helper(&y);
+ ^{ test36_helper(&y); }();
+}
Modified: cfe/trunk/test/SemaObjCXX/arc-overloading.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-overloading.mm?rev=133969&r1=133968&r2=133969&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-overloading.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-overloading.mm Mon Jun 27 18:59:58 2011
@@ -58,15 +58,15 @@
int &f3(id __autoreleasing *); // expected-note{{candidate function not viable: 1st argument ('__unsafe_unretained id *') has __unsafe_unretained ownership, but parameter has __autoreleasing ownership}}
void test_f3() {
- id __strong *sip;
- id __weak *wip;
- id __autoreleasing *aip;
- id __unsafe_unretained *uip;
-
- int &ir1 = f3(sip);
- int &ir2 = f3(wip);
- int &ir3 = f3(aip);
- f3(uip); // expected-error{{no matching function for call to 'f3'}}
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+ id __unsafe_unretained uip;
+
+ int &ir1 = f3(&sip);
+ int &ir2 = f3(&wip);
+ int &ir3 = f3(&aip);
+ f3(&uip); // expected-error{{no matching function for call to 'f3'}}
}
// Writeback conversion vs. no conversion
@@ -74,15 +74,15 @@
float &f4(id __strong *);
void test_f4() {
- id __strong *sip;
- id __weak *wip;
- id __autoreleasing *aip;
- extern __weak id *weak_global_ptr;
-
- float &fr1 = f4(sip);
- int &ir1 = f4(wip);
- int &ir2 = f4(aip);
- int &ir3 = f4(weak_global_ptr); // expected-error{{passing address of non-local object to __autoreleasing parameter for write-back}}
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+ extern __weak id weak_global_ptr;
+
+ float &fr1 = f4(&sip);
+ int &ir1 = f4(&wip);
+ int &ir2 = f4(&aip);
+ int &ir3 = f4(&weak_global_ptr); // expected-error{{passing address of non-local object to __autoreleasing parameter for write-back}}
}
// Writeback conversion vs. other conversion.
@@ -90,13 +90,13 @@
float &f5(id const __unsafe_unretained *);
void test_f5() {
- id __strong *sip;
- id __weak *wip;
- id __autoreleasing *aip;
-
- int &ir1 = f5(wip);
- float &fr1 = f5(sip);
- int &ir2 = f5(aip);
+ id __strong sip;
+ id __weak wip;
+ id __autoreleasing aip;
+
+ int &ir1 = f5(&wip);
+ float &fr1 = f5(&sip);
+ int &ir2 = f5(&aip);
}
@interface A
@@ -106,13 +106,13 @@
float &f6(id const __unsafe_unretained *);
void test_f6() {
- A* __strong *sip;
- A* __weak *wip;
- A* __autoreleasing *aip;
-
- int &ir1 = f6(wip);
- float &fr1 = f6(sip);
- int &ir2 = f6(aip);
+ A* __strong sip;
+ A* __weak wip;
+ A* __autoreleasing aip;
+
+ int &ir1 = f6(&wip);
+ float &fr1 = f6(&sip);
+ int &ir2 = f6(&aip);
}
// Reference binding
More information about the cfe-commits
mailing list