[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