From 3313ed25f44191c719dca9ba7c12166da0da60ed Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Wed, 1 Jun 2016 17:14:19 +0000 Subject: [PATCH] ObjC lifetime: pull sugar off when the qualifiers conflict. It's possible to have multiple local ObjCLifetime qualifiers. When there is a conflict, we can't stop after we reach a type that is directly qualified. We need to keep pulling sugar off and removing the ObjCLifetime qualifers. rdar://25804796 Differential Revision: http://reviews.llvm.org/D20843 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@271409 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaType.cpp | 10 ++++--- test/SemaObjC/arc-objc-lifetime-conflict.m | 32 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 test/SemaObjC/arc-objc-lifetime-conflict.m diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 113c7c7bf0..9786f7fb4f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -5415,11 +5415,13 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, } // Otherwise, if the qualifiers actually conflict, pull sugar off - // until we reach a type that is directly qualified. + // and remove the ObjCLifetime qualifiers. if (previousLifetime != lifetime) { - // This should always terminate: the canonical type is - // qualified, so some bit of sugar must be hiding it. - while (!underlyingType.Quals.hasObjCLifetime()) { + // It's possible to have multiple local ObjCLifetime qualifiers. We + // can't stop after we reach a type that is directly qualified. + const Type *prevTy = nullptr; + while (!prevTy || prevTy != underlyingType.Ty) { + prevTy = underlyingType.Ty; underlyingType = underlyingType.getSingleStepDesugaredType(); } underlyingType.Quals.removeObjCLifetime(); diff --git a/test/SemaObjC/arc-objc-lifetime-conflict.m b/test/SemaObjC/arc-objc-lifetime-conflict.m new file mode 100644 index 0000000000..218950ca7b --- /dev/null +++ b/test/SemaObjC/arc-objc-lifetime-conflict.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-arc -fobjc-runtime-has-weak %s -emit-llvm -o - | FileCheck %s + +// CHECK: bitcast {{.*}} %self_weak_s_w_s +// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: bitcast {{.*}} %self_strong_w_s +// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: bitcast {{.*}} %self_weak_s +// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: bitcast {{.*}} %self_weak_s3 +// CHECK-NEXT: objc_destroyWeak +// CHECK-NEXT: bitcast {{.*}} %self_strong3 +// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: bitcast {{.*}} %self_strong2 +// CHECK-NEXT: objc_storeStrong +// CHECK-NEXT: bitcast {{.*}} %self_strong +// CHECK-NEXT: objc_storeStrong +@interface NSObject +@end +@interface A : NSObject +@end +@implementation A +- (void)test { + __attribute__((objc_ownership(strong))) __typeof__(self) self_strong; + __attribute__((objc_ownership(strong))) __typeof__(self_strong) self_strong2; + __attribute__((objc_ownership(strong))) __typeof__(self_strong2) self_strong3; + __attribute__((objc_ownership(weak))) __typeof__(self_strong3) self_weak_s3; + + __attribute__((objc_ownership(weak))) __typeof__(self_strong) self_weak_s; + __attribute__((objc_ownership(strong))) __typeof__(self_weak_s) self_strong_w_s; + __attribute__((objc_ownership(weak))) __typeof__(self_strong_w_s) self_weak_s_w_s; +} +@end -- 2.40.0