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 +@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 +@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]]) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits