Disable some bogus -Wmaybe-uninitialized warnings
authorJan Hubicka <jh@suse.cz>
Mon, 16 Nov 2020 15:31:30 +0000 (16:31 +0100)
committerJan Hubicka <jh@suse.cz>
Mon, 16 Nov 2020 15:31:30 +0000 (16:31 +0100)
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
gcc/testsuite/g++.dg/warn/uninit-1.C [new file with mode: 0644]
gcc/tree-ssa-uninit.c

index 4a43c50aa661c218acd3fa47c562ea89508d8b2a..c7f763eaeff0c3aeb089cebea762376eb0193e96 100644 (file)
@@ -1333,7 +1333,14 @@ analyze_ssa_name_flags (tree name, vec<unsigned char> &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 (file)
index 0000000..30f3cea
--- /dev/null
@@ -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);
+}
index f23514395e08069ec031b722d8b65d24fdcfbe32..c94831bfb75647c677b7a9779d10324e716fdca3 100644 (file)
@@ -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 <gcall *> (stmt))
+           maybe_warn_pass_by_reference (call, wlims);
          else if (gimple_assign_load_p (stmt)
                   && gimple_has_location (stmt))
            {