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