On 3/2/26 11:21 AM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
-- >8 --
This testcase didn't compile properly because eval_is_function and
eval_extract got an unresolved TEMPLATE_ID_EXPR. We used to resolve
them in process_metafunction but I removed that call, thinking it was
no longer necessary. This patch puts it back.
Why isn't it resolved by substitute?
PR c++/124324
gcc/cp/ChangeLog:
* reflect.cc (process_metafunction): Call resolve_nondeduced_context.
Move variable declarations closer to their first use.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/extract11.C: New test.
---
gcc/cp/reflect.cc | 41 +++++++++++++-----------
gcc/testsuite/g++.dg/reflect/extract11.C | 18 +++++++++++
2 files changed, 40 insertions(+), 19 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/reflect/extract11.C
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 09b0632a619..974228bccc5 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -7344,7 +7344,7 @@ process_metafunction (const constexpr_ctx *ctx, tree fun,
tree call,
return NULL_TREE;
}
tree h = NULL_TREE, h1 = NULL_TREE, hvec = NULL_TREE, expr = NULL_TREE;
- tree type = NULL_TREE, ht, info;
+ tree type = NULL_TREE;
reflect_kind kind = REFLECT_UNDEF;
for (int argno = 0; argno < 3; ++argno)
switch (METAFN_KIND_ARG (argno))
@@ -7353,24 +7353,27 @@ process_metafunction (const constexpr_ctx *ctx, tree
fun, tree call,
break;
case METAFN_KIND_ARG_INFO:
case METAFN_KIND_ARG_TINFO:
- gcc_assert (argno < 2);
- info = get_info (ctx, call, argno, non_constant_p, overflow_p,
- jump_target);
- if (*jump_target || *non_constant_p)
- return NULL_TREE;
- ht = REFLECT_EXPR_HANDLE (info);
- if (METAFN_KIND_ARG (argno) == METAFN_KIND_ARG_TINFO
- && eval_is_type (ht) != boolean_true_node)
- return throw_exception_nontype (loc, ctx, fun, non_constant_p,
- jump_target);
- if (argno == 0)
- {
- kind = REFLECT_EXPR_KIND (info);
- h = ht;
- }
- else
- h1 = ht;
- break;
+ {
+ gcc_assert (argno < 2);
+ tree info = get_info (ctx, call, argno, non_constant_p, overflow_p,
+ jump_target);
+ if (*jump_target || *non_constant_p)
+ return NULL_TREE;
+ tree ht = REFLECT_EXPR_HANDLE (info);
+ if (METAFN_KIND_ARG (argno) == METAFN_KIND_ARG_TINFO
+ && eval_is_type (ht) != boolean_true_node)
+ return throw_exception_nontype (loc, ctx, fun, non_constant_p,
+ jump_target);
+ ht = resolve_nondeduced_context (ht, complain_flags (ctx));
+ if (argno == 0)
+ {
+ kind = REFLECT_EXPR_KIND (info);
+ h = ht;
+ }
+ else
+ h1 = ht;
+ break;
+ }
case METAFN_KIND_ARG_REFLECTION_RANGE:
gcc_assert (argno == 1);
hvec = get_info_vec (loc, ctx, call, argno, non_constant_p,
diff --git a/gcc/testsuite/g++.dg/reflect/extract11.C
b/gcc/testsuite/g++.dg/reflect/extract11.C
new file mode 100644
index 00000000000..054cdde19df
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/extract11.C
@@ -0,0 +1,18 @@
+// PR c++/124324
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+consteval std::meta::info worst_sizeof_p1(std::meta::info ty) {
+ static constexpr auto lam = []<class T>() static { return sizeof(T); };
+ return substitute(^^decltype(lam)::template operator(), {ty});
+}
+
+constexpr std::meta::info ws = worst_sizeof_p1(^^int);
+static_assert([: ws :]() == 4);
+static_assert(is_function(ws));
+static_assert(is_static_member(ws));
+
+using F = size_t();
+constexpr F* f = extract<F*>(ws);
base-commit: 1f9879e17466f5bcb583dd7bac8bae68b57ac31f