Skip to content

Commit 5f62c79

Browse files
committed
[C++20] [Modules] Use current named module to do module local lookup
See the attached test for the motiviation. Previously we dependent on the module ownership of the decl context to perform module local lookup. But if the lookup is unqualified, we may perform the lookup with canonical decl, which belongs to the incorrect named module
1 parent ca0b566 commit 5f62c79

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

clang/lib/Serialization/ASTReader.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8564,14 +8564,22 @@ bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
85648564
Find(It->second.Table, Name);
85658565
}
85668566

8567-
if (auto *NamedModule =
8568-
OriginalDC ? cast<Decl>(OriginalDC)->getTopLevelOwningNamedModule()
8569-
: nullptr) {
8567+
auto FindModuleLocalLookup = [&, this](Module *NamedModule) {
85708568
if (auto It = ModuleLocalLookups.find(DC); It != ModuleLocalLookups.end()) {
85718569
++NumModuleLocalVisibleDeclContexts;
85728570
Find(It->second.Table, std::make_pair(Name, NamedModule));
85738571
}
8574-
}
8572+
};
8573+
if (auto *NamedModule =
8574+
OriginalDC ? cast<Decl>(OriginalDC)->getTopLevelOwningNamedModule()
8575+
: nullptr)
8576+
FindModuleLocalLookup(NamedModule);
8577+
// See clang/test/Modules/ModulesLocalNamespace.cppm for the motiviation case.
8578+
// We're going to find a decl but the decl context of the lookup is
8579+
// unspecified. In this case, the OriginalDC may be the decl context in other
8580+
// module.
8581+
if (ContextObj && ContextObj->getCurrentNamedModule())
8582+
FindModuleLocalLookup(ContextObj->getCurrentNamedModule());
85758583

85768584
if (auto It = TULocalLookups.find(DC); It != TULocalLookups.end()) {
85778585
++NumTULocalVisibleDeclContexts;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/m-a.cppm -emit-module-interface -o %t/m-a.pcm
7+
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-module-interface -o %t/m-b.pcm \
8+
// RUN: -fprebuilt-module-path=%t
9+
// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fsyntax-only -verify -fprebuilt-module-path=%t
10+
11+
//--- a.cppm
12+
export module a;
13+
namespace aa {
14+
15+
}
16+
17+
//--- m-a.cppm
18+
export module m:a;
19+
namespace aa {
20+
struct A {};
21+
}
22+
23+
//--- b.cppm
24+
module m:b;
25+
import :a;
26+
27+
namespace bb {
28+
struct B {
29+
void func(aa::A);
30+
};
31+
}
32+
33+
//--- b.cpp
34+
// expected-no-diagnostics
35+
module m:b.impl;
36+
import a;
37+
import :b;
38+
39+
namespace bb {
40+
using namespace aa;
41+
42+
void B::func(A) {}
43+
44+
}
45+
46+
47+

0 commit comments

Comments
 (0)