On Thu, 24 Feb 2022, Qing Zhao wrote: > > > > On Feb 24, 2022, at 4:16 AM, Richard Biener <rguent...@suse.de> wrote: > > > > On Sat, 19 Feb 2022, Qing Zhao wrote: > > > >> Hi, > >> > >> This is the 2nd patch for fixing pr102276. > >> > >> Adding -Wtrivial-auto-var-init and update documentation. > >> > >> Adding a new warning option -Wtrivial-auto-var-init to report cases when > >> -ftrivial-auto-var-init cannot initialize the auto variable. At the same > >> time, update documentation for -ftrivial-auto-var-init to connect it with > >> the new warning option -Wtrivial-auto-var-init, and add documentation > >> for -Wtrivial-auto-var-init. > >> > >> Bootstraped and regression tested on both x86 and aarch64. > >> > >> Okay for committing? > >> > >> thanks. > >> > >> Qing. > >> > >> ============================== > >> From 4346890b8f4258489c4841f1992ba3ce816d7689 Mon Sep 17 00:00:00 2001 > >> From: Qing Zhao <qing.z...@oracle.com> > >> Date: Fri, 18 Feb 2022 15:53:15 +0000 > >> Subject: [PATCH 2/2] Adding -Wtrivial-auto-var-init and update > >> documentation. > >> > >> Adding a new warning option -Wtrivial-auto-var-init to report cases when > >> -ftrivial-auto-var-init cannot initialize the auto variable. At the same > >> time, update documentation for -ftrivial-auto-var-init to connect it with > >> the new warning option -Wtrivial-auto-var-init, and add documentation > >> for -Wtrivial-auto-var-init. > >> > >> 2022-02-18 Qing Zhao <qing.z...@oracle.com> > >> gcc/ChangeLog: > >> > >> * common.opt (-Wtrivial-auto-var-init): New option. > >> * doc/invoke.texi (-Wtrivial-auto-var-init): Document new option. > >> (-ftrivial-auto-var-init): Update option; > >> * gimplify.cc (maybe_warn_switch_unreachable): Rename... > >> (maybe_warn_switch_unreachable_and_auto_init): ...to this. > >> (gimplify_switch_expr): Call new function. > >> > >> gcc/testsuite/ChangeLog: > >> > >> * gcc.dg/auto-init-pr102276-3.c: New test. > >> * gcc.dg/auto-init-pr102276-4.c: New test. > >> --- > >> gcc/common.opt | 4 + > >> gcc/doc/invoke.texi | 14 ++- > >> gcc/gimplify.cc | 100 +++++++++++++++----- > >> gcc/testsuite/gcc.dg/auto-init-pr102276-3.c | 40 ++++++++ > >> gcc/testsuite/gcc.dg/auto-init-pr102276-4.c | 40 ++++++++ > >> 5 files changed, 175 insertions(+), 23 deletions(-) > >> create mode 100644 gcc/testsuite/gcc.dg/auto-init-pr102276-3.c > >> create mode 100644 gcc/testsuite/gcc.dg/auto-init-pr102276-4.c > >> > >> diff --git a/gcc/common.opt b/gcc/common.opt > >> index c21e5273ae3..22c95dbfa49 100644 > >> --- a/gcc/common.opt > >> +++ b/gcc/common.opt > >> @@ -801,6 +801,10 @@ Wtrampolines > >> Common Var(warn_trampolines) Warning > >> Warn whenever a trampoline is generated. > >> > >> +Wtrivial-auto-var-init > >> +Common Var(warn_trivial_auto_var_init) Warning Init(0) > >> +Warn about where -ftrivial-auto-var-init cannot initialize the auto > >> variable. > >> + > > > > Warn about cases where ... initialize a variable. > > Okay. > > > > >> Wtype-limits > >> Common Var(warn_type_limits) Warning EnabledBy(Wextra) > >> Warn if a comparison is always true or always false due to the limited > >> range of the data type. > >> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > >> index e1a00c80307..c61a5b4b4a5 100644 > >> --- a/gcc/doc/invoke.texi > >> +++ b/gcc/doc/invoke.texi > >> @@ -399,7 +399,7 @@ Objective-C and Objective-C++ Dialects}. > >> -Wswitch -Wno-switch-bool -Wswitch-default -Wswitch-enum @gol > >> -Wno-switch-outside-range -Wno-switch-unreachable -Wsync-nand @gol > >> -Wsystem-headers -Wtautological-compare -Wtrampolines -Wtrigraphs @gol > >> --Wtsan -Wtype-limits -Wundef @gol > >> +-Wtrivial-auto-var-init -Wtsan -Wtype-limits -Wundef @gol > >> -Wuninitialized -Wunknown-pragmas @gol > >> -Wunsuffixed-float-constants -Wunused @gol > >> -Wunused-but-set-parameter -Wunused-but-set-variable @gol > >> @@ -6953,6 +6953,14 @@ This warning is enabled by default for C and C++ > >> programs. > >> Warn when @code{__sync_fetch_and_nand} and @code{__sync_nand_and_fetch} > >> built-in functions are used. These functions changed semantics in GCC 4.4. > >> > >> +@item -Wtrivial-auto-var-init > >> +@opindex Wtrivial-auto-var-init > >> +@opindex Wno-trivial-auto-var-init > >> +Warn when @code{-ftrivial-auto-var-init} cannot initialize the automatic > >> +variable. A common situation is an automatic variable that is declared > >> +between the controlling expression and the first case lable of a > >> @code{switch} > >> +statement. > >> + > >> @item -Wunused-but-set-parameter > >> @opindex Wunused-but-set-parameter > >> @opindex Wno-unused-but-set-parameter > >> @@ -12314,6 +12322,10 @@ initializer as uninitialized, > >> @option{-Wuninitialized} and > >> warning messages on such automatic variables. > >> With this option, GCC will also initialize any padding of automatic > >> variables > >> that have structure or union types to zeroes. > >> +However, the current implementation cannot initialize automatic variables > >> that > >> +are declared between the controlling expression and the first case of a > >> +@code{switch} statement. Using @option{-Wtrivial-auto-var-init} to > >> report all > >> +such cases. > >> > >> The three values of @var{choice} are: > >> > >> diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc > >> index 4e3bbf5314d..7e52794691f 100644 > >> --- a/gcc/gimplify.cc > >> +++ b/gcc/gimplify.cc > >> @@ -2079,13 +2079,59 @@ warn_switch_unreachable_r (gimple_stmt_iterator > >> *gsi_p, bool *handled_ops_p, > >> return NULL_TREE; > >> } > >> > >> +/* Callback for walk_gimple_seq. */ > >> + > >> +static tree > >> +warn_switch_unreachable_auto_init_r (gimple_stmt_iterator *gsi_p, > >> + bool *handled_ops_p, > >> + struct walk_stmt_info *) > >> +{ > >> + gimple *stmt = gsi_stmt (*gsi_p); > >> + > >> + *handled_ops_p = true; > >> + switch (gimple_code (stmt)) > >> + { > >> + case GIMPLE_TRY: > >> + case GIMPLE_BIND: > >> + case GIMPLE_CATCH: > >> + case GIMPLE_EH_FILTER: > >> + case GIMPLE_TRANSACTION: > >> + /* Walk the sub-statements. */ > >> + *handled_ops_p = false; > >> + break; > >> + case GIMPLE_CALL: > >> + if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT) > >> + && flag_auto_var_init > AUTO_INIT_UNINITIALIZED) > >> + { > >> + /* Get the variable name from the 3rd argument of call. */ > >> + tree var_name = gimple_call_arg (stmt, 2); > >> + var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0); > >> + const char *var_name_str = TREE_STRING_POINTER (var_name); > >> + > >> + warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init, > >> + "%qs cannot be initialized with" > >> + "%<-ftrivial-auto-var_init%>", > >> + var_name_str); > >> + } > >> + break; > >> + case GIMPLE_LABEL: > >> + /* Stop till the first Label. */ > >> + return integer_zero_node; > >> + default: > >> + break; > >> + } > >> + return NULL_TREE; > >> +} > >> + > >> /* Possibly warn about unreachable statements between switch's controlling > >> - expression and the first case. SEQ is the body of a switch > >> expression. */ > >> + expression and the first case. Also warn about -ftrivial-auto-var-init > >> + cannot initialize the auto variable under such situation. > >> + SEQ is the body of a switch expression. */ > >> > >> static void > >> -maybe_warn_switch_unreachable (gimple_seq seq) > >> +maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq) > >> { > >> - if (!warn_switch_unreachable > >> + if ((!warn_switch_unreachable && !warn_trivial_auto_var_init) > >> /* This warning doesn't play well with Fortran when optimizations > >> are on. */ > >> || lang_GNU_Fortran () > >> @@ -2093,26 +2139,36 @@ maybe_warn_switch_unreachable (gimple_seq seq) > >> return; > >> > >> struct walk_stmt_info wi; > >> - memset (&wi, 0, sizeof (wi)); > >> - walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi); > >> - gimple *stmt = (gimple *) wi.info; > >> > >> - if (stmt && gimple_code (stmt) != GIMPLE_LABEL) > >> + if (warn_switch_unreachable) > >> { > >> - if (gimple_code (stmt) == GIMPLE_GOTO > >> - && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL > >> - && DECL_ARTIFICIAL (gimple_goto_dest (stmt))) > >> - /* Don't warn for compiler-generated gotos. These occur > >> - in Duff's devices, for example. */ > >> - ; > >> - else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED) > >> - && (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))) > >> - /* Don't warn for compiler-generated initializations for > >> - -ftrivial-auto-var-init. */ > >> - ; > >> - else > >> - warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, > >> - "statement will never be executed"); > >> + memset (&wi, 0, sizeof (wi)); > >> + walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi); > >> + gimple *stmt = (gimple *) wi.info; > >> + > >> + if (stmt && gimple_code (stmt) != GIMPLE_LABEL) > >> + { > >> + if (gimple_code (stmt) == GIMPLE_GOTO > >> + && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL > >> + && DECL_ARTIFICIAL (gimple_goto_dest (stmt))) > >> + /* Don't warn for compiler-generated gotos. These occur > >> + in Duff's devices, for example. */ > >> + ; > >> + else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED) > >> + && (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))) > >> + /* Don't warn for compiler-generated initializations for > >> + -ftrivial-auto-var-init. */ > >> + ; > >> + else > >> + warning_at (gimple_location (stmt), OPT_Wswitch_unreachable, > >> + "statement will never be executed"); > >> + } > >> + } > > > > Hmm. I'd re-organize the code to emit both the Wswitch-unreachable > > and -Wtrivial_auto_var_init diagnostic from the existing > > warn_switch_unreachable_r callback. You can use wi.info to keep > > track whether a Wswitch-unreachable diagnostic was already emitted > > (and if -Wtrivial_auto_var_init is not enabled abort the walk) > > for example. > > Okay. Will try this. > > A question here: for the current -Wswitch-unreachable, the warning will be > emit only once for the first unreachable stmt. > Shall we emit warning for each unreachable stmt instead?
No, only for the first one. But we might want to diagnose all not auto-init variables. Richard. > thanks. > > Qing > > > > Thanks, > > Richard. > > > >> + if (warn_trivial_auto_var_init) > >> + { > >> + memset (&wi, 0, sizeof (wi)); > >> + walk_gimple_seq (seq, warn_switch_unreachable_auto_init_r, NULL, > >> &wi); > >> } > >> } > >> > >> @@ -2646,7 +2702,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq > >> *pre_p) > >> gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq); > >> > >> gimplify_ctxp->in_switch_expr = old_in_switch_expr; > >> - maybe_warn_switch_unreachable (switch_body_seq); > >> + maybe_warn_switch_unreachable_and_auto_init (switch_body_seq); > >> maybe_warn_implicit_fallthrough (switch_body_seq); > >> /* Only do this for the outermost GIMPLE_SWITCH. */ > >> if (!gimplify_ctxp->in_switch_expr) > >> diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c > >> b/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c > >> new file mode 100644 > >> index 00000000000..f113f46e29d > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c > >> @@ -0,0 +1,40 @@ > >> +/* { dg-do compile } */ > >> +/* { dg-options "-O2 -Wtrivial-auto-var-init > >> -ftrivial-auto-var-init=zero" } */ > >> + > >> +int g(int *, int *); > >> +int f() > >> +{ > >> + switch (0) { > >> + int x; /* { dg-warning "cannot be initialized with" } */ > >> + int y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g(&x, &y); > >> + } > >> +} > >> + > >> +int g1(int, int); > >> +int f1() > >> +{ > >> + switch (0) { > >> + int x; /* { dg-warning "cannot be initialized with" } */ > >> + int y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g1(x, y); > >> + } > >> +} > >> + > >> +struct S > >> +{ > >> + char a; > >> + int b; > >> +}; > >> +int g2(int); > >> +int f2(int input) > >> +{ > >> + switch (0) { > >> + struct S x; /* { dg-warning "cannot be initialized with" } */ > >> + struct S y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g2(input) + x.b + y.b; > >> + } > >> +} > >> diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c > >> b/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c > >> new file mode 100644 > >> index 00000000000..662e0d1182e > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c > >> @@ -0,0 +1,40 @@ > >> +/* { dg-do compile } */ > >> +/* { dg-options "-O2 -Wtrivial-auto-var-init > >> -ftrivial-auto-var-init=pattern" } */ > >> + > >> +int g(int *, int *); > >> +int f() > >> +{ > >> + switch (0) { > >> + int x; /* { dg-warning "cannot be initialized with" } */ > >> + int y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g(&x, &y); > >> + } > >> +} > >> + > >> +int g1(int, int); > >> +int f1() > >> +{ > >> + switch (0) { > >> + int x; /* { dg-warning "cannot be initialized with" } */ > >> + int y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g1(x, y); > >> + } > >> +} > >> + > >> +struct S > >> +{ > >> + char a; > >> + int b; > >> +}; > >> +int g2(int); > >> +int f2(int input) > >> +{ > >> + switch (0) { > >> + struct S x; /* { dg-warning "cannot be initialized with" } */ > >> + struct S y; /* { dg-warning "cannot be initialized with" } */ > >> + default: > >> + return g2(input) + x.b + y.b; > >> + } > >> +} > >> > > > > -- > > Richard Biener <rguent...@suse.de> > > SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, > > Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg) > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)