[PATCH] middle-end: Fix up C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR126848]
Jakub Jelinek <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <aoQSLYH8MhKk0n5F@tucnak> |
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?
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