aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--lib/Sema/SemaDeclObjC.cpp5
-rw-r--r--test/Sema/anonymous-struct-union.c3
-rw-r--r--test/Sema/nested-redef.c3
-rw-r--r--test/SemaObjC/interface-1.m10
-rw-r--r--test/SemaObjC/ivar-sem-check-1.m3
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}}