Bug 56654 - uninit warning behaves erratically (always executed block, "is" vs "may", order when walking uses)
Summary: uninit warning behaves erratically (always executed block, "is" vs "may", ord...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.9.0
: P3 enhancement
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2013-03-18 13:37 UTC by Richard Biener
Modified: 2022-08-30 07:33 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 10.2.0, 11.0, 4.9.3, 5.3.0, 6.2.0, 7.5.0, 8.3.0, 9.3.0
Last reconfirmed: 2021-03-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2013-03-18 13:37:50 UTC
For c-c++-common/uninit-17.c we currently expect the uninit use at:

static void bar(int a, int *ptr)
{
  do
  {
    int b;   /* { dg-message "declared" } */
    if (b < 40) {
      ptr[0] = b;
    }
    b += 1; /* { dg-warning "may be used uninitialized" } */
    ptr++;
  }
  while (--a != 0);
}

where I would expect it at the if stmt.  Now, when I exchange the late
DOM and the late VRP passes I instead get the warning two lines earlier
(inside the guarded BB).  But there is no change in the IL:

> diff -u a/uninit-17.c.131t.uninit1 b/uninit-17.c.131t.uninit1 
--- a/uninit-17.c.131t.uninit1  2013-03-18 14:27:16.677116283 +0100
+++ b/uninit-17.c.131t.uninit1  2013-03-18 14:26:58.956922876 +0100
@@ -3,7 +3,13 @@
 
 [WORKLIST]: add to initial list: b_5 = PHI <b_13(D)(2), b_7(6)>
 [CHECK]: examining phi: b_5 = PHI <b_13(D)(2), b_7(6)>
-[CHECK]: Found unguarded use: b_7 = b_5 + 1;
+
+Use in stmt *ptr_6 = b_5;
+is guarded by :
+if (b_5 <= 39)
+
+[CHECK] Found def edge 1 in b_5 = PHI <b_13(D)(2), b_7(6)>
+[CHECK]: Found unguarded use: *ptr_6 = b_5;
 void foobar(int, int*) (int a, int * ptr)
 {
   int b;

the only difference is in the order of b_5 immediate uses.

That is, find_uninit_use should impose an ordering when walking over
immediate uses - for example visit the most dominating use first.
Comment 1 Manuel López-Ibáñez 2014-09-11 14:17:23 UTC
But while this is not simple a "is used" because of "if (b < 40)"? That seems to be the major bug here.
Comment 2 Manuel López-Ibáñez 2014-09-11 22:14:15 UTC
(In reply to Manuel López-Ibáñez from comment #1)
> But while this is not simple a "is used" because of "if (b < 40)"? That
> seems to be the major bug here.

Wow, I should not type in a hurry. What I meant to say is:

Given "if (b < 40)", why is this not warned as "is used uninit"?
Comment 3 Manuel López-Ibáñez 2014-09-12 13:53:29 UTC
Anyway, it is at least one bug, perhaps more.
Comment 4 Martin Sebor 2021-03-26 16:41:56 UTC
Reconfirming with GCC 11.
Comment 5 Richard Biener 2022-08-29 14:09:41 UTC
We do now diagnose "is used uninitialized", the ordering issue remains and I have a patch for that that sorts after RPO but doesn't sort within the block if there is more than one candidate.
Comment 6 GCC Commits 2022-08-30 07:33:16 UTC
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>:

https://gcc.gnu.org/g:8a63343a744a8584a9dfcbc3817f66755baafe8a

commit r13-2261-g8a63343a744a8584a9dfcbc3817f66755baafe8a
Author: Richard Biener <rguenther@suse.de>
Date:   Mon Aug 29 16:16:44 2022 +0200

    tree-optimization/56654 - sort uninit candidates after RPO
    
    The following sorts the immediate uses of a possibly uninitialized
    SSA variable after their RPO order so we prefer warning for an
    earlier occuring use rather than issueing the diagnostic for the
    first uninitialized immediate use.
    
    The sorting will inevitably be imperfect but it also allows us to
    optimize the expensive predicate check for the case where there
    are multiple uses in the same basic-block which is a nice side-effect.
    
            PR tree-optimization/56654
            * tree-ssa-uninit.cc (cand_cmp): New.
            (find_uninit_use): First process all PHIs and collect candidate
            stmts, then sort those after RPO.
            (warn_uninitialized_phi): Pass on bb_to_rpo.
            (execute_late_warn_uninitialized): Compute and pass on
            reverse lookup of RPO number from basic block index.
Comment 7 Richard Biener 2022-08-30 07:33:43 UTC
Fixed.