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
