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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65340
91177308-0d34-0410-b5e6-
96231b3b80d8
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");
}
}
}
- }
- 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);
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);
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.
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)
};
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}}
// 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 { };
++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
+
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}}