* [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
@ 2022-02-19 16:24 Qing Zhao
2022-02-24 4:20 ` Fwd: " Qing Zhao
2022-02-24 10:16 ` Richard Biener
0 siblings, 2 replies; 6+ messages in thread
From: Qing Zhao @ 2022-02-19 16:24 UTC (permalink / raw)
To: richard Biener, Jakub Jelinek; +Cc: kees Cook, gcc-patches Paul A Clarke via
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.zhao@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.zhao@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.
+
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");
+ }
+ }
+
+ 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;
+ }
+}
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Fwd: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
2022-02-19 16:24 [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation Qing Zhao
@ 2022-02-24 4:20 ` Qing Zhao
2022-02-24 10:16 ` Richard Biener
1 sibling, 0 replies; 6+ messages in thread
From: Qing Zhao @ 2022-02-24 4:20 UTC (permalink / raw)
To: richard Biener, Jakub Jelinek; +Cc: gcc-patches Paul A Clarke via
Ping...
Qing
Begin forwarded message:
From: Qing Zhao via Gcc-patches <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>
Subject: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
Date: February 19, 2022 at 10:24:09 AM CST
To: richard Biener <rguenther@suse.de<mailto:rguenther@suse.de>>, Jakub Jelinek <jakub@redhat.com<mailto:jakub@redhat.com>>
Cc: gcc-patches Paul A Clarke via <gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>>, kees Cook <keescook@chromium.org<mailto:keescook@chromium.org>>
Reply-To: Qing Zhao <qing.zhao@oracle.com<mailto:qing.zhao@oracle.com>>
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.zhao@oracle.com<mailto:qing.zhao@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.zhao@oracle.com<mailto:qing.zhao@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<http://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<http://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.
+
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<http://gimplify.cc> b/gcc/gimplify.cc<http://gimplify.cc>
index 4e3bbf5314d..7e52794691f 100644
--- a/gcc/gimplify.cc<http://gimplify.cc>
+++ b/gcc/gimplify.cc<http://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<http://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<http://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");
+ }
+ }
+
+ 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;
+ }
+}
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
2022-02-19 16:24 [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation Qing Zhao
2022-02-24 4:20 ` Fwd: " Qing Zhao
@ 2022-02-24 10:16 ` Richard Biener
2022-02-24 15:17 ` Qing Zhao
1 sibling, 1 reply; 6+ messages in thread
From: Richard Biener @ 2022-02-24 10:16 UTC (permalink / raw)
To: Qing Zhao; +Cc: Jakub Jelinek, kees Cook, gcc-patches Paul A Clarke via
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.zhao@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.zhao@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.
> 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.
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 <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
2022-02-24 10:16 ` Richard Biener
@ 2022-02-24 15:17 ` Qing Zhao
2022-02-25 12:43 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Qing Zhao @ 2022-02-24 15:17 UTC (permalink / raw)
To: Richard Biener; +Cc: Jakub Jelinek, kees Cook, gcc-patches Paul A Clarke via
> On Feb 24, 2022, at 4:16 AM, Richard Biener <rguenther@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.zhao@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.zhao@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?
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 <rguenther@suse.de>
> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
> Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
2022-02-24 15:17 ` Qing Zhao
@ 2022-02-25 12:43 ` Richard Biener
2022-02-25 15:04 ` Qing Zhao
0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2022-02-25 12:43 UTC (permalink / raw)
To: Qing Zhao; +Cc: Jakub Jelinek, kees Cook, gcc-patches Paul A Clarke via
On Thu, 24 Feb 2022, Qing Zhao wrote:
>
>
> > On Feb 24, 2022, at 4:16 AM, Richard Biener <rguenther@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.zhao@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.zhao@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 <rguenther@suse.de>
> > SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
> > Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation.
2022-02-25 12:43 ` Richard Biener
@ 2022-02-25 15:04 ` Qing Zhao
0 siblings, 0 replies; 6+ messages in thread
From: Qing Zhao @ 2022-02-25 15:04 UTC (permalink / raw)
To: Richard Biener; +Cc: Jakub Jelinek, kees Cook, gcc-patches Paul A Clarke via
> On Feb 25, 2022, at 6:43 AM, Richard Biener <rguenther@suse.de> wrote:
>
> On Thu, 24 Feb 2022, Qing Zhao wrote:
>
>>
>>
>>> On Feb 24, 2022, at 4:16 AM, Richard Biener <rguenther@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.zhao@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.zhao@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.
Okay.
Qing
>
> 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 <rguenther@suse.de>
>>> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
>>> Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
>>
>>
>
> --
> Richard Biener <rguenther@suse.de>
> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
> Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-02-25 15:04 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-19 16:24 [PATCH 2/2][middle-end/102276] Adding -Wtrivial-auto-var-init and update documentation Qing Zhao
2022-02-24 4:20 ` Fwd: " Qing Zhao
2022-02-24 10:16 ` Richard Biener
2022-02-24 15:17 ` Qing Zhao
2022-02-25 12:43 ` Richard Biener
2022-02-25 15:04 ` Qing Zhao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).