Re: [PATCH] middle-end: Fix up C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR126848]
Richard Biener <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On Tue, 18 Aug 2026, Jakub Jelinek wrote:
> Hi!
>
> As the following new testcases show, I've messed up the
> C++26 P2795R5 - Erroneous behavior for uninitialized reads
> implementation. What the paper requires for C++26 and later
> (unless user opts out of it with -ftrivial-auto-var-init=uninitialized,
> which effectively pretends everything that accepts [[indeterminate]]
> attribute has that attribute) is that multiple reads of the same
> uninitialized variable yield the same value (whatever it is) and
> as QoI that such uses are diagnosed with -Wuninitialized
> or -Wmaybe-uninitialized.
> The implementation implemented it as a new mode (not directly requestable
> by users using an option) of -ftrivial-auto-var-init= (the new mode used
> just for the case where -ftrivial-auto-var-init={zero,pattern} isn't used),
> with extra code in the FE to deal with vacuous initialization in switch
> bodies etc. for C++26 and some small changes during gimplification for
> the new AUTO_INIT_CXX26 mode.
> On various testcases it worked fine, but this bugreport shows that
> in the middle-end optimizations we actually need to treat it differently.
> In order to fullfill the C++26 requirements, we can't treat .DEFERRED_INIT
> for C++26 and later as something returning something uninitialized where
> optimizations happily optimize say a PHI with such uninitialized value and
> some other value as that other value, or some passes consider the result
> as UNDEFINED rather than VARYING.
> There is an option to come up with a different internal function for these
> C++26 uses of .DEFERRED_INIT, but because it has also many similarities
> with .DEFERRED_INIT (e.g. same expansion) and because the internal function
> already has an argument which is the flag_trivial_auto_var_init value,
> this patch just changes AUTO_INIT_CXX26 value from 3 to 4 so that it can
> be used as a mask, so now we have 6 different modes:
> AUTO_INIT_UNINITIALIZED (the default for non-C++ or C++ < 26)
> AUTO_INIT_ZERO (-ftrivial-auto-var-init=zero for non-C++ or C++ < 26)
> AUTO_INIT_PATTERN (-ftrivial-auto-var-init=pattern for non-C++ or C++ < 26)
> AUTO_INIT_CXX26 (the default for C++ >= 26)
> AUTO_INIT_ZERO | AUTO_INIT_CXX26 (-ftrivial-auto-var-init=zero for C++ >= 26)
> AUTO_INIT_PATTERN | AUTO_INIT_CXX26 (-ftrivial-auto-var-init=pattern for C++ >= 26)
> The option handling ensures to or in AUTO_INIT_CXX26 for C++26/29 unless
> -ftrivial-auto-var-init=uninitialized is used explicitly, and
> the ccp pass and ssa_undefined_value_p is changed so that it treats the
> AUTO_INIT_CXX26 modes of .DEFERRED_INIT differently (basically as a source
> of VARYING value). Because the uninit pass uses ssa_undefined_value_p, I
> had to change also has_undefined_value_p because for -Wuninitialized
> purposes we want to treat all .DEFERRED_INIT calls the same.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Hmm. As it now makes semantic difference, can we instead put the
flag_auto_var_init mode in the .DEFERRED_INIT call as argument?
Because we do not seem to prohibit inlining between functions
with different flag_auto_var_init modes (not sure if that would be
a problem already), see can_inline_edge_by_limits_p.
Also for optimization purposes, wouldn't a 'zero' be a better
"same" value than treating this as VARYING?
Richard.
> 2026-08-18 Jakub Jelinek <[email protected]>
>
> PR c++/126848
> gcc/
> * flag-types.h (enum auto_init_type): Change AUTO_INIT_CXX26
> value from 3 to 4.
> * gimplify.cc (gimplify_decl_expr): Mask off AUTO_INIT_CXX26 bit
> before comparing to AUTO_INIT_PATTERN.
> (gimplify_target_expr): Likewise.
> * internal-fn.cc (expand_DEFERRED_INIT): Likewise. Formatting fix.
> * opts.cc (finish_options): For -fhardened or in AUTO_INIT_CXX26
> bit from previous value if it was set. Mask off AUTO_INIT_CXX26 bit
> before comparing to AUTO_INIT_ZERO.
> * tree-ssa-ccp.cc (likely_value): Return VARYING rather than UNDEFINED
> for .DEFERRED_INIT call with AUTO_INIT_CXX26 bit set in the second
> argument.
> * tree-ssa.cc (ssa_undefined_value_p): Return false rather than true
> for .DEFERRED_INIT call with AUTO_INIT_CXX26 bit set in the second
> argument.
> * tree-ssa-uninit.cc (has_undefined_value_p): Return true for
> SSA_NAMEs with .DEFERRED_INIT call as SSA_NAME_DEF_STMT.
> gcc/c-family/
> * c-opts.cc (c_common_post_options): For -ftrivial-auto-var-init=zero
> or -ftrivial-auto-var-init=pattern in C++26 or later mode set
> AUTO_INIT_CXX26 bit in flag_auto_var_init.
> gcc/testsuite/
> * c-c++-common/auto-init-1.c: Use [15] instead of 1 or [26] instead of
> 2 in regexps matching second .DEFERRED_INIT arguments.
> * c-c++-common/auto-init-2.c: Likewise.
> * c-c++-common/auto-init-3.c: Likewise.
> * c-c++-common/auto-init-4.c: Likewise.
> * c-c++-common/auto-init-5.c: Likewise.
> * c-c++-common/auto-init-6.c: Likewise.
> * c-c++-common/auto-init-7.c: Likewise.
> * c-c++-common/auto-init-8.c: Likewise.
> * c-c++-common/auto-init-9.c: Likewise.
> * c-c++-common/auto-init-10.c: Likewise.
> * c-c++-common/auto-init-11.c: Likewise.
> * c-c++-common/auto-init-12.c: Likewise.
> * c-c++-common/auto-init-13.c: Likewise.
> * c-c++-common/auto-init-14.c: Likewise.
> * c-c++-common/auto-init-15.c: Likewise.
> * c-c++-common/auto-init-16.c: Likewise.
> * c-c++-common/auto-init-esra.c: Likewise.
> * c-c++-common/auto-init-padding-1.c: Likewise.
> * g++.dg/cpp26/erroneous7.C: New test.
> * g++.dg/cpp26/erroneous8.C: New test.
> * g++.dg/cpp26/erroneous9.C: New test.
>
> --- gcc/flag-types.h.jj 2026-05-14 09:51:59.586625450 +0200
> +++ gcc/flag-types.h 2026-08-17 13:35:27.342710636 +0200
> @@ -289,7 +289,7 @@ enum auto_init_type {
> AUTO_INIT_UNINITIALIZED = 0,
> AUTO_INIT_PATTERN = 1,
> AUTO_INIT_ZERO = 2,
> - AUTO_INIT_CXX26 = 3
> + AUTO_INIT_CXX26 = 4
> };
>
> /* Initialization of padding bits with zeros. */
> --- gcc/gimplify.cc.jj 2026-07-31 09:05:43.764169075 +0200
> +++ gcc/gimplify.cc 2026-08-17 14:12:56.276232812 +0200
> @@ -2113,7 +2113,7 @@ gimplify_decl_expr (tree *stmt_p, gimple
> since __builtin_clear_padding will take the address of the
> variable. As a result, if a long double/_Complex long double
> variable will spilled into stack later, its padding is 0XFE. */
> - if (flag_auto_var_init == AUTO_INIT_PATTERN
> + if ((flag_auto_var_init & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
> && !is_gimple_reg (decl)
> && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
> gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
> @@ -8478,7 +8478,7 @@ gimplify_target_expr (tree *expr_p, gimp
> if (var_needs_auto_init_p (temp) && VOID_TYPE_P (TREE_TYPE (init)))
> {
> gimple_add_init_for_auto_var (temp, flag_auto_var_init, &init_pre_p);
> - if (flag_auto_var_init == AUTO_INIT_PATTERN
> + if ((flag_auto_var_init & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
> && !is_gimple_reg (temp)
> && clear_padding_type_may_have_padding_p (TREE_TYPE (temp)))
> gimple_add_padding_init_for_auto_var (temp, is_vla, &init_pre_p);
> --- gcc/internal-fn.cc.jj 2026-06-12 16:55:06.688171290 +0200
> +++ gcc/internal-fn.cc 2026-08-17 13:42:57.120996652 +0200
> @@ -3526,7 +3526,7 @@ expand_DEFERRED_INIT (internal_fn, gcall
> mark_addressable (lhs);
> tree var_addr = build_fold_addr_expr (lhs);
>
> - tree value = (init_type == AUTO_INIT_PATTERN)
> + tree value = ((init_type & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN)
> ? build_int_cst (integer_type_node,
> INIT_PATTERN_VALUE)
> : integer_zero_node;
> @@ -3543,7 +3543,7 @@ expand_DEFERRED_INIT (internal_fn, gcall
> scalar_int_mode var_mode;
> if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE
> && tree_fits_uhwi_p (var_size)
> - && (init_type == AUTO_INIT_PATTERN
> + && ((init_type & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
> || !is_gimple_reg_type (var_type))
> && int_mode_for_size (tree_to_uhwi (var_size) * BITS_PER_UNIT,
> 0).exists (&var_mode)
> @@ -3551,10 +3551,10 @@ expand_DEFERRED_INIT (internal_fn, gcall
> {
> unsigned HOST_WIDE_INT total_bytes = tree_to_uhwi (var_size);
> unsigned char *buf = XALLOCAVEC (unsigned char, total_bytes);
> - memset (buf, (init_type == AUTO_INIT_PATTERN
> + memset (buf, ((init_type & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
> ? INIT_PATTERN_VALUE : 0), total_bytes);
> - tree itype = build_nonstandard_integer_type
> - (total_bytes * BITS_PER_UNIT, 1);
> + tree itype
> + = build_nonstandard_integer_type (total_bytes * BITS_PER_UNIT, 1);
> wide_int w = wi::from_buffer (buf, total_bytes);
> init = wide_int_to_tree (itype, w);
> /* Pun the LHS to make sure its type has constant size
> --- gcc/opts.cc.jj 2026-07-20 09:57:50.000000000 +0200
> +++ gcc/opts.cc 2026-08-17 14:15:02.092641406 +0200
> @@ -1164,8 +1164,10 @@ finish_options (struct gcc_options *opts
> if (opts->x_flag_hardened)
> {
> if (!opts_set->x_flag_auto_var_init)
> - opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
> - else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
> + opts->x_flag_auto_var_init
> + = auto_init_type (opts->x_flag_auto_var_init | AUTO_INIT_ZERO);
> + else if ((opts->x_flag_auto_var_init & ~AUTO_INIT_CXX26)
> + != AUTO_INIT_ZERO)
> warning_at (loc, OPT_Whardened,
> "%<-ftrivial-auto-var-init=zero%> is not enabled by "
> "%<-fhardened%> because it was specified on the command "
> --- gcc/tree-ssa-ccp.cc.jj 2026-06-01 09:15:39.041605261 +0200
> +++ gcc/tree-ssa-ccp.cc 2026-08-17 14:48:54.809980053 +0200
> @@ -727,9 +727,16 @@ likely_value (gimple *stmt)
> if (gimple_has_volatile_ops (stmt))
> return VARYING;
>
> - /* .DEFERRED_INIT produces undefined. */
> + /* .DEFERRED_INIT produces undefined except for AUTO_INIT_CXX26
> + which produces varying because it is undefined that needs to have
> + the same value in all uses. */
> if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
> - return UNDEFINED;
> + {
> + if (tree_to_uhwi (gimple_call_arg (stmt, 1)) & AUTO_INIT_CXX26)
> + return VARYING;
> + else
> + return UNDEFINED;
> + }
>
> /* Arrive here for more complex cases. */
> has_constant_operand = false;
> --- gcc/tree-ssa.cc.jj 2026-05-30 09:46:04.446062938 +0200
> +++ gcc/tree-ssa.cc 2026-08-17 14:50:05.461089614 +0200
> @@ -1348,9 +1348,15 @@ ssa_undefined_value_p (tree t, bool part
> return true;
>
> /* The value is undefined if the definition statement is a call
> - to .DEFERRED_INIT function. */
> + to .DEFERRED_INIT function. Except for AUTO_INIT_CXX26 which is
> + undefined but needs to have the same value in all uses. */
> if (gimple_call_internal_p (def_stmt, IFN_DEFERRED_INIT))
> - return true;
> + {
> + if (tree_to_uhwi (gimple_call_arg (def_stmt, 1)) & AUTO_INIT_CXX26)
> + return false;
> + else
> + return true;
> + }
>
> /* The value is partially undefined if the definition statement is
> a REALPART_EXPR or IMAGPART_EXPR and its operand is defined by
> --- gcc/tree-ssa-uninit.cc.jj 2026-06-25 10:03:50.890435462 +0200
> +++ gcc/tree-ssa-uninit.cc 2026-08-17 14:52:34.374212821 +0200
> @@ -81,6 +81,7 @@ static bool
> has_undefined_value_p (tree t)
> {
> return (ssa_undefined_value_p (t)
> + || gimple_call_internal_p (SSA_NAME_DEF_STMT (t), IFN_DEFERRED_INIT)
> || (possibly_undefined_names
> && possibly_undefined_names->contains (t)));
> }
> --- gcc/c-family/c-opts.cc.jj 2026-06-25 10:03:50.752437217 +0200
> +++ gcc/c-family/c-opts.cc 2026-08-17 14:15:23.515370436 +0200
> @@ -925,8 +925,13 @@ c_common_post_options (const char **pfil
> flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_C11;
>
> if (cxx_dialect >= cxx26)
> - SET_OPTION_IF_UNSET (&global_options, &global_options_set,
> - flag_auto_var_init, AUTO_INIT_CXX26);
> + {
> + SET_OPTION_IF_UNSET (&global_options, &global_options_set,
> + flag_auto_var_init, AUTO_INIT_CXX26);
> + if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
> + flag_auto_var_init
> + = auto_init_type (flag_auto_var_init | AUTO_INIT_CXX26);
> + }
>
> /* The -Wtrivial-auto-var-init warning is useless for C++, where we always
> add .DEFERRED_INIT calls when some (vacuous) initializers are bypassed
> --- gcc/testsuite/c-c++-common/auto-init-1.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-1.c 2026-08-17 15:08:40.789032839 +0200
> @@ -29,13 +29,13 @@ void foo()
> return;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, 2, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, 2, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, 2, \&\"temp3\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, 2, \&\"temp4\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(4, 2, \&\"temp5\"" "gimple" { target ilp32 } } } */
> -/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, 2, \&\"temp5\"" "gimple" { target lp64 } } } */
> -/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, 2, \&\"temp6\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(4, 2, \&\"temp7\"" "gimple" { target ilp32 } } } */
> -/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, 2, \&\"temp7\"" "gimple" { target lp64 } } } */
> -/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, 2, \&\"temp8\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, \[26], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, \[26], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, \[26], \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, \[26], \&\"temp4\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(4, \[26], \&\"temp5\"" "gimple" { target ilp32 } } } */
> +/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, \[26], \&\"temp5\"" "gimple" { target lp64 } } } */
> +/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, \[26], \&\"temp6\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(4, \[26], \&\"temp7\"" "gimple" { target ilp32 } } } */
> +/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, \[26], \&\"temp7\"" "gimple" { target lp64 } } } */
> +/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, \[26], \&\"temp8\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-2.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-2.c 2026-08-17 15:06:10.548926349 +0200
> @@ -29,13 +29,13 @@ void foo()
> return;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, 1, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, 1, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, 1, \&\"temp3\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, 1, \&\"temp4\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(4, 1, \&\"temp5\"" "gimple" { target ilp32 } } } */
> -/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, 1, \&\"temp5\"" "gimple" { target lp64 } } } */
> -/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, 1, \&\"temp6\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(4, 1, \&\"temp7\"" "gimple" { target ilp32 } } } */
> -/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, 1, \&\"temp7\"" "gimple" { target lp64 } } } */
> -/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, 1, \&\"temp8\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(1, \[15], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(2, \[15], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(4, \[15], \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\(4, \[15], \&\"temp4\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(4, \[15], \&\"temp5\"" "gimple" { target ilp32 } } } */
> +/* { dg-final { scan-tree-dump "temp5 = .DEFERRED_INIT \\(8, \[15], \&\"temp5\"" "gimple" { target lp64 } } } */
> +/* { dg-final { scan-tree-dump "temp6 = .DEFERRED_INIT \\(8, \[15], \&\"temp6\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(4, \[15], \&\"temp7\"" "gimple" { target ilp32 } } } */
> +/* { dg-final { scan-tree-dump "temp7 = .DEFERRED_INIT \\(8, \[15], \&\"temp7\"" "gimple" { target lp64 } } } */
> +/* { dg-final { scan-tree-dump "temp8 = .DEFERRED_INIT \\(1, \[15], \&\"temp8\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-3.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-3.c 2026-08-17 15:06:30.087680095 +0200
> @@ -14,6 +14,6 @@ long double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, 2, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, 2, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((8|12|16), 2, \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, \[26], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, \[26], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((8|12|16), \[26], \&\"temp3\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-4.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-4.c 2026-08-17 15:06:48.289450696 +0200
> @@ -14,6 +14,6 @@ long double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, 1, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, 1, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((8|12|16), 1, \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(4, \[15], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(8, \[15], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((8|12|16), \[15], \&\"temp3\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-5.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-5.c 2026-08-17 15:07:02.468272000 +0200
> @@ -15,7 +15,7 @@ _Complex long double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, 2, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, 2, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((16|24|32), 2, \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, \[26], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, \[26], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((16|24|32), \[26], \&\"temp3\"" "gimple" } } */
>
> --- gcc/testsuite/c-c++-common/auto-init-6.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-6.c 2026-08-17 15:07:15.548107151 +0200
> @@ -15,7 +15,7 @@ _Complex long double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, 1, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, 1, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((16|24|32), 1, \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(8, \[15], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(16, \[15], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\((16|24|32), \[15], \&\"temp3\"" "gimple" } } */
>
> --- gcc/testsuite/c-c++-common/auto-init-7.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-7.c 2026-08-17 15:07:29.815927329 +0200
> @@ -29,7 +29,7 @@ double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, 2, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, 2, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, 2, \&\"temp3\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\((8|5), 2, \&\"temp4\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, \[26], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, \[26], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, \[26], \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\((8|5), \[26], \&\"temp4\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-8.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-8.c 2026-08-17 15:09:24.907476803 +0200
> @@ -29,7 +29,7 @@ double foo()
> return result;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, 1, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, 1, \&\"temp2\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, 1, \&\"temp3\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\((8|5), 1, \&\"temp4\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(12, \[15], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp2 = .DEFERRED_INIT \\(24, \[15], \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp3 = .DEFERRED_INIT \\(28, \[15], \&\"temp3\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp4 = .DEFERRED_INIT \\((8|5), \[15], \&\"temp4\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-9.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-9.c 2026-08-17 15:07:56.960585220 +0200
> @@ -16,5 +16,5 @@ void foo()
> return;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, 2, \&\"temp1\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump-not "temp2 = .DEFERRED_INIT \\(8, 2, \&\"temp2\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, \[26], \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump-not "temp2 = .DEFERRED_INIT \\(8, \[26], \&\"temp2\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-10.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-10.c 2026-08-17 15:01:42.894299672 +0200
> @@ -18,5 +18,5 @@ void foo()
> return;
> }
>
> -/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, 1, \&\"temp1\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "temp1 = .DEFERRED_INIT \\(2, \[15], \&\"temp1\"" "gimple" } } */
> /* { dg-final { scan-tree-dump-not "temp2 = .DEFERRED_INIT \\(" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-11.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-11.c 2026-08-17 15:01:58.557102267 +0200
> @@ -11,4 +11,4 @@ void foo(int n)
> return;
> }
>
> -/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 2, \&\"arr\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, \[26], \&\"arr\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-12.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-12.c 2026-08-17 15:02:14.292903944 +0200
> @@ -11,4 +11,4 @@ void foo(int n)
> return;
> }
>
> -/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 1, \&\"arr\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, \[15], \&\"arr\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-13.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-13.c 2026-08-17 15:02:31.555686378 +0200
> @@ -19,5 +19,5 @@ int foo()
> return d.b + var.bar.b;
> }
>
> -/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, 1, \&\"d\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, 1, \&\"var\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, \[15], \&\"d\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, \[15], \&\"var\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-14.c.jj 2026-03-27 10:17:15.164313931 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-14.c 2026-08-17 15:02:48.988466669 +0200
> @@ -19,5 +19,5 @@ int foo()
> return d.b + var.bar.b;
> }
>
> -/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, 2, \&\"d\"" "gimple" } } */
> -/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, 2, \&\"var\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "d = .DEFERRED_INIT \\(4, \[26], \&\"d\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump "var = .DEFERRED_INIT \\(4, \[26], \&\"var\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-15.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-15.c 2026-08-17 15:03:02.756293152 +0200
> @@ -10,4 +10,4 @@ void foo(int a)
> g(x);
> }
>
> -/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 2, \&\"x\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, \[26], \&\"x\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-16.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-16.c 2026-08-17 15:03:15.101137567 +0200
> @@ -10,4 +10,4 @@ void foo(int a)
> g(x);
> }
>
> -/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, 1, \&\"x\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(D.\\d*, \[15], \&\"x\"" "gimple" } } */
> --- gcc/testsuite/c-c++-common/auto-init-esra.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-esra.c 2026-08-17 15:08:10.141419098 +0200
> @@ -31,5 +31,5 @@ void VCross(VECTOR a, const VECTOR b, co
> Assign_Vector(a, tmp);
> }
>
> -/* { dg-final { scan-tree-dump-times "tmp = .DEFERRED_INIT \\(24, 2, \&\"tmp\"" 1 "gimple" } } */
> -/* { dg-final { scan-tree-dump-times ".DEFERRED_INIT \\(8, 2, \&\"tmp\"" 3 "esra" } } */
> +/* { dg-final { scan-tree-dump-times "tmp = .DEFERRED_INIT \\(24, \[26], \&\"tmp\"" 1 "gimple" } } */
> +/* { dg-final { scan-tree-dump-times ".DEFERRED_INIT \\(8, \[26], \&\"tmp\"" 3 "esra" } } */
> --- gcc/testsuite/c-c++-common/auto-init-padding-1.c.jj 2026-03-27 10:17:15.165313915 +0100
> +++ gcc/testsuite/c-c++-common/auto-init-padding-1.c 2026-08-17 15:09:33.139373054 +0200
> @@ -19,5 +19,5 @@ void foo(int a)
> g(s);
> }
>
> -/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(24, 1, \&\"s\"" "gimple" } } */
> +/* { dg-final { scan-tree-dump ".DEFERRED_INIT \\(24, \[15], \&\"s\"" "gimple" } } */
> /* { dg-final { scan-tree-dump "__builtin_clear_padding" "gimple" } } */
> --- gcc/testsuite/g++.dg/cpp26/erroneous7.C.jj 2026-08-17 14:03:41.599248723 +0200
> +++ gcc/testsuite/g++.dg/cpp26/erroneous7.C 2026-08-17 14:08:37.776502487 +0200
> @@ -0,0 +1,20 @@
> +// PR c++/126848
> +// { dg-do run { target c++26 } }
> +// { dg-skip-if "" { *-*-* } { "-ftrivial-auto-var-init=*" } { "" } }
> +// { dg-options "-O2 -Wuninitialized" }
> +
> +[[gnu::noipa]]
> +int
> +foo (int x)
> +{
> + int a;
> + int b = x ? a : 1;
> + return b - a; // { dg-warning "'a' is used uninitialized" }
> +}
> +
> +int
> +main ()
> +{
> + if (foo (1) != 0)
> + __builtin_abort ();
> +}
> --- gcc/testsuite/g++.dg/cpp26/erroneous8.C.jj 2026-08-17 14:03:51.153127881 +0200
> +++ gcc/testsuite/g++.dg/cpp26/erroneous8.C 2026-08-17 14:08:51.113333793 +0200
> @@ -0,0 +1,19 @@
> +// PR c++/126848
> +// { dg-do run { target c++26 } }
> +// { dg-options "-O2 -ftrivial-auto-var-init=zero -Wuninitialized" }
> +
> +[[gnu::noipa]]
> +int
> +foo (int x)
> +{
> + int a;
> + int b = x ? a : 1;
> + return b - a; // { dg-warning "'a' is used uninitialized" }
> +}
> +
> +int
> +main ()
> +{
> + if (foo (1) != 0)
> + __builtin_abort ();
> +}
> --- gcc/testsuite/g++.dg/cpp26/erroneous9.C.jj 2026-08-17 14:04:36.985548163 +0200
> +++ gcc/testsuite/g++.dg/cpp26/erroneous9.C 2026-08-17 14:09:04.012170640 +0200
> @@ -0,0 +1,19 @@
> +// PR c++/126848
> +// { dg-do run { target c++26 } }
> +// { dg-options "-O2 -ftrivial-auto-var-init=pattern -Wuninitialized" }
> +
> +[[gnu::noipa]]
> +int
> +foo (int x)
> +{
> + int a;
> + int b = x ? a : 1;
> + return b - a; // { dg-warning "'a' is used uninitialized" }
> +}
> +
> +int
> +main ()
> +{
> + if (foo (1) != 0)
> + __builtin_abort ();
> +}
>
> Jakub
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)