On Thu, 19 Mar 2020, Marek Polacek wrote:

> On Thu, Mar 19, 2020 at 01:06:35PM -0400, Patrick Palka via Gcc-patches wrote:
> > On Thu, 19 Mar 2020, Patrick Palka wrote:
> > 
> > > This patch adds a check to detect changing the active union member during
> > > initialization of the union.  It uses the CONSTRUCTOR_NO_CLEARING flag as 
> > > a
> > > proxy for whether the non-empty CONSTRUCTOR of UNION_TYPE we're assigning 
> > > to in
> > > cxx_eval_store_expression is in the process of being initialized, which 
> > > seems to
> > > work well.
> > 
> > If we can't rely on CONSTRUCTOR_NO_CLEARING to be set iff a CONSTRUCTOR
> > is in the process of being initialized, then here's an alternative patch
> > for consideration, that detects this UB in an indirect way and after the
> > fact.
> 
> Yeah, I'm not sure if that would work well, especially in C++20 where we
> sometimes don't clear it:
> 
>   /* The result of a constexpr function must be completely initialized.
> 
>      However, in C++20, a constexpr constructor doesn't necessarily have
>      to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
>      in order to detect reading an unitialized object in constexpr instead
>      of value-initializing it.  (reduced_constant_expression_p is expected to
>      take care of clearing the flag.)  */
>   if (TREE_CODE (result) == CONSTRUCTOR
>       && (cxx_dialect < cxx2a
>           || !DECL_CONSTRUCTOR_P (fun)))
>     clear_no_implicit_zero (result);
> 
> and rely on reduced_constant_expression_p to clear it.

I see, thanks.  Here's a reproducer for the issue you pointed out, which
is a valid testcase but gets rejected with the proposed patch:

    union U
    {
      int x;
      char y;
    };

    constexpr bool
    baz ()
    {
      U u;
      u.x = 3;
      u.y = 7;
      return (u.y == 7);
    }

    static_assert (baz ());

CONSTRUCTOR_NO_CLEARING is set for 'u' and is not cleared after its
constructor returns, and so the check yields a false positive for the
assignment to u.y.  That's unfortunate...

Reply via email to