r256907 - [modules] When a tag type that was imported from a module is referenced via an

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 1 12:41:18 PST 2016


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 at 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 at b.h:1 {{here}}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list