Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?
-- >8 --
Here we are in a generic lambda and want to process a call to
identifier_of. Since it's a generic lambda, the lambda's operator()
is a template. eval_identifier_of calls build_special_member_call
which calls build_new_method_call which, in a template, creates:
call = (build_min_non_dep_call_vec
(call,
build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
orig_instance, orig_fns, NULL_TREE),
orig_args));
but that can't be evaluated by cxx_eval_constant_expression that we
call after process_metafunction. (In this test, we are called from
tsubst_lambda_expr -> finish_if_stmt_cond -> cxx_constant_value.)
Since in process_metafunction we shouldn't encounter calls that are
instantiation-dependent, a simple fix is to force a non-template
context. To be sure I ran a full regtest with
gcc_checking_assert (!instantiation_dependent_expression_p (call));
just before the sentinel and found no problems.
PR c++/127749
gcc/cp/ChangeLog:
* reflect.cc (process_metafunction): Add
processing_template_decl_sentinel.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/dep17.C: New test.
---
gcc/cp/reflect.cc | 6 ++++++
gcc/testsuite/g++.dg/reflect/dep17.C | 30 ++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/reflect/dep17.C
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 8bf518df64f..2ebedc3b41c 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -8152,6 +8152,12 @@ process_metafunction (const constexpr_ctx *ctx, tree
fun, tree call,
gcc_unreachable ();
}
+ /* Some of the eval_ functions build new trees and in a template
+ that could produce template trees. The subsequent evaluation
+ cannot process such trees, though, so force a non-template
+ context. This assumes that the call is not instantiation-dependent. */
+ processing_template_decl_sentinel ptds;
+
switch (minfo->code)
{
case METAFN_OPERATOR_OF:
diff --git a/gcc/testsuite/g++.dg/reflect/dep17.C
b/gcc/testsuite/g++.dg/reflect/dep17.C
new file mode 100644
index 00000000000..04bdd7928e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/dep17.C
@@ -0,0 +1,30 @@
+// PR c++/127749
+// { dg-do compile { target c++26 } }
+// { dg-options "-freflection" }
+
+#include <meta>
+
+struct S {
+ int mem = 0;
+};
+
+template<std::meta::info member>
+auto constexpr inline fn = [](auto...) {
+ static_assert(std::meta::identifier_of(member) == "mem");
+ if constexpr (std::meta::identifier_of(member) == "mem")
+ throw 0;
+};
+
+template<std::meta::info member>
+auto constexpr inline fn2 = []() {
+ static_assert(std::meta::identifier_of(member) == "mem");
+ if constexpr (std::meta::identifier_of(member) == "mem")
+ throw 0;
+};
+
+void
+g ()
+{
+ fn<^^S::mem>();
+ fn2<^^S::mem>();
+}
base-commit: baea2a0be30d843febce3b40543aa93f91018444
--
2.56.0