https://github.com/wx257osn2 updated 
https://github.com/llvm/llvm-project/pull/196791

>From adbf863c01a830dbed6dae82c7ce45ede7cd424d Mon Sep 17 00:00:00 2001
From: "A. Jiang" <[email protected]>
Date: Sun, 10 May 2026 18:12:15 +0900
Subject: [PATCH 1/5] add test

https://github.com/llvm/llvm-project/issues/175831#issuecomment-3753235470
---
 clang/test/SemaTemplate/concepts.cpp | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 1b7cfc96243ef..c5fe4969a36b6 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1836,7 +1836,6 @@ namespace GH191016 {
   void test(){ S<int> s; }
 }
 
-
 namespace GH188640 {
 
 namespace Ex1 {
@@ -1880,3 +1879,21 @@ void g() { static_assert(f<1>() == 42); }
 } // namespace VAR
 
 } // namespace GH188640
+
+namespace GH175831 {
+
+template<class>
+struct reference {};
+template<class Q>
+consteval Q get_spec(reference<Q>) { return {}; }
+
+template<class T>
+concept repr_impl = sizeof(T) > 0;
+template<class, auto V>
+concept representation_of = repr_impl<decltype(V)>;
+template<auto V, representation_of<get_spec(V)>>
+struct quantity {};
+
+auto x = quantity<reference<int>{}, int>{};
+
+} // namespace GH175831

>From 31900217d9c19ab01b7ff4e1cf1b2339419c734e Mon Sep 17 00:00:00 2001
From: I <[email protected]>
Date: Sun, 10 May 2026 18:21:56 +0900
Subject: [PATCH 2/5] stop replacement on unevaluated context

---
 clang/lib/Sema/TreeTransform.h | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 40187f71231bd..efaff4c0e02ec 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16736,13 +16736,23 @@ ExprResult 
TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
     // specific annotations, such as implicit casts, are discarded. Calling the
     // corresponding sema action is necessary to recover those. Otherwise,
     // equivalency of the result would be lost.
+    //
+    // In unevaluated contexts (e.g. inside decltype), CheckTemplateArgument
+    // forces constant evaluation that is inappropriate and may fail for
+    // valid expressions (e.g. function calls with by-value class parameters).
+    // Since we only need the type in such contexts, we can tolerate the
+    // failure and proceed with the transformed replacement as-is.
     TemplateArgument SugaredConverted, CanonicalConverted;
-    Replacement = SemaRef.CheckTemplateArgument(
+    ExprResult Checked = SemaRef.CheckTemplateArgument(
         Param, ParamType, Replacement.get(), SugaredConverted,
         CanonicalConverted,
         /*StrictCheck=*/false, Sema::CTAK_Specified);
-    if (Replacement.isInvalid())
-      return true;
+    if (Checked.isInvalid()) {
+      if (!SemaRef.isUnevaluatedContext())
+        return true;
+    } else {
+      Replacement = Checked;
+    }
   } else {
     // Otherwise, the same expression would have been produced.
     Replacement = E->getReplacement();

>From ecba5c863914869feb81798efb15b52df904e12c Mon Sep 17 00:00:00 2001
From: I <[email protected]>
Date: Sun, 10 May 2026 18:47:44 +0900
Subject: [PATCH 3/5] add release note

---
 clang/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c17143e3c0398..6c2cecfb7dc20 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -543,6 +543,7 @@ Bug Fixes in This Version
 - Fixed a crash when parsing invalid ``static_assert`` declarations with 
string-literal messages (#GH187690).
 - Fixed a potential stack-use-after-return issue in Clang when 
copy-initializing
   an array via an element-at-a-time copy loop (#GH192026)
+- Fixed a regression where calling a function that takes a class-type 
parameter by value inside ``decltype`` of a concept could be incorrectly 
rejected when used as a non-type template argument. (#GH175831)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>From a4cc6b698973d52a81851b47037cf3931e97d360 Mon Sep 17 00:00:00 2001
From: I <[email protected]>
Date: Mon, 11 May 2026 20:49:25 +0900
Subject: [PATCH 4/5] add test

---
 clang/test/SemaTemplate/concepts.cpp | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index c5fe4969a36b6..cc7fa50f13bf5 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1882,6 +1882,8 @@ void g() { static_assert(f<1>() == 42); }
 
 namespace GH175831 {
 
+namespace ShuoldResolve {
+
 template<class>
 struct reference {};
 template<class Q>
@@ -1896,4 +1898,28 @@ struct quantity {};
 
 auto x = quantity<reference<int>{}, int>{};
 
+} // namespace ShouldResolve
+
+namespace CannotResolve {
+
+template<class>
+struct reference {};
+template<class Q>
+consteval auto get_spec(reference<Q>) { return Q{}; }
+
+template<class T>
+concept repr_impl = sizeof(T) > sizeof(char);
+template<class, auto V>
+concept representation_of = repr_impl<decltype(V)>;
+template<auto V, representation_of<get_spec(V)>>
+struct quantity {};
+
+auto x = quantity<reference<char>{}, char>{};
+// expected-error@-1 {{constraints not satisfied for class template 'quantity' 
[with V = reference<char>{}, $1 = char]}}
+// expected-note@-5  {{because 'representation_of<char, 
get_spec(reference<char>{})>' evaluated to false}}
+// expected-note-re@-7  {{because 'decltype({{.*}})' (aka 'char') does not 
satisfy 'repr_impl'}}
+// expected-note@-10  {{because 'sizeof(char) > sizeof(char)' (1 > 1) 
evaluated to false}}
+
+} // namespace CannotResolve
+
 } // namespace GH175831

>From 315ef2b0fc0903e1b56e64c746187ae38454c240 Mon Sep 17 00:00:00 2001
From: I <[email protected]>
Date: Mon, 11 May 2026 20:57:21 +0900
Subject: [PATCH 5/5] check evaluated context or not before calling
 CheckTemplateArgument

---
 clang/lib/Sema/TreeTransform.h | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index efaff4c0e02ec..5fea685acea74 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16736,22 +16736,14 @@ ExprResult 
TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
     // specific annotations, such as implicit casts, are discarded. Calling the
     // corresponding sema action is necessary to recover those. Otherwise,
     // equivalency of the result would be lost.
-    //
-    // In unevaluated contexts (e.g. inside decltype), CheckTemplateArgument
-    // forces constant evaluation that is inappropriate and may fail for
-    // valid expressions (e.g. function calls with by-value class parameters).
-    // Since we only need the type in such contexts, we can tolerate the
-    // failure and proceed with the transformed replacement as-is.
-    TemplateArgument SugaredConverted, CanonicalConverted;
-    ExprResult Checked = SemaRef.CheckTemplateArgument(
-        Param, ParamType, Replacement.get(), SugaredConverted,
-        CanonicalConverted,
-        /*StrictCheck=*/false, Sema::CTAK_Specified);
-    if (Checked.isInvalid()) {
-      if (!SemaRef.isUnevaluatedContext())
+    if (!SemaRef.isUnevaluatedContext()) {
+      TemplateArgument SugaredConverted, CanonicalConverted;
+      Replacement = SemaRef.CheckTemplateArgument(
+          Param, ParamType, Replacement.get(), SugaredConverted,
+          CanonicalConverted,
+          /*StrictCheck=*/false, Sema::CTAK_Specified);
+      if (Replacement.isInvalid())
         return true;
-    } else {
-      Replacement = Checked;
     }
   } else {
     // Otherwise, the same expression would have been produced.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to