diff options
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 5 | ||||
-rw-r--r-- | test/Sema/anonymous-struct-union.c | 3 | ||||
-rw-r--r-- | test/Sema/nested-redef.c | 3 | ||||
-rw-r--r-- | test/SemaObjC/interface-1.m | 10 | ||||
-rw-r--r-- | test/SemaObjC/ivar-sem-check-1.m | 3 |
6 files changed, 29 insertions, 10 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4ec2dc6968..1786b6372b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 660f745228..b3644a5ab9 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -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) diff --git a/test/Sema/anonymous-struct-union.c b/test/Sema/anonymous-struct-union.c index 72790c9abb..b288f6278a 100644 --- a/test/Sema/anonymous-struct-union.c +++ b/test/Sema/anonymous-struct-union.c @@ -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}} diff --git a/test/Sema/nested-redef.c b/test/Sema/nested-redef.c index 83cd420967..b0b12805e6 100644 --- a/test/Sema/nested-redef.c +++ b/test/Sema/nested-redef.c @@ -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 { }; diff --git a/test/SemaObjC/interface-1.m b/test/SemaObjC/interface-1.m index ea77050505..b974b39a3a 100644 --- a/test/SemaObjC/interface-1.m +++ b/test/SemaObjC/interface-1.m @@ -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 + diff --git a/test/SemaObjC/ivar-sem-check-1.m b/test/SemaObjC/ivar-sem-check-1.m index 1ec4e57ce8..1833a0f457 100644 --- a/test/SemaObjC/ivar-sem-check-1.m +++ b/test/SemaObjC/ivar-sem-check-1.m @@ -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}} |