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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.