Skip to content

Commit 612e4e9

Browse files
authored
[C++20] [Modules] Instantiate pending instantiations when GMF ends (#126842)
Close #125999 The cause of the problem is, when we instantiate the pending instantiation, the owning module of the TU gets into 'foo' instead of the GMF. The concern of the patch is, I am not sure the point of 'pending' instantiations. I mean, if there is a reason we **must** pending the intantiations to the end of the TU.
1 parent ab6f470 commit 612e4e9

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

clang/lib/Sema/Sema.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,13 @@ void Sema::ActOnStartOfTranslationUnit() {
11051105
}
11061106

11071107
void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
1108-
// No explicit actions are required at the end of the global module fragment.
1109-
if (Kind == TUFragmentKind::Global)
1108+
if (Kind == TUFragmentKind::Global) {
1109+
// Perform Pending Instantiations at the end of global module fragment so
1110+
// that the module ownership of TU-level decls won't get messed.
1111+
llvm::TimeTraceScope TimeScope("PerformPendingInstantiations");
1112+
PerformPendingInstantiations();
11101113
return;
1114+
}
11111115

11121116
// Transfer late parsed template instantiations over to the pending template
11131117
// instantiation list. During normal compilation, the late template parser

clang/test/Modules/pr125999.cppm

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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/foo.cppm -verify -fsyntax-only
6+
7+
//--- bar.h
8+
template <typename T>
9+
struct Singleton {
10+
static T* instance_;
11+
static T* get() {
12+
static bool init = false;
13+
if (!init) {
14+
init = true;
15+
instance_ = ::new T();
16+
}
17+
return instance_;
18+
}
19+
};
20+
21+
template <typename T>
22+
T* Singleton<T>::instance_ = nullptr;
23+
24+
struct s{};
25+
inline void* foo() {
26+
return Singleton<s>::get();
27+
}
28+
29+
//--- foo.cppm
30+
// expected-no-diagnostics
31+
module;
32+
#include "bar.h"
33+
export module foo;

0 commit comments

Comments
 (0)