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