forked from OSchip/llvm-project
Correctly handle type mismatches in the __weak copy/move-initialization
peephole I added in r250916. rdar://23559789 llvm-svn: 253255
This commit is contained in:
parent
1bfc89baac
commit
0204e342ca
|
@ -600,12 +600,15 @@ static bool isAccessedBy(const ValueDecl *decl, const Expr *e) {
|
|||
|
||||
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(CodeGenFunction &CGF,
|
|||
// 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;
|
||||
}
|
||||
|
|
|
@ -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]])
|
|
@ -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]])
|
Loading…
Reference in New Issue