[clang] [Clang] Do not try emitting function body when substituting a constraint (PR #186380)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 13 05:24:01 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Younan Zhang (zyn0217)
<details>
<summary>Changes</summary>
The MS ABI does not appear to have implemented C++20 concept mangling yet. This has led to a bug after CWG2369, where lambdas within a requires body become un-mangleable because the surrounding function templates might not be instantiated.
Previously, we bypassed code emission for such lambdas. However, a lambda can also appear within a template argument, which breaks that workaround.
I really wish for a correct concept implementation in the MS ABI.
Fixes https://github.com/llvm/llvm-project/issues/173160
---
Full diff: https://github.com/llvm/llvm-project/pull/186380.diff
2 Files Affected:
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+6-14)
- (modified) clang/test/CodeGenCXX/ms-mangle-requires.cpp (+34)
``````````diff
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e74c41517ecbf..18a6f199adde6 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5965,20 +5965,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
savedContext.pop();
}
- // We never need to emit the code for a lambda in unevaluated context.
- // We also can't mangle a lambda in the require clause of a function template
- // during constraint checking as the MSI ABI would need to mangle the (not yet
- // specialized) enclosing declaration
- // FIXME: Should we try to skip this for non-lambda functions too?
- bool ShouldSkipCG = [&] {
- auto *RD = dyn_cast<CXXRecordDecl>(Function->getParent());
- if (!RD || !RD->isLambda())
- return false;
-
- return llvm::any_of(ExprEvalContexts, [](auto &Context) {
- return Context.isUnevaluated() || Context.isImmediateFunctionContext();
- });
- }();
+ // We never need to emit the code in constriant substitution.
+ // For example, we can't mangle a lambda in the require clause of a function
+ // template during constraint checking as the MS ABI would need to mangle the
+ // (not yet specialized) enclosing declaration.
+ // FIXME: This can be removed when MS ABI supports concepts.
+ bool ShouldSkipCG = inConstraintSubstitution();
if (!ShouldSkipCG) {
DeclGroupRef DG(Function);
Consumer.HandleTopLevelDecl(DG);
diff --git a/clang/test/CodeGenCXX/ms-mangle-requires.cpp b/clang/test/CodeGenCXX/ms-mangle-requires.cpp
index 88c432c54b117..755b151018fcf 100644
--- a/clang/test/CodeGenCXX/ms-mangle-requires.cpp
+++ b/clang/test/CodeGenCXX/ms-mangle-requires.cpp
@@ -69,3 +69,37 @@ void test() {
}
// CHECK-LABEL:define {{.*}} void @"??$f@$0CK@@GH147650@@YAXXZ"()
}
+
+namespace GH173160 {
+
+template< typename TypeList, typename Func >
+auto for_each_type(Func func) {
+ return func;
+}
+
+template< class T >
+struct X {};
+
+template< class T >
+concept Component = requires(T component) {
+ for_each_type<typename T::required_type>( []{} );
+};
+
+struct EntityRegistry {
+ template< Component C >
+ auto get_component(const int id) -> X<C> {
+ return {};
+ }
+};
+
+struct A {
+ struct required_type {};
+};
+
+void foo() {
+ EntityRegistry entities;
+ entities.get_component<A>(0);
+ // CHECK: define {{.*}} @"??$get_component at UA@GH173160@@@EntityRegistry at GH173160@@QEAA?AU?$X at UA@GH173160@@@1 at H@Z"
+}
+
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/186380
More information about the cfe-commits
mailing list