On Mon, Jan 20, 2025 at 11:46:44AM -0500, Jason Merrill wrote:
> On 1/20/25 10:27 AM, Marek Polacek wrote:
> > On Fri, Jan 17, 2025 at 06:38:45PM -0500, Jason Merrill wrote:
> > > On 1/17/25 1:31 PM, Marek Polacek wrote:
> > > > On Fri, Jan 17, 2025 at 08:10:24AM -0500, Jason Merrill wrote:
> > > > > On 1/16/25 8:04 PM, Marek Polacek wrote:
> > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > > >
> > > > > > -- >8 --
> > > > > > The recent r15-6369 unfortunately caused a bad wrong-code issue.
> > > > > > Here we have
> > > > > >
> > > > > > TARGET_EXPR <D.2996, (void) (D.2996 = {.status=0,
> > > > > > .data={._vptr.Foo=&_ZTV3Foo + 16}})>
> > > > > >
> > > > > > and call cp_fold_r -> maybe_constant_init with object=D.2996. In
> > > > > > cxx_eval_outermost_constant_expr we now take the type of the object
> > > > > > if present. An object can't have type 'void' and so we continue to
> > > > > > evaluate the initializer. That evaluates into a VOID_CST, meaning
> > > > > > we disregard the whole initializer, and terrible things ensue.
> > > > >
> > > > > In that case, I'd think we want to use the value of 'object' (which
> > > > > should
> > > > > be in ctx.ctor?) instead of the return value of
> > > > > cxx_eval_constant_expression.
> > > >
> > > > Ah, I'm sorry I didn't choose that approach. Maybe like this, then?
> > > >
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > >
> > > OK. Maybe also add an assert that TREE_TYPE (r) is close enough to type?
> >
> > Thanks. dg.exp passed with this extra assert:
> >
> > @@ -8986,7 +8986,11 @@ cxx_eval_outermost_constant_expr (tree t, bool
> > allow_non_constant,
> > /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
> > of statements, and the result ought to be stored in ctx.ctor. */
> > if (r == void_node && !constexpr_dtor && ctx.ctor)
> > - r = ctx.ctor;
> > + {
> > + r = ctx.ctor;
> > + gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
> > + (TREE_TYPE (r), type));
> > + }
>
> I was thinking to add that assert in general, not just in this case, to
> catch any other instances of trying to return the wrong type.
Unfortunately this
+ /* Check we are not trying to return the wrong type. */
+ gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
+ (initialized_type (r), type)
+ || error_operand_p (type));
breaks too much, e.g. constexpr-prvalue2.C with struct A x struct B,
or pr82128.C
*(((struct C *) a)->D.2903._vptr.A + 8)
x
int (*) ()
I've also tried can_convert, or similar_type_p but no luck. Any thoughts?
Marek