diff options
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 51 | ||||
-rw-r--r-- | test/SemaObjC/alias-test-2.m | 4 | ||||
-rw-r--r-- | test/SemaObjCXX/objc-extern-c.mm | 30 |
3 files changed, 64 insertions, 21 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 592d7c231e..fe9a7841cf 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -373,9 +373,15 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName(); Diag(IDecl->getLocation(), diag::note_previous_definition); - // Return the previous class interface. - // FIXME: don't leak the objects passed in! - return ActOnObjCContainerStartDefinition(IDecl); + // Create a new one; the other may be in a different DeclContex, (e.g. + // this one may be in a LinkageSpecDecl while the other is not) which + // will break invariants. + IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, + ClassName, ClassLoc); + if (AttrList) + ProcessDeclAttributeList(TUScope, IDecl, AttrList); + PushOnScopeChains(IDecl, TUScope); + } else { IDecl->setLocation(ClassLoc); IDecl->setAtStartLoc(AtInterfaceLoc); @@ -575,23 +581,30 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, if (!PDecl->isForwardDecl()) { Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName; Diag(PDecl->getLocation(), diag::note_previous_definition); - // Just return the protocol we already had. - // FIXME: don't leak the objects passed in! - return ActOnObjCContainerStartDefinition(PDecl); + + // Create a new one; the other may be in a different DeclContex, (e.g. + // this one may be in a LinkageSpecDecl while the other is not) which + // will break invariants. + // We will not add it to scope chains to ignore it as the warning says. + PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, + ProtocolLoc, AtProtoInterfaceLoc, + /*isForwardDecl=*/false); + + } else { + ObjCList<ObjCProtocolDecl> PList; + PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); + err = CheckForwardProtocolDeclarationForCircularDependency( + ProtocolName, ProtocolLoc, PDecl->getLocation(), PList); + + // Make sure the cached decl gets a valid start location. + PDecl->setAtStartLoc(AtProtoInterfaceLoc); + PDecl->setLocation(ProtocolLoc); + // Since this ObjCProtocolDecl was created by a forward declaration, + // we now add it to the DeclContext since it wasn't added before + PDecl->setLexicalDeclContext(CurContext); + CurContext->addDecl(PDecl); + PDecl->completedForwardDecl(); } - ObjCList<ObjCProtocolDecl> PList; - PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context); - err = CheckForwardProtocolDeclarationForCircularDependency( - ProtocolName, ProtocolLoc, PDecl->getLocation(), PList); - - // Make sure the cached decl gets a valid start location. - PDecl->setAtStartLoc(AtProtoInterfaceLoc); - PDecl->setLocation(ProtocolLoc); - // Since this ObjCProtocolDecl was created by a forward declaration, - // we now add it to the DeclContext since it wasn't added before - PDecl->setLexicalDeclContext(CurContext); - CurContext->addDecl(PDecl); - PDecl->completedForwardDecl(); } else { PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName, ProtocolLoc, AtProtoInterfaceLoc, diff --git a/test/SemaObjC/alias-test-2.m b/test/SemaObjC/alias-test-2.m index 1f12b76055..0c186885a3 100644 --- a/test/SemaObjC/alias-test-2.m +++ b/test/SemaObjC/alias-test-2.m @@ -9,9 +9,9 @@ @compatibility_alias AliasForSuper Super; -@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}} +@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}} @end -@implementation MyAlias : AliasForSuper // expected-error {{conflicting super class name 'Super'}} +@interface MyAlias : AliasForSuper // expected-error {{duplicate interface definition for class 'MyWpModule'}} @end diff --git a/test/SemaObjCXX/objc-extern-c.mm b/test/SemaObjCXX/objc-extern-c.mm new file mode 100644 index 0000000000..6bd37610ae --- /dev/null +++ b/test/SemaObjCXX/objc-extern-c.mm @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@protocol P // expected-note {{previous}} +-(void)meth1; +@end + +@interface I // expected-note {{previous}} +@end + +@interface I2 +@end +@interface I2(C) // expected-note {{previous}} +@end + +extern "C" { +@protocol P // expected-warning {{duplicate protocol definition of 'P' is ignored}} +-(void)meth2; +@end + +@interface I // expected-error {{duplicate}} +@end + +@interface I2(C) // expected-warning {{duplicate}} +@end +} + +void test(id<P> p) { + [p meth1]; + [p meth2]; // expected-warning {{not found}} +} |