[clang] [C++20] [Modules] Profiling non dependent noexcept expression by pointer (PR #224528)
Ian Petersen via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 18 08:56:43 PDT 2026
================
@@ -0,0 +1,37 @@
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 -fmodule-file=a=%t/a.pcm -fsyntax-only %t/use.cpp -verify
+//
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/a.cppm -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 -fmodule-file=a=%t/a.pcm -fsyntax-only %t/use.cpp -verify
+
+//--- a.cppm
+export module a;
+template <class> concept C = true;
+
+template <class T> int fn() noexcept(C<T>);
+export using t = decltype(fn<int>());
+
+//--- use.cpp
+// expected-no-diagnostics
+import a;
+
+// During the deserialization process of fn<int>, the C<int> in noexcept expression
+// may be not completely deserialized. This test makes sure that we can handle the case.
+//
+// The ordering is:
+//
+// Deserialize C<int>
+//
+// Deserializing C<int>'s template argument
+//
+// Read SubstTemplateTypeParmType::AssociatedDecl in readSubstTemplateTypeParmType
----------------
ispeters wrote:
> Hmm, do we suffer from the same issue for other things? e.g.
>
> ```c++
> template <class T> int fn() requires (C<T>);
> template <class T> int fn() __attribute__((enable_if(C<T>)));
> ```
Claude helped me write the code at ispeters/llvm-project at a4349a8 (which is a commit ahead of PR #222148) that might be a useful starting point to answering this question. I modifies the `ASTContext` to keep a set of "open" decls that have been created but not yet fully deserialized, and uses that set to count how many times Clang reads trailing objects from those partially-constructed objects. I ran `check-clang` with that build and the only hits were in the new `lit` test that both this PR and #222148 add. When building NVIDIA/stdexec with the instrumentation enabled, I hit the `noexcept` case quite often. Building Vullkan-hpp had no hits. The logs from my runs looked something like this:
Running `ninja check-clang`:
```
CapturedDecl::Params armed 38724 hit 0
ImportDecl::IdentifierLocs armed 334 hit 0
ImplicitConceptSpecializationDecl::Args armed 283 hit 2
TemplateTypeParmDecl::TypeConstraint armed 83 hit 0
OpenACCConstructDecl::Clauses armed 60 hit 0
OutlinedFunctionDecl::Params armed 44 hit 0
ExplicitInstantiationDecl::QualifierLoc armed 28 hit 0
DecompositionDecl::Bindings armed 14 hit 0
CXXConstructorDecl::ExplicitSpecifier armed 14 hit 0
UsingPackDecl::Expansions armed 10 hit 0
ExplicitInstantiationDecl::ArgsAsWritten armed 9 hit 0
PragmaCommentDecl::Arg armed 7 hit 0
CXXConstructorDecl::InheritedConstructor armed 7 hit 0
PragmaDetectMismatchDecl::NameValue armed 6 hit 0
NonTypeTemplateParmDecl::PlaceholderConstraint armed 6 hit 0
TemplateTemplateParmDecl::ExpansionParams armed 4 hit 0
NonTypeTemplateParmDecl::ExpansionTypes armed 4 hit 0
FriendTemplateDecl::TemplateParameterLists armed 4 hit 0
```
Running stdexec's modular build:
```
ImplicitConceptSpecializationDecl::Args armed 52853 hit 1408
TemplateTypeParmDecl::TypeConstraint armed 12014 hit 0
CXXConstructorDecl::ExplicitSpecifier armed 2669 hit 0
CXXConstructorDecl::InheritedConstructor armed 1031 hit 0
DecompositionDecl::Bindings armed 164 hit 0
```
Building Vulkan-hpp:
```
ImplicitConceptSpecializationDecl::Args armed 989 hit 0
TemplateTypeParmDecl::TypeConstraint armed 421 hit 0
CXXConstructorDecl::ExplicitSpecifier armed 49 hit 0
DecompositionDecl::Bindings armed 4 hit 0
```
The code as-is is deliberately quick-and-dirty; it's not thread-safe (and so is apparently in appropriate for use in `clangd`) and writes its report to a temp file with a hardcoded name, but I think the approach could be made more robust if it's interesting.
https://github.com/llvm/llvm-project/pull/224528
More information about the cfe-commits
mailing list