Hi Richard, it looks like this commit causes an assertion failure in Sema when mixing PCH and modules. The following script is the smallest reproduction I could come up with. Could you please have a look?
$ cat ../repro.sh mkdir -p usr/include mkdir -p usr/include/bsm mkdir -p usr/include/netinet mkdir -p usr/include/netinet6 echo 'module Darwin { module in { header "netinet/in.h" exclude header "netinet6/in6.h" } umbrella header "bsm/libbsm.h" }' > usr/include/module.modulemap echo 'typedef struct __darwin_ucontext ucontext_t;' > usr/include/bsm/libbsm.h echo 'struct sockaddr_in6;' >> usr/include/bsm/libbsm.h echo '#include <netinet6/in6.h>' > usr/include/netinet/in.h echo 'struct sockaddr_in6 {};' > usr/include/netinet6/in6.h echo '#include <netinet/in.h>' > prefix.pch echo '#include <netinet/in.h> @interface I {} + (void):(struct sockaddr_in6 *)s; @end @implementation I + (void):(struct sockaddr_in6*)s {}; @end struct sockaddr_in6 *f() {}' > test.m CC=clang $CC -x objective-c-header -arch x86_64 -fmodules -c prefix.pch -o prefix.pch.pch -I. -fmodules-cache-path=cache -isysroot $PWD $CC -x objective-c -arch x86_64 -fmodules -c test.m -o test.o -include-pch prefix.pch.pch -I. -fmodules-cache-path=cache -isysroot $PWD sh ../repro.sh test.m:4:18: warning: declaration of 'struct sockaddr_in6' will not be visible outside of this function [-Wvisibility] + (void):(struct sockaddr_in6 *)s; ^ test.m:7:18: warning: declaration of 'struct sockaddr_in6' will not be visible outside of this function [-Wvisibility] + (void):(struct sockaddr_in6*)s {}; ^ test.m:3:12: warning: class 'I' defined without specifying a base class [-Wobjc-root-class] @interface I {} ^ test.m:3:13: note: add a super class to fix this problem @interface I {} ^ Assertion failed: (I != Vec.end() && "list does not contain decl"), function remove, file ../tools/clang/include/clang/AST/DeclContextInternals.h, line 116. 0 clang-3.8 0x000000010ec886ae llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46 1 clang-3.8 0x000000010ec88af9 PrintStackTraceSignalHandler(void*) + 25 2 clang-3.8 0x000000010ec85299 llvm::sys::RunSignalHandlers() + 425 3 clang-3.8 0x000000010ec88e59 SignalHandler(int) + 345 4 libsystem_platform.dylib 0x00007fff9700a30a _sigtramp + 26 5 clang-3.8 0x000000011273dbf5 guard variable for shouldAddRequirement(clang::Module*, llvm::StringRef, bool&)::IOKitAVC + 82405 6 clang-3.8 0x000000010ec88b1b raise + 27 7 clang-3.8 0x000000010ec88bd2 abort + 18 8 clang-3.8 0x000000010ec88bb1 __assert_rtn + 129 9 clang-3.8 0x0000000111b8f989 clang::StoredDeclsList::remove(clang::NamedDecl*) + 537 10 clang-3.8 0x0000000111b8b18c clang::DeclContext::removeDecl(clang::Decl*) + 1068 11 clang-3.8 0x0000000111b5e725 clang::FunctionDecl::setDeclsInPrototypeScope(llvm::ArrayRef<clang::NamedDecl*>) + 677 12 clang-3.8 0x0000000110bec4e2 clang::Sema::ActOnFunctionDeclarator(clang::Scope*, clang::Declarator&, clang::DeclContext*, clang::TypeSourceInfo*, clang::LookupResult&, llvm::MutableArrayRef<clang::TemplateParameterList*>, bool&) + 9874 13 clang-3.8 0x0000000110be8c93 clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>) + 3379 14 clang-3.8 0x0000000110c01e07 clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>, clang::Sema::SkipBodyInfo*) + 295 15 clang-3.8 0x00000001107362af clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) + 2303 16 clang-3.8 0x00000001106799f8 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, unsigned int, clang::SourceLocation*, clang::Parser::ForRangeInit*) + 1048 17 clang-3.8 0x000000011073599b clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) + 1163 18 clang-3.8 0x0000000110735125 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) + 197 19 clang-3.8 0x00000001107348dd clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) + 3469 20 clang-3.8 0x0000000110733b06 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) + 1030 21 clang-3.8 0x00000001106611c5 clang::ParseAST(clang::Sema&, bool, bool) + 1013 22 clang-3.8 0x000000010f77408f clang::ASTFrontendAction::ExecuteAction() + 511 23 clang-3.8 0x000000010f21de55 clang::CodeGenAction::ExecuteAction() + 10501 24 clang-3.8 0x000000010f7735f0 clang::FrontendAction::Execute() + 112 25 clang-3.8 0x000000010f6c3751 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 1873 26 clang-3.8 0x000000010f80380a clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 4410 27 clang-3.8 0x000000010d14bb3e cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 4926 28 clang-3.8 0x000000010d13b72f ExecuteCC1Tool(llvm::ArrayRef<char const*>, llvm::StringRef) + 479 29 clang-3.8 0x000000010d13928d main + 3245 30 libdyld.dylib 0x00007fff96e10489 start + 1 Stack dump: thanks! adrian > On Jan 5, 2016, at 7:52 PM, Richard Smith via cfe-commits > <cfe-commits@lists.llvm.org> wrote: > > Author: rsmith > Date: Tue Jan 5 21:52:10 2016 > New Revision: 256907 > > URL: http://llvm.org/viewvc/llvm-project?rev=256907&view=rev > Log: > [modules] When a tag type that was imported from a module is referenced via an > elaborated-type-specifier, create a declaration of it to track that the > current > module makes it visible too. > > Added: > cfe/trunk/test/Modules/tag-injection.cpp > Modified: > cfe/trunk/lib/Sema/SemaDecl.cpp > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=256907&r1=256906&r2=256907&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 5 21:52:10 2016 > @@ -12277,16 +12277,35 @@ Decl *Sema::ActOnTag(Scope *S, unsigned > if (!Invalid) { > // If this is a use, just return the declaration we found, unless > // we have attributes. > - > - // FIXME: In the future, return a variant or some other clue > - // for the consumer of this Decl to know it doesn't own it. > - // For our current ASTs this shouldn't be a problem, but will > - // need to be changed with DeclGroups. > - if (!Attr && > - ((TUK == TUK_Reference && > - (!PrevTagDecl->getFriendObjectKind() || > getLangOpts().MicrosoftExt)) > - || TUK == TUK_Friend)) > - return PrevTagDecl; > + if (TUK == TUK_Reference || TUK == TUK_Friend) { > + if (Attr) { > + // FIXME: Diagnose these attributes. For now, we create a new > + // declaration to hold them. > + } else if (TUK == TUK_Reference && > + (PrevTagDecl->getFriendObjectKind() == > + Decl::FOK_Undeclared || > + getOwningModule(PrevDecl) != > + PP.getModuleContainingLocation(KWLoc)) && > + SS.isEmpty()) { > + // This declaration is a reference to an existing entity, but > + // has different visibility from that entity: it either makes > + // a friend visible or it makes a type visible in a new module. > + // In either case, create a new declaration. We only do this if > + // the declaration would have meant the same thing if no prior > + // declaration were found, that is, if it was found in the same > + // scope where we would have injected a declaration. > + DeclContext *InjectedDC = CurContext; > + while (!InjectedDC->isFileContext() && > + !InjectedDC->isFunctionOrMethod()) > + InjectedDC = InjectedDC->getParent(); > + if (!InjectedDC->getRedeclContext()->Equals( > + PrevDecl->getDeclContext()->getRedeclContext())) > + return PrevTagDecl; > + // This is in the injected scope, create a new declaration. > + } else { > + return PrevTagDecl; > + } > + } > > // Diagnose attempts to redefine a tag. > if (TUK == TUK_Definition) { > > Added: cfe/trunk/test/Modules/tag-injection.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/tag-injection.cpp?rev=256907&view=auto > ============================================================================== > --- cfe/trunk/test/Modules/tag-injection.cpp (added) > +++ cfe/trunk/test/Modules/tag-injection.cpp Tue Jan 5 21:52:10 2016 > @@ -0,0 +1,22 @@ > +// RUN: rm -rf %t > +// RUN: mkdir %t > +// RUN: touch %t/a.h > +// RUN: echo 'struct X {};' > %t/b.h > +// RUN: echo 'module X { module a { header "a.h" } module b { header "b.h" } > }' > %t/x.modulemap > +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ > -fmodule-map-file=%t/x.modulemap %s -I%t -verify > -fmodules-local-submodule-visibility -std=c++11 > + > +#include "a.h" > + > +struct A { > + // This use of 'struct X' makes the declaration (but not definition) of X > visible. > + virtual void f(struct X *p); > +}; > + > +namespace N { > + struct B : A { > + void f(struct X *q) override; > + }; > +} > + > +X x; // expected-error {{definition of 'X' must be imported from module > 'X.b' before it is required}} > +// expected-note@b.h:1 {{here}} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits