]> granicus.if.org Git - clang/commitdiff
Fixup CodeGen for __weak __block variables. Radar 6756266
authorMike Stump <mrs@apple.com>
Tue, 14 Apr 2009 00:57:29 +0000 (00:57 +0000)
committerMike Stump <mrs@apple.com>
Tue, 14 Apr 2009 00:57:29 +0000 (00:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69010 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/Sema/SemaDecl.cpp
test/CodeGenObjC/blocks-1.m

index 2e7161c080e5c73c1ea3ba385726594fefbf7863..fe16c4d30fe7eb6fa6ce965da23ec04c0bfdbc3c 100644 (file)
@@ -422,7 +422,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
     // load of a __weak object. 
     llvm::Value *LvalueDst = Dst.getAddress();
     llvm::Value *src = Src.getScalarVal();
-    CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
+     CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
     return;
   }
   
@@ -631,6 +631,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD) ||
         isa<ImplicitParamDecl>(VD))) {
     LValue LV;
+    bool GCable = VD->hasLocalStorage() && ! VD->getAttr<BlocksAttr>();
     if (VD->getStorageClass() == VarDecl::Extern) {
       LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
                             E->getType().getCVRQualifiers(),
@@ -642,7 +643,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
       // local variables do not get their gc attribute set.
       QualType::GCAttrTypes attr = QualType::GCNone;
       // local static?
-      if (!VD->hasLocalStorage())
+      if (!GCable)
         attr = getContext().getObjCGCAttrKind(E->getType());
       if (VD->hasAttr<BlocksAttr>()) {
         bool needsCopyDispose = BlockRequiresCopying(VD->getType());
@@ -657,7 +658,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
       }
       LV = LValue::MakeAddr(V, E->getType().getCVRQualifiers(), attr);
     }
-    LValue::SetObjCNonGC(LV, VD->hasLocalStorage());
+    LValue::SetObjCNonGC(LV, GCable);
     return LV;
   } else if (VD && VD->isFileVarDecl()) {
     LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
index ef8b9e842e6467df0511575bcd8a4ebeebdbff9c..f4f131141f366f677a515677afa627588bf6513e 100644 (file)
@@ -1803,7 +1803,8 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
     Invalid = true;
   }
 
-  if (NewVD->hasLocalStorage() && T.isObjCGCWeak())
+  if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
+      && !NewVD->getAttr<BlocksAttr>())
     Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
 
   bool isIllegalVLA = T->isVariableArrayType() && NewVD->hasGlobalStorage();
index f7bbc3224457723b15b89bbe7816fe2b0d331874..38598b1b421071bfc45310b0de4b16fdab412a44 100644 (file)
@@ -1,14 +1,26 @@
-// RUN: clang-cc %s -emit-llvm -o %t -fblocks &&
-// RUN: grep "_Block_object_dispose" %t | count 2 &&
+// RUN: clang-cc %s -emit-llvm -o %t -fobjc-gc -fblocks &&
+// RUN: grep "_Block_object_dispose" %t | count 4 &&
 // RUN: grep "__copy_helper_block_" %t | count 2 &&
 // RUN: grep "__destroy_helper_block_" %t | count 2 &&
-// RUN: grep "__Block_byref_id_object_copy_" %t | count 0 &&
-// RUN: grep "__Block_byref_id_object_dispose_" %t | count 0 &&
+// RUN: grep "__Block_byref_id_object_copy_" %t | count 2 &&
+// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 &&
 // RUN: grep "i32 135)" %t | count 0 &&
-// RUN: grep "_Block_object_assign" %t | count 2
+// RUN: grep "_Block_object_assign" %t | count 3 &&
+// RUN: grep "objc_read_weak" %t | count 2 &&
+// RUN: grep "objc_assign_weak" %t | count 2
 
 @interface NSDictionary @end
 
 void test1(NSDictionary * dict) {
   ^{ (void)dict; }();
 }
+
+@interface D
+@end
+
+void foo() {
+  __block __weak D *weakSelf;
+  D *l;
+  l = weakSelf;
+  weakSelf = l;
+}