diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 8 | ||||
| -rw-r--r-- | clang/test/Modules/tag-injection.c | 18 | ||||
| -rw-r--r-- | clang/test/Sema/decl-in-prototype.c | 3 |
3 files changed, 25 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 66c0e059d4b..f95d1068cc5 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12316,7 +12316,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } else if (TUK == TUK_Reference && (PrevTagDecl->getFriendObjectKind() == Decl::FOK_Undeclared || - getOwningModule(PrevDecl) != + PP.getModuleContainingLocation( + PrevDecl->getLocation()) != PP.getModuleContainingLocation(KWLoc)) && SS.isEmpty()) { // This declaration is a reference to an existing entity, but @@ -12326,8 +12327,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // 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. - if (!getTagInjectionContext(CurContext) - ->getRedeclContext() + if (!getTagInjectionContext(CurContext)->getRedeclContext() ->Equals(PrevDecl->getDeclContext()->getRedeclContext())) return PrevTagDecl; // This is in the injected scope, create a new declaration in @@ -12634,7 +12634,7 @@ CreateNewDecl: << Name; Invalid = true; } - } else { + } else if (!PrevDecl) { Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); } DeclsInPrototypeScope.push_back(New); diff --git a/clang/test/Modules/tag-injection.c b/clang/test/Modules/tag-injection.c new file mode 100644 index 00000000000..5bb15477e2e --- /dev/null +++ b/clang/test/Modules/tag-injection.c @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: echo 'struct a;' > %t/a.h +// RUN: echo 'struct b {}; void foo(struct b*);' > %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 -fmodule-map-file=%t/x.modulemap %s -I%t -verify + +#include "a.h" + +void f(struct a *p); + +// FIXME: We should warn that 'b' will not be visible outside of this function, +// but we merge this 'b' with X.b's 'b' because we don't yet implement C's +// "compatible types" rule. +void g(struct b *p); + +struct b b; // expected-error {{definition of 'b' must be imported from module 'X.b' before it is required}} +// expected-note@b.h:1 {{here}} diff --git a/clang/test/Sema/decl-in-prototype.c b/clang/test/Sema/decl-in-prototype.c index 4f581aa54e5..3b8a3b86037 100644 --- a/clang/test/Sema/decl-in-prototype.c +++ b/clang/test/Sema/decl-in-prototype.c @@ -35,3 +35,6 @@ void f6(struct z {int b;} c) { // expected-warning {{declaration of 'struct z' w void pr19018_1 (enum e19018 { qq } x); // expected-warning{{declaration of 'enum e19018' will not be visible outside of this function}} enum e19018 qq; //expected-error{{tentative definition has type 'enum e19018' that is never completed}} \ //expected-note{{forward declaration of 'enum e19018'}} + +// Only warn once, even if we create two declarations. +void f(struct q *, struct __attribute__((aligned(4))) q *); // expected-warning {{will not be visible outside}} |

