diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 75f8c48022ae..b0d545380810 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -1561,8 +1561,15 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf(receiverNameLoc)) { if (CurMethod->isInstanceMethod()) { - QualType T = - Context.getObjCInterfaceType(CurMethod->getClassInterface()); + ObjCInterfaceDecl *Super = + CurMethod->getClassInterface()->getSuperClass(); + if (!Super) { + // The current class does not have a superclass. + Diag(receiverNameLoc, diag::error_root_class_cannot_use_super) + << CurMethod->getClassInterface()->getIdentifier(); + return ExprError(); + } + QualType T = Context.getObjCInterfaceType(Super); T = Context.getObjCObjectPointerType(T); return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), diff --git a/clang/test/Coverage/objc-language-features.inc b/clang/test/Coverage/objc-language-features.inc index dbbf205fcd6b..29d8298c82e6 100644 --- a/clang/test/Coverage/objc-language-features.inc +++ b/clang/test/Coverage/objc-language-features.inc @@ -9,6 +9,7 @@ @class B; @interface Root +@property(readonly) int p0; @end @interface A : Root { diff --git a/clang/test/SemaObjC/super-property-notation.m b/clang/test/SemaObjC/super-property-notation.m index 0c17bb9392ec..a0364c9d9c04 100644 --- a/clang/test/SemaObjC/super-property-notation.m +++ b/clang/test/SemaObjC/super-property-notation.m @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -verify %s @interface B +(int) classGetter; @@ -29,3 +28,25 @@ void f0() { int l2 = [A classGetter2]; } +// rdar://13349296 +__attribute__((objc_root_class)) @interface ClassBase +@property (nonatomic, retain) ClassBase * foo; +@end + +@implementation ClassBase +- (void) Meth:(ClassBase*)foo { + super.foo = foo; // expected-error {{'ClassBase' cannot use 'super' because it is a root class}} + [super setFoo:foo]; // expected-error {{'ClassBase' cannot use 'super' because it is a root class}} +} +@end + +@interface ClassDerived : ClassBase +@property (nonatomic, retain) ClassDerived * foo; +@end + +@implementation ClassDerived +- (void) Meth:(ClassBase*)foo { + super.foo = foo; // issues compile warning + [super setFoo:foo]; // works with no warning +} +@end