> On Sep 3, 2025, at 09:38, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> On Tue, Sep 02, 2025 at 09:35:04PM +0000, Qing Zhao wrote:
>>> I think I've mentioned it earlier, but -ftrivial-auto-var-init= doesn't
>>> work at all for C++.
>> You mean that -ftrivial-auto-var-init hasn’t work at all for C++’s auto 
>> variables with non-trivial ctors?
> 
> Yeah.  Actually, it probably also works if non-trivial ctors are constexpr
> and the ctors are actually optimized into TREE_CONSTANT DECL_INITIALIZER.

For such case, the CLOBBER (bob) is not emitted? 
> 
>>> With C++26 P2795R5 being voted in, if we were to default to say
>>> -ftrivial-auto-var-init=zero for -std=c++26/-std=gnu++26, that would mean
>>> the paper isn't really implemented.
>> 
>> I briefly read C++26 P2795R5 this morning (still have some questions, not 
>> fully understand yet), my major question is:
>> 
>> When -ftrivial-auto-var-init=zero is combined with C++26 P2795R5, what’s the
>> correct behavior the user is expecting?  When reading an uninitialized 
>> variable 
>> is considered  an well-defined erroneous behavior, can the user still use
>> -ftrivial-auto-var-init to initialize the auto vairables?
> 
> I think it is pretty much the same thing, we want -Wuninitialized to
> complain both in -std=c++26 and if -ftrivial-auto-var-init={zero,pattern}
> and still want to initialize (and either zero or pattern initialization is
> fine).  So I'd go for -std={gnu,c}++26 implying
> flag_auto_var_init = AUTO_INIT_CXX26 if
> -ftrivial-auto-var-init={zero,pattern} has not been specified,
> and for that
> mode most likely just zero initialize and don't bother with padding bits.

You mean, under the new AUTO_INIT_CXX26 mode, ONLY  all the fields of the 
structure
are zero initialized, but leave the paddings uninitialized?

> Plus as Jason said, move the CLOBBER_OBJECT_BEGIN clobbers from ctors for
> flag_auto_var_init != AUTO_INIT_UNINITIALIZED && flag_lifetime_dse > 1
> to before the whole object is initialized in all places where we emit calls
> to the non-trivial ctors and if it initializes a VAR_DECL (rather than say
> heap) emit .DEFERRED_INIT calls after those.

A little confused with the above:

Currently, we have the following IR (t.cc <http://t.cc/>.006t.gimple): (with 
-ftrivial-auto-var-init=zero)

Int foo ()
{
  struct S s;
  …
  try
     {
      s = .DEFERRED_INIT (12, 2, &"s"[0]);
      S::S (&s);
…
}

void S::S (struct S * const this)
{
  *this = {CLOBBER(bob)};
  {
    this->a = 42;
  }
}

Will the suggested new IR for the above be the following? 

Int foo ()
{
  struct S s;
  …
  try
     {
       s = {CLOBBER(bob));
       S::S (&s);
       s = .DEFFERRED_INIT (12, 2, &”s”[0]);
 …
}

void S::S (struct S * const this)
{
  this->a = 42;
}
       
Or something else?


> 
> But there is one thing the paper doesn't care about, which looks like a show
> stopper to me, in particular the stuff -Wtrivial-auto-var-init warning warns
> about.  Consider:
> 
> template <typename T>
> void bar (T &);
> 
> template <typename T>
> void
> foo (int x)
> {
>  switch (x)
>    {
>    case 1:
>      T t;
>      bar (t);
>      // FALLTHRU
>    case 2:
>      bar (t);
>      break;
>    default:
>      break;
>    }
> }
> 
> struct S { S (); S (int); ~S (); int s; };
> 
> void
> baz (int x)
> {
>  foo <S> (x);
>  foo <int> (x);
> }
> 
> The foo <S> instantiation is invalid and we do diagnose that as
> error that the switch (but could be goto too) jumps across initialization
> of the t variable.  Similarly if there is T t = 42; instead of T t;
> both foo <S> and foo <int> will be rejected.  But with just T t; in there
> foo <int> is accepted as valid, one can jump across it but it used to be
> undefined behavior in both bar (t); calls, or say with t = 42; before the
> first bar just undefined behavior in case of foo <int> (2);
> But now it is supposed to be erroneous behavior but it is unclear where
> it can initialize the t variable to the erroneous value.  Silently promote
> the variable to wider scope and initialize there, or add some wider scope
> flag which tracks if it is initialized or not and on any label initializes
> it if not yet initialized?  It is unclear how such wider scope vars would
> play with say OpenMP/OpenACC.
> 
> See http://eel.is/c++draft/stmt.dcl#2 and
> http://eel.is/c++draft/basic.life#2.sentence-2

Need to study the above a little bit more….
> 
>>> One problem with this are [[indeterminate]] vars, if .DEFERRED_INIT is
>>> emitted in the ctors, the vars will be cleared even if they are
>>> [[indeterminate]] (unless the ctors are inlined and some optimization
>>> figures out, these vars are [[indeterminate]], let's drop all .DEFERRED_INIT
>>> calls for those and their subparts.  
>> 
>> If the value need to be kept as [[indeterminate]], what’s the purpose to use
>> -ftrivial-auto-var-init?
> 
> I think even explicit -ftrivial-auto-var-init={zero,pattern} should treat
> [[indeterminate]] variables like those having the [[gnu::uninitialized]]
> attribute.

Okay, so [[indeterminate]] is a new attribute that will attached to the 
variables, meaning
that the value of the variable is intended to be indeterminate? 

Looks like it’s similar as the attribute uninitialized.

thanks.

Qing


> 
> Jakub
> 

Reply via email to