diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 113c7c7bf06008e66976c6ad11cda942f5373099..9786f7fb4f8ae0b7cc59cc1af38b17fea6e86a96 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 0000000000000000000000000000000000000000..218950ca7b50159a8b28155590fc203df2bab871 --- /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