summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-02-23 22:00:08 +0000
committerChris Lattner <sabre@nondot.org>2009-02-23 22:00:08 +0000
commitd13b8b55caaaf968b735bf82e49047d45e73c50b (patch)
tree4c0aa626af7427d6122e405976dc07bb047b2399 /clang/lib
parent12bbe9e144ac48f8c6c7fa59fbe90086dffa05a4 (diff)
downloadbcm5719-llvm-d13b8b55caaaf968b735bf82e49047d45e73c50b.tar.gz
bcm5719-llvm-d13b8b55caaaf968b735bf82e49047d45e73c50b.zip
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
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp5
2 files changed, 14 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4ec2dc6968b..1786b6372b0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 660f745228b..b3644a5ab9c 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/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)
OpenPOWER on IntegriCloud