r253255 - Correctly handle type mismatches in the __weak copy/move-initialization

John McCall via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 16 14:11:42 PST 2015


Author: rjmccall
Date: Mon Nov 16 16:11:41 2015
New Revision: 253255

URL: http://llvm.org/viewvc/llvm-project?rev=253255&view=rev
Log:
Correctly handle type mismatches in the __weak copy/move-initialization
peephole I added in r250916.

rdar://23559789

Added:
    cfe/trunk/test/CodeGenObjC/arc-weak.m
    cfe/trunk/test/CodeGenObjCXX/arc-weak.mm
Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=253255&r1=253254&r2=253255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Nov 16 16:11:41 2015
@@ -600,12 +600,15 @@ static bool isAccessedBy(const ValueDecl
 
 static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
                                    const LValue &destLV, const Expr *init) {
+  bool needsCast = false;
+
   while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) {
     switch (castExpr->getCastKind()) {
     // Look through casts that don't require representation changes.
     case CK_NoOp:
     case CK_BitCast:
     case CK_BlockPointerToObjCPointerCast:
+      needsCast = true;
       break;
 
     // If we find an l-value to r-value cast from a __weak variable,
@@ -618,12 +621,19 @@ static bool tryEmitARCCopyWeakInit(CodeG
       // Emit the source l-value.
       LValue srcLV = CGF.EmitLValue(srcExpr);
 
+      // Handle a formal type change to avoid asserting.
+      auto srcAddr = srcLV.getAddress();
+      if (needsCast) {
+        srcAddr = CGF.Builder.CreateElementBitCast(srcAddr,
+                                         destLV.getAddress().getElementType());
+      }
+
       // If it was an l-value, use objc_copyWeak.
       if (srcExpr->getValueKind() == VK_LValue) {
-        CGF.EmitARCCopyWeak(destLV.getAddress(), srcLV.getAddress());
+        CGF.EmitARCCopyWeak(destLV.getAddress(), srcAddr);
       } else {
         assert(srcExpr->getValueKind() == VK_XValue);
-        CGF.EmitARCMoveWeak(destLV.getAddress(), srcLV.getAddress());
+        CGF.EmitARCMoveWeak(destLV.getAddress(), srcAddr);
       }
       return true;
     }

Added: cfe/trunk/test/CodeGenObjC/arc-weak.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-weak.m?rev=253255&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-weak.m (added)
+++ cfe/trunk/test/CodeGenObjC/arc-weak.m Mon Nov 16 16:11:41 2015
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck %s
+
+__attribute((objc_root_class)) @interface A @end
+ at interface B : A @end
+
+// rdar://problem/23559789
+//   Ensure that type differences don't cause an assert here.
+void test0(__weak B **src) {
+  __weak A *dest = *src;
+}
+// CHECK-LABEL: define void @test0
+// CHECK:       [[SRC:%.*]] = alloca [[B:%.*]]**, align 8
+// CHECK:       [[DEST:%.*]] = alloca [[A:%.*]]*, align 8
+// CHECK:       [[T0:%.*]] = load [[B]]**, [[B]]*** [[SRC]], align 8
+// CHECK-NEXT:  [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]**
+// CHECK-NEXT:  [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK-NEXT:  [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8**
+// CHECK-NEXT:  call void @objc_copyWeak(i8** [[T2]], i8** [[T3]])
+// CHECK-NEXT:  [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK:       call void @objc_destroyWeak(i8** [[T0]])

Added: cfe/trunk/test/CodeGenObjCXX/arc-weak.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-weak.mm?rev=253255&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-weak.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/arc-weak.mm Mon Nov 16 16:11:41 2015
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -std=c++11 -o - %s | FileCheck %s
+
+__attribute((objc_root_class)) @interface A @end
+ at interface B : A @end
+
+// rdar://problem/23559789
+//   Ensure that type differences don't cause an assert here.
+void test0(__weak B **src) {
+  __weak A *dest = *src;
+}
+// CHECK-LABEL: define void @_Z5test0PU6__weakP1B(
+// CHECK:       [[SRC:%.*]] = alloca [[B:%.*]]**, align 8
+// CHECK:       [[DEST:%.*]] = alloca [[A:%.*]]*, align 8
+// CHECK:       [[T0:%.*]] = load [[B]]**, [[B]]*** [[SRC]], align 8
+// CHECK-NEXT:  [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]**
+// CHECK-NEXT:  [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK-NEXT:  [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8**
+// CHECK-NEXT:  call void @objc_copyWeak(i8** [[T2]], i8** [[T3]])
+// CHECK-NEXT:  [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK:       call void @objc_destroyWeak(i8** [[T0]])
+
+void test1(__weak B **src) {
+  __weak A *dest = static_cast<__weak B*&&>(*src);
+}
+// CHECK-LABEL: define void @_Z5test1PU6__weakP1B(
+// CHECK:       [[SRC:%.*]] = alloca [[B:%.*]]**, align 8
+// CHECK:       [[DEST:%.*]] = alloca [[A:%.*]]*, align 8
+// CHECK:       [[T0:%.*]] = load [[B]]**, [[B]]*** [[SRC]], align 8
+// CHECK-NEXT:  [[T1:%.*]] = bitcast [[B]]** [[T0]] to [[A]]**
+// CHECK-NEXT:  [[T2:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK-NEXT:  [[T3:%.*]] = bitcast [[A]]** [[T1]] to i8**
+// CHECK-NEXT:  call void @objc_moveWeak(i8** [[T2]], i8** [[T3]])
+// CHECK-NEXT:  [[T0:%.*]] = bitcast [[A]]** [[DEST]] to i8**
+// CHECK:       call void @objc_destroyWeak(i8** [[T0]])




More information about the cfe-commits mailing list