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?

-- >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
-- 
2.55.0

Reply via email to