From 0c9687d0daa08c33456210b87e4060d6397ff4d8 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 16 Nov 2020 16:31:30 +0100 Subject: [PATCH] Disable some bogus -Wmaybe-uninitialized warnings gcc/ChangeLog: PR middle-end/97840 * ipa-modref.c (analyze_ssa_name_flags): Skip clobbers if inlining is done. * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Make stmt gcall; skip const calls and unused arguments. (warn_uninitialized_vars): Update prototype. gcc/testsuite/ChangeLog: * g++.dg/warn/uninit-1.C: New test. --- gcc/ipa-modref.c | 9 ++++++++- gcc/testsuite/g++.dg/warn/uninit-1.C | 29 +++++++++++++++++++++++++++++ gcc/tree-ssa-uninit.c | 14 +++++++++++--- 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/uninit-1.C diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index 4a43c50..c7f763e 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -1333,7 +1333,14 @@ analyze_ssa_name_flags (tree name, vec &known_flags, int depth) /* Handle *name = exp. */ else if (assign && memory_access_to (gimple_assign_lhs (assign), name)) - flags &= ~(EAF_UNUSED | EAF_NOCLOBBER); + { + /* In general we can not ignore clobbers because they are + barriers for code motion, however after inlining it is safe to + do because local optimization passes do not consider clobbers + from other functions. Similar logic is in ipa-pure-const.c. */ + if (!cfun->after_inlining || !gimple_clobber_p (assign)) + flags &= ~(EAF_UNUSED | EAF_NOCLOBBER); + } /* ASM statements etc. */ else if (!assign) { diff --git a/gcc/testsuite/g++.dg/warn/uninit-1.C b/gcc/testsuite/g++.dg/warn/uninit-1.C new file mode 100644 index 0000000..30f3cea --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/uninit-1.C @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wmaybe-uninitialized" } */ +struct a {int a;}; +__attribute__ ((noinline)) +void +nowarn (const struct a *ptr) +{ + if (ptr) + asm volatile (""); +} +void +test() +{ + struct a ptr; + nowarn (&ptr); +} +__attribute__ ((noinline)) +int +nowarn2 (const struct a *ptr, const struct a ptr2) +{ + return ptr != 0 || ptr2.a; +} +int mem; +int +test2() +{ + struct a ptr,ptr2={0}; + return nowarn2 (&ptr, ptr2); +} diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index f235143..c94831b 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -443,7 +443,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, access implying read access to those objects. */ static void -maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims) +maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims) { if (!wlims.wmaybe_uninit) return; @@ -457,6 +457,10 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims) if (!fntype) return; + /* Const function do not read their arguments. */ + if (gimple_call_flags (stmt) & ECF_CONST) + return; + const built_in_function fncode = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL) ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST); @@ -523,6 +527,10 @@ maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims) (but not definitive) read access. */ wlims.always_executed = false; + /* Ignore args we are not going to read from. */ + if (gimple_call_arg_flags (stmt, argno - 1) & EAF_UNUSED) + continue; + tree arg = gimple_call_arg (stmt, argno - 1); ao_ref ref; @@ -639,8 +647,8 @@ warn_uninitialized_vars (bool wmaybe_uninit) if (gimple_vdef (stmt)) wlims.vdef_cnt++; - if (is_gimple_call (stmt)) - maybe_warn_pass_by_reference (stmt, wlims); + if (gcall *call = dyn_cast (stmt)) + maybe_warn_pass_by_reference (call, wlims); else if (gimple_assign_load_p (stmt) && gimple_has_location (stmt)) { -- 2.7.4