diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 56a9fa9ac3..c629a82a2c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -212,6 +212,8 @@ def error_synthesized_ivar_yet_not_supported : Error< def error_property_ivar_type : Error< "type of property %0 does not match type of ivar %1">; +def error_ivar_in_superclass_use : Error< + "property %0 attempting to use ivar %1 declared in in super class %2">; def error_weak_property : Error< "existing ivar %1 for __weak property %0 must be __weak">; def error_strong_property : Error< diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index cf782caf5c..d468c1334e 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1791,11 +1791,13 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, // Check that we have a valid, previously declared ivar for @synthesize if (Synthesize) { // @synthesize + bool NoExplicitPropertyIvar = (!PropertyIvar); if (!PropertyIvar) PropertyIvar = PropertyId; QualType PropType = Context.getCanonicalType(property->getType()); // Check that this is a previously declared 'ivar' in 'IDecl' interface - Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar); + ObjCInterfaceDecl *ClassDeclared; + Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar, ClassDeclared); if (!Ivar) { if (getLangOptions().ObjCNonFragileABI) { Ivar = ObjCIvarDecl::Create(Context, CurContext, PropertyLoc, @@ -1809,6 +1811,15 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, return DeclPtrTy(); } } + else if (getLangOptions().ObjCNonFragileABI && + NoExplicitPropertyIvar && ClassDeclared != IDecl) { + Diag(PropertyLoc, diag::error_ivar_in_superclass_use) + << property->getDeclName() << Ivar->getDeclName() + << ClassDeclared->getDeclName(); + Diag(Ivar->getLocation(), diag::note_previous_access_declaration) + << Ivar << Ivar->getNameAsCString(); + // Note! I deliberately want it to fall thru so more errors are caught. + } QualType IvarType = Context.getCanonicalType(Ivar->getType()); // Check that type of property and its ivar are type compatible. diff --git a/test/SemaObjC/ivar-sem-check-2.m b/test/SemaObjC/ivar-sem-check-2.m new file mode 100644 index 0000000000..2b85685362 --- /dev/null +++ b/test/SemaObjC/ivar-sem-check-2.m @@ -0,0 +1,17 @@ +// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin10 -verify %s + +@interface Super { + id value; // expected-note {{previously declared 'value' here}} +} +@property(retain) id value; +@property(retain) id value1; +@end + +@interface Sub : Super @end + +@implementation Sub +@synthesize value; // expected-error {{property 'value' attempting to use ivar 'value' declared in in super class 'Super'}} // expected-note {{previous use is here}} +@synthesize value1=value; // expected-error {{synthesized properties 'value1' and 'value' both claim ivar 'value'}} +@end + +