On 7/13/26 5:52 PM, Marek Polacek wrote:
On Mon, Jul 13, 2026 at 11:57:54AM -0400, Jason Merrill wrote:
On 7/10/26 4:28 PM, Marek Polacek wrote:
On Thu, Jul 09, 2026 at 08:43:42PM -0400, Jason Merrill wrote:
On 7/9/26 5:50 PM, Marek Polacek wrote:
On Wed, Jul 08, 2026 at 08:59:32AM -0400, Jason Merrill wrote:
On 7/7/26 6:16 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?

-- >8 --
We trip on the assert in lvalue_kind/MODOP_EXPR whose comment says
that we expect to see MODOP_EXPRs only during template processing.
In this test we get there with processing_template_decl==0.  The
MODOP_EXPR is created in:

        /* Parse the requirement body. */
        ++processing_template_decl;
        reqs = cp_parser_requirement_body (parser);
        --processing_template_decl;

but we're not in a template when calling maybe_convert_cond which
calls verify_sequence_points which ends up calling lvalue_p on
the MODOP_EXPR.  verify_sequence_points is a c-family/ function
so we couldn't make it stop recursing on REQUIRES_EXPR, so I suppose
we can do the following.

Eh, this just looks like a workaround for a single testcase.

I see several problems here:

1) We're retaining template trees in a non-template function,
2) verify_sequence_points is walking the unevaluated operand of a requires
because verify_tree assumes that all unknown expressions are evaluated, and
3) REQURES_EXPR looks like a normal expression (tcc_expression).

I think the right way to approach this would be to attack 3 by changing
REQUIRES_EXPR to tcc_exceptional.  Then 1 doesn't matter because the generic
code (such as verify_tree) sees that it's magic and doesn't try to walk into
it.

I did this.  It's no longer a trivial patch but it does fix the crash.

Thanks.

We could also attack 2 by defining unevaluated_p in the C front-end as well,
and checking it in verify_tree.  2 also affects other unevaluated codes like
NOEXCEPT_EXPR, potentially leading to wrong -Wsequence-point results.

I did not do this.  If you think I should, I will.

Maybe just add a FIXME next to the SIZEOF_EXPR case?

Done.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
We trip on the assert in lvalue_kind/MODOP_EXPR whose comment says
that we expect to see MODOP_EXPRs only during template processing.
In this test we get there with processing_template_decl==0.  The
MODOP_EXPR is created in:

       /* Parse the requirement body. */
       ++processing_template_decl;
       reqs = cp_parser_requirement_body (parser);
       --processing_template_decl;

but we're not in a template when calling maybe_convert_cond which
calls verify_sequence_points which ends up calling lvalue_p on
the MODOP_EXPR.

verify_sequence_points is walking the unevaluated operand of a requires
because verify_tree assumes that all unknown expressions are evaluated, and
REQURES_EXPR looks like a normal expression (tcc_expression).

missing I

This patch changes REQURES_EXPR to tcc_exceptional.  That means that

likewise

Both fixed.

the generic code (such as verify_tree) sees that it's magic and doesn't
try to walk into it.

@@ -6530,8 +6530,11 @@ trees_out::core_vals (tree t)
      if (CODE_CONTAINS_STRUCT (code, TS_EXP))
        {
+      location_t loc = (code == REQUIRES_EXPR

Hmm, why does REQUIRES_EXPR have TS_EXP after this patch?

I think you want to remove the MARK_TS_EXP from cp_common_init_ts and then
move REQUIRES_EXPR out of this if.

This is so that I can set TREE_TYPE on a REQUIRES_EXPR.  Code like
maybe_convert_cond needs a tree with a TREE_TYPE.

...but then we should use MARK_TS_TYPED instead.  Fixed.

@@ -7128,7 +7133,10 @@ trees_in::core_vals (tree t)
      if (CODE_CONTAINS_STRUCT (code, TS_EXP))

Likewise.

Done.

@@ -4527,6 +4528,18 @@ cp_tree_equal (tree t1, tree t2)
        case REFLECT_EXPR:
          return compare_reflections (t1, t2);
+    case REQUIRES_EXPR:
+      if (!cp_tree_equal (REQUIRES_EXPR_PARMS (t1),
+                         REQUIRES_EXPR_PARMS (t2)))
+       return false;
+      if (!cp_tree_equal (REQUIRES_EXPR_REQS (t1),
+                         REQUIRES_EXPR_REQS (t2)))
+       return false;
+      if (!cp_tree_equal (REQUIRES_EXPR_EXTRA_ARGS (t1),
+                         REQUIRES_EXPR_EXTRA_ARGS (t2)))
+       return false;
+      return true;

This could be return (x && y && z) but up to you.

I've used that style; it's a bit shorter.  Thanks,

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

OK, thanks.

For 16, maybe we can just remove the assert.

Or change it to _checking_.

Here's a patch for that, ok for 16?

OK.

-- >8 --
We trip on the assert in lvalue_kind/MODOP_EXPR whose comment says
that we expect to see MODOP_EXPRs only during template processing.
In this test we get there with processing_template_decl==0.  The
MODOP_EXPR is created in:

     /* Parse the requirement body. */
     ++processing_template_decl;
     reqs = cp_parser_requirement_body (parser);
     --processing_template_decl;

but we're not in a template when calling maybe_convert_cond which
calls verify_sequence_points which ends up calling lvalue_p on
the MODOP_EXPR.

verify_sequence_points is walking the unevaluated operand of a requires
because verify_tree assumes that all unknown expressions are evaluated, and
REQUIRES_EXPR looks like a normal expression (tcc_expression).

The trunk patch changed REQUIRES_EXPR to tcc_exceptional.  But in 16, we
can just dial the assert down to _checking.

gcc/cp/ChangeLog:

        * tree.cc (lvalue_kind) <case MODOP_EXPR>: Use
        gcc_checking_assert instead of gcc_assert.
---
  gcc/cp/tree.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 2bcbfa84707..1da3e7d6fc2 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -280,7 +280,7 @@ lvalue_kind (const_tree ref)
      case MODOP_EXPR:
        /* We expect to see unlowered MODOP_EXPRs only during
         template processing.  */
-      gcc_assert (processing_template_decl);
+      gcc_checking_assert (processing_template_decl);
        if (CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0))))
        goto default_;
        else

Reply via email to