mirror of https://github.com/microsoft/clang.git
[modules] Fix visibility checking for using declarations via ADL.
We want to check whether the using (shadow) declaration itself is visible, not whether its target is visible. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8da894badf
commit
fa26081470
|
@ -3349,16 +3349,24 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isa<UsingShadowDecl>(D))
|
||||
D = cast<UsingShadowDecl>(D)->getTargetDecl();
|
||||
auto *Underlying = D;
|
||||
if (auto *USD = dyn_cast<UsingShadowDecl>(D))
|
||||
Underlying = USD->getTargetDecl();
|
||||
|
||||
if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D))
|
||||
if (!isa<FunctionDecl>(Underlying) &&
|
||||
!isa<FunctionTemplateDecl>(Underlying))
|
||||
continue;
|
||||
|
||||
if (!isVisible(D) && !(D = findAcceptableDecl(*this, D)))
|
||||
continue;
|
||||
if (!isVisible(D)) {
|
||||
D = findAcceptableDecl(*this, D);
|
||||
if (!D)
|
||||
continue;
|
||||
if (auto *USD = dyn_cast<UsingShadowDecl>(D))
|
||||
Underlying = USD->getTargetDecl();
|
||||
}
|
||||
|
||||
Result.insert(D);
|
||||
// FIXME: Preserve D as the FoundDecl.
|
||||
Result.insert(Underlying);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -fno-spell-checking %s
|
||||
// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -DONLY_Y %s
|
||||
|
||||
#pragma clang module build a
|
||||
module a {
|
||||
explicit module x {}
|
||||
explicit module y {}
|
||||
}
|
||||
#pragma clang module contents
|
||||
#pragma clang module begin a.x
|
||||
namespace N {
|
||||
template<typename T> extern int f(T) { return 0; }
|
||||
}
|
||||
#pragma clang module end
|
||||
|
||||
#pragma clang module begin a.y
|
||||
#pragma clang module import a.x
|
||||
using N::f;
|
||||
#pragma clang module end
|
||||
#pragma clang module endbuild
|
||||
|
||||
namespace N { struct A {}; }
|
||||
struct B {};
|
||||
|
||||
#ifndef ONLY_Y
|
||||
#pragma clang module import a.x
|
||||
void test1() {
|
||||
f(N::A());
|
||||
f(B()); // expected-error {{use of undeclared identifier 'f'}}
|
||||
}
|
||||
#else
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
|
||||
#pragma clang module import a.y
|
||||
void test2() {
|
||||
// These are OK even if a.x is not imported.
|
||||
f(N::A());
|
||||
f(B());
|
||||
}
|
Loading…
Reference in New Issue