fix rdar://6611778, a redefinition of an interface was causing an

assertion when the ivars and method list was reset into the existing
interface.  To fix this, mark decls as invalid when they are redefined,
and don't insert ivars/methods into invalid decls.

llvm-svn: 65340
This commit is contained in:
Chris Lattner 2009-02-23 22:00:08 +00:00
parent 12bbe9e144
commit d13b8b55ca
6 changed files with 29 additions and 10 deletions

View File

@ -3665,12 +3665,20 @@ void Sema::ActOnFields(Scope* S,
AttributeList *Attr) {
Decl *EnclosingDecl = static_cast<Decl*>(RecDecl);
assert(EnclosingDecl && "missing record or interface decl");
RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
// If the decl this is being inserted into is invalid, then it may be a
// redeclaration or some other bogus case. Don't try to add fields to it.
if (EnclosingDecl->isInvalidDecl()) {
// FIXME: Deallocate fields?
return;
}
// Verify that all the fields are okay.
unsigned NumNamedMembers = 0;
llvm::SmallVector<FieldDecl*, 32> RecFields;
RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
for (unsigned i = 0; i != NumFields; ++i) {
FieldDecl *FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
assert(FD && "missing field decl");
@ -3782,9 +3790,8 @@ void Sema::ActOnFields(Scope* S,
}
}
}
}
else if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
} else if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");
IMPDecl->setIVarList(ClsFields, RecFields.size(), Context);
CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);

View File

@ -78,6 +78,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
if (IDecl) {
// Class already seen. Is it a forward declaration?
if (!IDecl->isForwardDecl()) {
IDecl->setInvalidDecl();
Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
Diag(IDecl->getLocation(), diag::note_previous_definition);
@ -225,6 +226,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
if (PDecl) {
// Protocol already seen. Better be a forward protocol declaration
if (!PDecl->isForwardDecl()) {
PDecl->setInvalidDecl();
Diag(ProtocolLoc, diag::err_duplicate_protocol_def) << ProtocolName;
Diag(PDecl->getLocation(), diag::note_previous_definition);
// Just return the protocol we already had.
@ -555,8 +557,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
}
else {
} else {
// Is there an interface declaration of this class; if not, warn!
IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (!IDecl)

View File

@ -47,8 +47,7 @@ struct Redecl {
};
int z; // expected-error{{duplicate member 'z'}}
void zz(); // expected-error{{duplicate member 'zz'}} \
// expected-error{{field 'zz' declared as a function}}
void zz(); // expected-error{{duplicate member 'zz'}}
};
union { // expected-error{{anonymous unions must be struct or union members}}

View File

@ -1,6 +1,7 @@
// RUN: clang -fsyntax-only -verify %s
struct X { // expected-note{{previous definition is here}}
struct X { } x; // expected-error{{nested redefinition of 'X'}}
struct X { } x; // expected-error{{nested redefinition of 'X'}} \
expected-error {{field has incomplete type}}
};
struct Y { };

View File

@ -25,3 +25,13 @@ void test2() {
++c;
}
// rdar://6611778
@interface FOO // expected-note {{previous definition is here}}
- (void)method;
@end
@interface FOO // expected-error {{duplicate interface definition for class 'FOO'}}
- (void)method2;
@end

View File

@ -9,7 +9,8 @@ typedef int FOO();
int arr[]; // expected-error {{field has incomplete type}}
struct S IC; // expected-error {{field has incomplete type}}
struct T { // expected-note {{previous definition is here}}
struct T {} X; // expected-error {{nested redefinition of 'T'}}
struct T {} X; // expected-error {{nested redefinition of 'T'}} \
expected-error {{field has incomplete type}}
}YYY;
FOO BADFUNC; // expected-error {{field 'BADFUNC' declared as a function}}
int kaka; // expected-note {{previous declaration is here}}