diff options
| author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-03-11 11:36:17 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-11 11:36:17 +0800 |
| commit | 612e4e9d6daff61eb480b9b3d9ca47f33168772e (patch) | |
| tree | c2c01e9c4000382da09beab8460ac37212ffa6cf | |
| parent | ab6f470675ed31e5ed1494f6521c3d477c537392 (diff) | |
[C++20] [Modules] Instantiate pending instantiations when GMF ends (#126842)
Close https://github.com/llvm/llvm-project/issues/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.
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 8 | ||||
| -rw-r--r-- | clang/test/Modules/pr125999.cppm | 33 |
2 files changed, 39 insertions, 2 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index b3fba097999f..93a2d797679d 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1105,9 +1105,13 @@ void Sema::ActOnStartOfTranslationUnit() { } void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) { - // No explicit actions are required at the end of the global module fragment. - if (Kind == TUFragmentKind::Global) + if (Kind == TUFragmentKind::Global) { + // Perform Pending Instantiations at the end of global module fragment so + // that the module ownership of TU-level decls won't get messed. + llvm::TimeTraceScope TimeScope("PerformPendingInstantiations"); + PerformPendingInstantiations(); return; + } // Transfer late parsed template instantiations over to the pending template // instantiation list. During normal compilation, the late template parser diff --git a/clang/test/Modules/pr125999.cppm b/clang/test/Modules/pr125999.cppm new file mode 100644 index 000000000000..a859ce759260 --- /dev/null +++ b/clang/test/Modules/pr125999.cppm @@ -0,0 +1,33 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/foo.cppm -verify -fsyntax-only + +//--- bar.h +template <typename T> +struct Singleton { + static T* instance_; + static T* get() { + static bool init = false; + if (!init) { + init = true; + instance_ = ::new T(); + } + return instance_; + } +}; + +template <typename T> +T* Singleton<T>::instance_ = nullptr; + +struct s{}; +inline void* foo() { + return Singleton<s>::get(); +} + +//--- foo.cppm +// expected-no-diagnostics +module; +#include "bar.h" +export module foo; |
