]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: void(concept-id) evaluation [PR121822]
authorPatrick Palka <ppalka@redhat.com>
Tue, 17 Feb 2026 16:21:45 +0000 (11:21 -0500)
committerPatrick Palka <ppalka@redhat.com>
Tue, 17 Feb 2026 16:21:45 +0000 (11:21 -0500)
Similar to r16-7056-g22f51c0f5e62a4, here the expression within
the decltype void(Derived<T>) is non-dependent enough that we
instantiate/fold it immediately, during which however convert_to_void
tries to evaluate the concept-id, which fails.  When in an
unevaluated context such as decltype I don't think convert_to_void
should be evaluating concept-ids.

PR c++/121822

gcc/cp/ChangeLog:

* cvt.cc (convert_to_void): Don't evaluate a concept-id
in an unevaluated context.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-decltype6.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/cvt.cc
gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C [new file with mode: 0644]

index fe9b9dc6dd18e56da44b44c42a3fe30ab9b874c1..4042938da5e961b9ea6221a2c14dfc10562782d8 100644 (file)
@@ -1210,7 +1210,7 @@ convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
 
   /* Explicitly evaluate void-converted concept checks since their
      satisfaction may produce ill-formed programs.  */
-   if (concept_check_p (expr))
+   if (concept_check_p (expr) && !cp_unevaluated_operand)
      expr = evaluate_concept_check (expr);
 
   /* Detect using expressions of consteval-only types outside manifestly
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-decltype6.C
new file mode 100644 (file)
index 0000000..03ecc7b
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/121822
+// { dg-do compile { target c++20 } }
+
+template<class...>
+using void_t = void;
+
+template<class T>
+concept Derived = requires { typename T::derived_type; };
+
+template<class T, class = void>
+struct Wrapper;
+
+template<class T>
+struct Wrapper<T, void_t<decltype(void(Derived<T>))>> { };
+
+Wrapper<int> x;