public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][RFC] tree-optimization/105646 - re-interpret always executed in uninit diag
@ 2022-08-22  6:16 Richard Biener
  2022-09-27 15:47 ` Jeff Law
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2022-08-22  6:16 UTC (permalink / raw)
  To: gcc-patches

The following fixes PR105646, not diagnosing

int f1();
int f3(){
    auto const & a = f1();
    bool v3{v3};
    return a;
}

with optimization because the early uninit diagnostic pass only
diagnoses always executed cases.  The patch does this by
re-interpreting what always executed means and choosing to
ignore exceptional and abnormal control flow for this.  At the
same time it improves things as suggested in a comment - when
the value-numbering run done without optimizing figures there's
a fallthru path, consider blocks on it as always executed.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

	PR tree-optimization/105646
	* tree-ssa-uninit.cc (warn_uninitialized_vars): Pre-compute
	the set of fallthru reachable blocks from function entry
	and use that to determine wlims.always_executed.

	* g++.dg/uninit-pr105646.C: New testcase.
---
 gcc/testsuite/g++.dg/uninit-pr105646.C | 17 +++++++++
 gcc/tree-ssa-uninit.cc                 | 53 +++++++++++++++++++++-----
 2 files changed, 61 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/uninit-pr105646.C

diff --git a/gcc/testsuite/g++.dg/uninit-pr105646.C b/gcc/testsuite/g++.dg/uninit-pr105646.C
new file mode 100644
index 00000000000..48ceb986ec6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/uninit-pr105646.C
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-options "-O2 -Wuninitialized" }
+
+int f1();
+int f2(){
+    bool v2{v2}; // { dg-warning "is used uninitialized" }
+    auto const & a = f1();
+    return a;
+}
+int f3(){
+    auto const & a = f1();
+    // Diagnose the following when optimizing and as unconditional
+    // uninitialized use despite f1 possibly throwing
+    bool v3{v3}; // { dg-warning "is used uninitialized" }
+    return a;
+}
diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc
index 7074c9117b2..b687e24a7e6 100644
--- a/gcc/tree-ssa-uninit.cc
+++ b/gcc/tree-ssa-uninit.cc
@@ -987,10 +987,49 @@ warn_uninitialized_vars (bool wmaybe_uninit)
   wlimits wlims = { };
   wlims.wmaybe_uninit = wmaybe_uninit;
 
-  gimple_stmt_iterator gsi;
-  basic_block bb;
+  auto_bb_flag ft_reachable (cfun);
+
+  /* Mark blocks that are always executed when we ignore provably
+     not executed and EH and abnormal edges.  */
+  basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  while (!(bb->flags & ft_reachable))
+    {
+      bb->flags |= ft_reachable;
+      edge e = find_fallthru_edge (bb->succs);
+      if (e && e->flags & EDGE_EXECUTABLE)
+	{
+	  bb = e->dest;
+	  continue;
+	}
+      /* Find a single executable edge.  */
+      edge_iterator ei;
+      edge ee = NULL;
+      FOR_EACH_EDGE (e, ei, bb->succs)
+	if (e->flags & EDGE_EXECUTABLE)
+	  {
+	    if (!ee)
+	      ee = e;
+	    else
+	      {
+		ee = NULL;
+		break;
+	      }
+	  }
+      if (ee)
+	bb = ee->dest;
+      else
+	{
+	  bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
+	  if (!bb || bb->index == EXIT_BLOCK)
+	    break;
+	}
+    }
+
   FOR_EACH_BB_FN (bb, cfun)
     {
+      wlims.always_executed = (bb->flags & ft_reachable);
+      bb->flags &= ~ft_reachable;
+
       edge_iterator ei;
       edge e;
       FOR_EACH_EDGE (e, ei, bb->preds)
@@ -1001,14 +1040,10 @@ warn_uninitialized_vars (bool wmaybe_uninit)
       if (!e)
 	continue;
 
-      basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
-      /* ???  This could be improved when we use a greedy walk and have
-	 some edges marked as not executable.  */
-      wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
-
       if (wlims.always_executed)
 	warn_uninit_phi_uses (bb);
 
+      gimple_stmt_iterator gsi;
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
 	  gimple *stmt = gsi_stmt (gsi);
@@ -1029,7 +1064,7 @@ warn_uninitialized_vars (bool wmaybe_uninit)
 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
 	    {
 	      /* BIT_INSERT_EXPR first operand should not be considered
-	         a use for the purpose of uninit warnings.  */
+		 a use for the purpose of uninit warnings.  */
 	      if (gassign *ass = dyn_cast <gassign *> (stmt))
 		{
 		  if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
@@ -1040,7 +1075,7 @@ warn_uninitialized_vars (bool wmaybe_uninit)
 	      if (wlims.always_executed)
 		warn_uninit (OPT_Wuninitialized, use,
 			     SSA_NAME_VAR (use), stmt);
-	      else if (wmaybe_uninit)
+	      else if (wlims.wmaybe_uninit)
 		warn_uninit (OPT_Wmaybe_uninitialized, use,
 			     SSA_NAME_VAR (use), stmt);
 	    }
-- 
2.35.3

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][RFC] tree-optimization/105646 - re-interpret always executed in uninit diag
  2022-08-22  6:16 [PATCH][RFC] tree-optimization/105646 - re-interpret always executed in uninit diag Richard Biener
@ 2022-09-27 15:47 ` Jeff Law
  2022-09-29  8:25   ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Jeff Law @ 2022-09-27 15:47 UTC (permalink / raw)
  To: gcc-patches


On 8/22/22 00:16, Richard Biener via Gcc-patches wrote:
> The following fixes PR105646, not diagnosing
>
> int f1();
> int f3(){
>      auto const & a = f1();
>      bool v3{v3};
>      return a;
> }
>
> with optimization because the early uninit diagnostic pass only
> diagnoses always executed cases.  The patch does this by
> re-interpreting what always executed means and choosing to
> ignore exceptional and abnormal control flow for this.  At the
> same time it improves things as suggested in a comment - when
> the value-numbering run done without optimizing figures there's
> a fallthru path, consider blocks on it as always executed.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> OK?
>
> Thanks,
> Richard.
>
> 	PR tree-optimization/105646
> 	* tree-ssa-uninit.cc (warn_uninitialized_vars): Pre-compute
> 	the set of fallthru reachable blocks from function entry
> 	and use that to determine wlims.always_executed.
>
> 	* g++.dg/uninit-pr105646.C: New testcase.

I'm torn on this.  On one hand, ignoring abnormal flow control in the 
early pass is almost certainly going to result in false positives but 
it's also going to result in fixing some false negatives.

I'm willing to ACK and see what the real world fallout is in the spring 
when the distros run their builds.  Your call.


Jeff



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][RFC] tree-optimization/105646 - re-interpret always executed in uninit diag
  2022-09-27 15:47 ` Jeff Law
@ 2022-09-29  8:25   ` Richard Biener
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Biener @ 2022-09-29  8:25 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Tue, Sep 27, 2022 at 5:48 PM Jeff Law via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
>
> On 8/22/22 00:16, Richard Biener via Gcc-patches wrote:
> > The following fixes PR105646, not diagnosing
> >
> > int f1();
> > int f3(){
> >      auto const & a = f1();
> >      bool v3{v3};
> >      return a;
> > }
> >
> > with optimization because the early uninit diagnostic pass only
> > diagnoses always executed cases.  The patch does this by
> > re-interpreting what always executed means and choosing to
> > ignore exceptional and abnormal control flow for this.  At the
> > same time it improves things as suggested in a comment - when
> > the value-numbering run done without optimizing figures there's
> > a fallthru path, consider blocks on it as always executed.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > OK?
> >
> > Thanks,
> > Richard.
> >
> >       PR tree-optimization/105646
> >       * tree-ssa-uninit.cc (warn_uninitialized_vars): Pre-compute
> >       the set of fallthru reachable blocks from function entry
> >       and use that to determine wlims.always_executed.
> >
> >       * g++.dg/uninit-pr105646.C: New testcase.
>
> I'm torn on this.  On one hand, ignoring abnormal flow control in the
> early pass is almost certainly going to result in false positives but
> it's also going to result in fixing some false negatives.
>
> I'm willing to ACK and see what the real world fallout is in the spring
> when the distros run their builds.  Your call.

I have pushed this now after retesting.  Let's see if there's any bad
fallout - we can certainly reconsider.

Richard.

>
> Jeff
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-09-29  8:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-22  6:16 [PATCH][RFC] tree-optimization/105646 - re-interpret always executed in uninit diag Richard Biener
2022-09-27 15:47 ` Jeff Law
2022-09-29  8:25   ` Richard Biener

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).