More Sema check for ivars in class continuation.
llvm-svn: 97002
This commit is contained in:
parent
625916df32
commit
545643c309
|
@ -1440,6 +1440,8 @@ public:
|
|||
void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
|
||||
ObjCContainerDecl* IDecl);
|
||||
|
||||
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
|
||||
|
||||
/// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
|
||||
/// true, or false, accordingly.
|
||||
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
|
||||
|
|
|
@ -5659,21 +5659,8 @@ void Sema::ActOnFields(Scope* S,
|
|||
}
|
||||
// Must enforce the rule that ivars in the base classes may not be
|
||||
// duplicates.
|
||||
if (ID->getSuperClass()) {
|
||||
for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
|
||||
IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
|
||||
ObjCIvarDecl* Ivar = (*IVI);
|
||||
|
||||
if (IdentifierInfo *II = Ivar->getIdentifier()) {
|
||||
ObjCIvarDecl* prevIvar =
|
||||
ID->getSuperClass()->lookupInstanceVariable(II);
|
||||
if (prevIvar) {
|
||||
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
|
||||
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ID->getSuperClass())
|
||||
DiagnoseDuplicateIvars(ID, ID->getSuperClass());
|
||||
} else if (ObjCImplementationDecl *IMPDecl =
|
||||
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
|
||||
assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");
|
||||
|
|
|
@ -1781,6 +1781,29 @@ void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
|
|||
}
|
||||
}
|
||||
|
||||
/// DiagnoseDuplicateIvars -
|
||||
/// Check for duplicate ivars in the entire class at the start of
|
||||
/// @implementation. This becomes necesssary because class extension can
|
||||
/// add ivars to a class in random order which will not be known until
|
||||
/// class's @implementation is seen.
|
||||
void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
|
||||
ObjCInterfaceDecl *SID) {
|
||||
for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
|
||||
IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
|
||||
ObjCIvarDecl* Ivar = (*IVI);
|
||||
if (Ivar->isInvalidDecl())
|
||||
continue;
|
||||
if (IdentifierInfo *II = Ivar->getIdentifier()) {
|
||||
ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
|
||||
if (prevIvar) {
|
||||
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
|
||||
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
|
||||
Ivar->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: For class/category implemenations, allMethods/allProperties is
|
||||
// always null.
|
||||
void Sema::ActOnAtEnd(SourceRange AtEnd,
|
||||
|
@ -1892,6 +1915,11 @@ void Sema::ActOnAtEnd(SourceRange AtEnd,
|
|||
if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
|
||||
ImplMethodsVsClassMethods(IC, IDecl);
|
||||
AtomicPropertySetterGetterRules(IC, IDecl);
|
||||
if (LangOpts.ObjCNonFragileABI2)
|
||||
while (IDecl->getSuperClass()) {
|
||||
DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
|
||||
IDecl = IDecl->getSuperClass();
|
||||
}
|
||||
}
|
||||
} else if (ObjCCategoryImplDecl* CatImplClass =
|
||||
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
|
||||
|
||||
@interface Root @end
|
||||
|
||||
@interface SuperClass : Root
|
||||
{
|
||||
int iSuper; // expected-note {{previous declaration is here}}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface SubClass : SuperClass {
|
||||
int ivar; // expected-error {{duplicate member 'ivar'}}
|
||||
int another_ivar; // expected-error {{duplicate member 'another_ivar'}}
|
||||
int iSuper; // expected-error {{duplicate member 'iSuper'}}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface SuperClass () {
|
||||
int ivar; // expected-note {{previous declaration is here}}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Root () {
|
||||
int another_ivar; // expected-note {{previous declaration is here}}
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SubClass
|
||||
-(int) method {
|
||||
return self->ivar; // would be ambiguous if the duplicate ivar were allowed
|
||||
}
|
||||
@end
|
Loading…
Reference in New Issue