public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10
@ 2020-08-11  7:30 stefansf at linux dot ibm.com
  2020-08-11  9:27 ` [Bug middle-end/96564] " glisse at gcc dot gnu.org
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: stefansf at linux dot ibm.com @ 2020-08-11  7:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

            Bug ID: 96564
           Summary: New maybe use of uninitialized variable warning since
                    GCC >10
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: stefansf at linux dot ibm.com
  Target Milestone: ---

Consider the following MWE:

extern void* malloc (long unsigned int);
void fun (unsigned *x) {
  unsigned *a = malloc (*x);
  if (a == 0)
    return;
  if (a != x)            // (A)
    *a = *x;
  *x = *a;
}

If compiled with GCC 10, then no warning is emitted.

If compiled with GCC HEAD (currently 84005b8abf9), then the following warning
is emitted:

gcc -W -c -O2 mwe.c
mwe.c: In function 'fun':
mwe.c:8:8: warning: '*(a)' may be used uninitialized [-Wmaybe-uninitialized]
    8 |   *x = *a;
      |        ^~

Rational why this example is strictly speaking fine:

1) Assume x is a valid pointer.  Then malloc will either return a nullpointer
and we return, or a pointer to a fresh object which address is different from
any other existing object.  Thus (A) always evaluates to true which means *a is
initialized.

2) Assume x is an invalid pointer.  Then dereferencing x prior to the call to
malloc already results in UB.

Thus the only case in which condition (A) may evaluate to false is when x is an
invalid pointer (e.g. previously malloc'd and then free'd such that a further
call to malloc returns the very same address rendering (A) false) results in
UB.

Since this is a maybe warning I'm wondering whether this is considered a bug or
is acceptable.  Any thoughts?

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

* [Bug middle-end/96564] New maybe use of uninitialized variable warning since GCC >10
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
@ 2020-08-11  9:27 ` glisse at gcc dot gnu.org
  2020-08-11  9:47 ` [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959 jakub at gcc dot gnu.org
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: glisse at gcc dot gnu.org @ 2020-08-11  9:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
I think there are duplicates about the fact that while gcc knows that a and x
cannot alias (if you read *x, write to *a, then read from *x again, gcc reuses
the first value), it does not use that information to fold comparisons between
x and a.

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
  2020-08-11  9:27 ` [Bug middle-end/96564] " glisse at gcc dot gnu.org
@ 2020-08-11  9:47 ` jakub at gcc dot gnu.org
  2020-08-11 17:10 ` msebor at gcc dot gnu.org
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-08-11  9:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2020-08-11
   Target Milestone|---                         |11.0
             Status|UNCONFIRMED                 |NEW
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |msebor at gcc dot gnu.org
            Summary|New maybe use of            |[11 Regression] New maybe
                   |uninitialized variable      |use of uninitialized
                   |warning since GCC >10       |variable warning since
                   |                            |r11-959
     Ever confirmed|0                           |1

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Started with r11-959-gb825a22890740f341eae566af27e18e528cd29a7

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
  2020-08-11  9:27 ` [Bug middle-end/96564] " glisse at gcc dot gnu.org
  2020-08-11  9:47 ` [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959 jakub at gcc dot gnu.org
@ 2020-08-11 17:10 ` msebor at gcc dot gnu.org
  2020-08-11 17:24 ` msebor at gcc dot gnu.org
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-08-11 17:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=87313
           Keywords|                            |alias, diagnostic,
                   |                            |missed-optimization

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
r11-959 enabled -Wuninitialized for allocated objects (alloca/VLA and malloc). 
The underlying problem is the failure to take advantage of the non-aliasing
guarantee of the return value of these functions.  One report that describes
this limitation is pr87313.  A slightly simpler but even more obvious test case
is:

$ cat pr96564.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout
pr96564.c
void f (int *x)
{
  int a[*x];

  if (a != x)
    *a = 0;

  *x = *a;
}

pr96564.c: In function ‘f’:
pr96564.c:8:6: warning: ‘*(<unknown>)[0]’ may be used uninitialized
[-Wmaybe-uninitialized]
    8 |   *x = *a;
      |   ~~~^~~~

;; Function f (f, funcdef_no=0, decl_uid=1931, cgraph_uid=1, symbol_order=0)

Removing basic block 5
f (int * x)
{
  int[0:D.1936] * a.0;
  sizetype _2;
  int _8;
  sizetype _9;
  int prephitmp_18;
  int pretmp_20;

  <bb 2> [local count: 1073741824]:
  _8 = *x_1(D);
  _2 = (sizetype) _8;
  _9 = _2 * 4;
  a.0_11 = __builtin_alloca_with_align (_9, 32);
  if (x_1(D) != a.0_11)
    goto <bb 4>; [70.00%]
  else
    goto <bb 3>; [30.00%]

  <bb 3> [local count: 322122544]:
  pretmp_20 = (*a.0_11)[0];

  <bb 4> [local count: 1073741824]:
  # prephitmp_18 = PHI <pretmp_20(3), 0(2)>
  *x_1(D) = prephitmp_18;
  return;

}

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (2 preceding siblings ...)
  2020-08-11 17:10 ` msebor at gcc dot gnu.org
@ 2020-08-11 17:24 ` msebor at gcc dot gnu.org
  2020-08-25  8:20 ` rguenth at gcc dot gnu.org
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: msebor at gcc dot gnu.org @ 2020-08-11 17:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=13962

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
Another (much older and borader) request to make use of the aliasing guarantee
for pointer comparisons is pr13962.

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (3 preceding siblings ...)
  2020-08-11 17:24 ` msebor at gcc dot gnu.org
@ 2020-08-25  8:20 ` rguenth at gcc dot gnu.org
  2021-01-14  9:19 ` rguenth at gcc dot gnu.org
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-08-25  8:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
note alias cannot disabiguate (A) on its own since both a and x could be NULL,
it additionally needs the flow-based info that a is not NULL at (A).

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (4 preceding siblings ...)
  2020-08-25  8:20 ` rguenth at gcc dot gnu.org
@ 2021-01-14  9:19 ` rguenth at gcc dot gnu.org
  2021-02-11 10:48 ` jakub at gcc dot gnu.org
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-01-14  9:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2

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

* [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (5 preceding siblings ...)
  2021-01-14  9:19 ` rguenth at gcc dot gnu.org
@ 2021-02-11 10:48 ` jakub at gcc dot gnu.org
  2021-04-27 11:39 ` [Bug middle-end/96564] [11/12 " jakub at gcc dot gnu.org
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-02-11 10:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amacleod at redhat dot com

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
While SSA_NAME_PTR_INFO/get_ptr_nonnull can't do this, either vrp pass or any
other pass that would be using ranger can do that.  So what pass would be the
best match for that?

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

* [Bug middle-end/96564] [11/12 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (6 preceding siblings ...)
  2021-02-11 10:48 ` jakub at gcc dot gnu.org
@ 2021-04-27 11:39 ` jakub at gcc dot gnu.org
  2021-07-28  7:05 ` rguenth at gcc dot gnu.org
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-04-27 11:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|11.0                        |11.2

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
GCC 11.1 has been released, retargeting bugs to GCC 11.2.

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

* [Bug middle-end/96564] [11/12 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (7 preceding siblings ...)
  2021-04-27 11:39 ` [Bug middle-end/96564] [11/12 " jakub at gcc dot gnu.org
@ 2021-07-28  7:05 ` rguenth at gcc dot gnu.org
  2022-04-21  7:48 ` rguenth at gcc dot gnu.org
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-07-28  7:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|11.2                        |11.3

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 11.2 is being released, retargeting bugs to GCC 11.3

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

* [Bug middle-end/96564] [11/12 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (8 preceding siblings ...)
  2021-07-28  7:05 ` rguenth at gcc dot gnu.org
@ 2022-04-21  7:48 ` rguenth at gcc dot gnu.org
  2023-03-14  5:00 ` [Bug middle-end/96564] [11/12/13 " pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-04-21  7:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|11.3                        |11.4

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 11.3 is being released, retargeting bugs to GCC 11.4.

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

* [Bug middle-end/96564] [11/12/13 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (9 preceding siblings ...)
  2022-04-21  7:48 ` rguenth at gcc dot gnu.org
@ 2023-03-14  5:00 ` pinskia at gcc dot gnu.org
  2023-05-29 10:03 ` [Bug middle-end/96564] [11/12/13/14 " jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-03-14  5:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #10 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note I don't think you really need exact aliasing information to optimize this
though. See PR 109119 for an example where you just need to know on the path
where PRE adds the load, the two addresses are equal due to the condition.

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (10 preceding siblings ...)
  2023-03-14  5:00 ` [Bug middle-end/96564] [11/12/13 " pinskia at gcc dot gnu.org
@ 2023-05-29 10:03 ` jakub at gcc dot gnu.org
  2024-03-10 22:49 ` law at gcc dot gnu.org
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-05-29 10:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|11.4                        |11.5

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
GCC 11.4 is being released, retargeting bugs to GCC 11.5.

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (11 preceding siblings ...)
  2023-05-29 10:03 ` [Bug middle-end/96564] [11/12/13/14 " jakub at gcc dot gnu.org
@ 2024-03-10 22:49 ` law at gcc dot gnu.org
  2024-03-11 10:23 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: law at gcc dot gnu.org @ 2024-03-10 22:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

Jeffrey A. Law <law at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #12 from Jeffrey A. Law <law at gcc dot gnu.org> ---
So I think we could solve this with a bit of help from the alias oracle.  We
have  the routine ptrs_compare_unequal, but points-to-null is going to get in
the way.

I think VRP and DOM have enough information to rule out NULL for both objects
in question.  So if we could query the points-to information, ignoring NULL
then we could likely solve this particular bug.

Essentially VRP or DOM would prove NULL isn't in the set of possible values at
the comparison point.  Then we query the alias information ignoring NULL. 
Voila we compute a static result for the comparison of the two pointers and the
problematical block becomes unreachable and the bogus warning goes away.

Richi, any thoughts in viability of such an API?

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (12 preceding siblings ...)
  2024-03-10 22:49 ` law at gcc dot gnu.org
@ 2024-03-11 10:23 ` rguenth at gcc dot gnu.org
  2024-03-11 13:26 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-03-11 10:23 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #12)
> So I think we could solve this with a bit of help from the alias oracle.  We
> have  the routine ptrs_compare_unequal, but points-to-null is going to get
> in the way.
> 
> I think VRP and DOM have enough information to rule out NULL for both
> objects in question.  So if we could query the points-to information,
> ignoring NULL then we could likely solve this particular bug.
> 
> Essentially VRP or DOM would prove NULL isn't in the set of possible values
> at the comparison point.  Then we query the alias information ignoring NULL.
> Voila we compute a static result for the comparison of the two pointers and
> the problematical block becomes unreachable and the bogus warning goes away.
> 
> Richi, any thoughts in viability of such an API?

We now treat pt.null conservatively and track non-null-ness derived from
range-info in it.  That means when VRP/DOM can prove a pointer is always
not NULL they can do set_ptr_nonnull (p) on it.

This means the

  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
     but those require pt.null to be conservatively correct.  */

is no longer true and we could finally implement it, like with

diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index e7c1c1aa624..5b6d9e0aa6a 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -479,9 +479,25 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
        }
       return !pt_solution_includes (&pi->pt, obj1);
     }
-
-  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
-     but those require pt.null to be conservatively correct.  */
+  else if (TREE_CODE (ptr1) == SSA_NAME)
+    {
+      struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1);
+      if (!pi1
+         || pi1->pt.vars_contains_restrict
+         || pi1->pt.vars_contains_interposable)
+       return false;
+      if (integer_zerop (ptr2) && !pi1->pt.null)
+       return true;
+      if (TREE_CODE (ptr2) == SSA_NAME)
+       {
+         struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2);
+         if (!pi2
+             || pi2->pt.vars_contains_restrict
+             || pi2->pt.vars_contains_interposable)
+         if (!pi1->pt.null || !pi2->pt.null)
+           return !pt_solutions_intersect (&pi1->pt, &pi2->pt);
+       }
+    }

   return false;
 }


but the testcase shows the non-null-ness is only conditional which means
we'd have to use a range query above which necessarily falls back to
the global ranges given we don't have any context available here.  The
old EVRP adjusted global ranges during the walk but this is no longer done.

Note it's enough that one pointer is nonnull, so for your idea the
API could be extended with a bool one_ptr_nonnull parameter.

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (13 preceding siblings ...)
  2024-03-11 10:23 ` rguenth at gcc dot gnu.org
@ 2024-03-11 13:26 ` rguenth at gcc dot gnu.org
  2024-03-11 15:20 ` amacleod at redhat dot com
  2024-03-12  7:37 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-03-11 13:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> ---
gcc.c-torture/execute/pr64242.c is one of the testcases FAILing (guess it's
invalid)

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (14 preceding siblings ...)
  2024-03-11 13:26 ` rguenth at gcc dot gnu.org
@ 2024-03-11 15:20 ` amacleod at redhat dot com
  2024-03-12  7:37 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: amacleod at redhat dot com @ 2024-03-11 15:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #15 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Richard Biener from comment #13)
> (In reply to Jeffrey A. Law from comment #12)
> > So I think we could solve this with a bit of help from the alias oracle.  We
> > have  the routine ptrs_compare_unequal, but points-to-null is going to get
> > in the way.
> > 
> > I think VRP and DOM have enough information to rule out NULL for both
> > objects in question.  So if we could query the points-to information,
> > ignoring NULL then we could likely solve this particular bug.
> > 
> > Essentially VRP or DOM would prove NULL isn't in the set of possible values
> > at the comparison point.  Then we query the alias information ignoring NULL.
> > Voila we compute a static result for the comparison of the two pointers and
> > the problematical block becomes unreachable and the bogus warning goes away.
> > 
> > Richi, any thoughts in viability of such an API?
> 
> We now treat pt.null conservatively and track non-null-ness derived from
> range-info in it.  That means when VRP/DOM can prove a pointer is always
> not NULL they can do set_ptr_nonnull (p) on it.
> 
> This means the
> 
>   /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
>      but those require pt.null to be conservatively correct.  */
> 
> is no longer true and we could finally implement it, like with
> 
> diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
> index e7c1c1aa624..5b6d9e0aa6a 100644
> --- a/gcc/tree-ssa-alias.cc
> +++ b/gcc/tree-ssa-alias.cc
> @@ -479,9 +479,25 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
>         }
>        return !pt_solution_includes (&pi->pt, obj1);
>      }
> -
> -  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
> -     but those require pt.null to be conservatively correct.  */
> +  else if (TREE_CODE (ptr1) == SSA_NAME)
> +    {
> +      struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1);
> +      if (!pi1
> +         || pi1->pt.vars_contains_restrict
> +         || pi1->pt.vars_contains_interposable)
> +       return false;
> +      if (integer_zerop (ptr2) && !pi1->pt.null)
> +       return true;
> +      if (TREE_CODE (ptr2) == SSA_NAME)
> +       {
> +         struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2);
> +         if (!pi2
> +             || pi2->pt.vars_contains_restrict
> +             || pi2->pt.vars_contains_interposable)
> +         if (!pi1->pt.null || !pi2->pt.null)
> +           return !pt_solutions_intersect (&pi1->pt, &pi2->pt);
> +       }
> +    }
>  
>    return false;
>  }
> 
> 
> but the testcase shows the non-null-ness is only conditional which means
> we'd have to use a range query above which necessarily falls back to
> the global ranges given we don't have any context available here.  The
> old EVRP adjusted global ranges during the walk but this is no longer done.
> 
You mean it lied?  because x_1 is not NULL until after _8 = *x_1(D); executes. 
It can still be NULL on that stmt can it not?   Did it reset the global value
afterwards?

Contextually ranger knows both are non-null at EVRP time:
a.0_27 : [irange] int[0:D.xxxx] * [1, +INF]
2->3  (T) x_1(D) :     [irange] int * [1, +INF]
2->3  (T) a.0_27 :      [irange] int[0:D.xxxx] * [1, +INF]
2->4  (F) x_1(D) :     [irange] int * [1, +INF]
2->4  (F) a.0_27 :      [irange] int[0:D.xxxx] * [1, +INF]

So we know x_1 is non-NULL after the de-reference for the rest of the block
(and function).  It also sets a.0_27 globally to be [1, +INF].


> Note it's enough that one pointer is nonnull, so for your idea the
> API could be extended with a bool one_ptr_nonnull parameter.

ranger currently sets a.0 globally to be non-null in EVRP.

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

* [Bug middle-end/96564] [11/12/13/14 Regression] New maybe use of uninitialized variable warning since r11-959
  2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
                   ` (15 preceding siblings ...)
  2024-03-11 15:20 ` amacleod at redhat dot com
@ 2024-03-12  7:37 ` rguenth at gcc dot gnu.org
  16 siblings, 0 replies; 18+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-03-12  7:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96564

--- Comment #16 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Macleod from comment #15)
> (In reply to Richard Biener from comment #13)
> > (In reply to Jeffrey A. Law from comment #12)
> > > So I think we could solve this with a bit of help from the alias oracle.  We
> > > have  the routine ptrs_compare_unequal, but points-to-null is going to get
> > > in the way.
> > > 
> > > I think VRP and DOM have enough information to rule out NULL for both
> > > objects in question.  So if we could query the points-to information,
> > > ignoring NULL then we could likely solve this particular bug.
> > > 
> > > Essentially VRP or DOM would prove NULL isn't in the set of possible values
> > > at the comparison point.  Then we query the alias information ignoring NULL.
> > > Voila we compute a static result for the comparison of the two pointers and
> > > the problematical block becomes unreachable and the bogus warning goes away.
> > > 
> > > Richi, any thoughts in viability of such an API?
> > 
> > We now treat pt.null conservatively and track non-null-ness derived from
> > range-info in it.  That means when VRP/DOM can prove a pointer is always
> > not NULL they can do set_ptr_nonnull (p) on it.
> > 
> > This means the
> > 
> >   /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
> >      but those require pt.null to be conservatively correct.  */
> > 
> > is no longer true and we could finally implement it, like with
> > 
> > diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
> > index e7c1c1aa624..5b6d9e0aa6a 100644
> > --- a/gcc/tree-ssa-alias.cc
> > +++ b/gcc/tree-ssa-alias.cc
> > @@ -479,9 +479,25 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
> >         }
> >        return !pt_solution_includes (&pi->pt, obj1);
> >      }
> > -
> > -  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
> > -     but those require pt.null to be conservatively correct.  */
> > +  else if (TREE_CODE (ptr1) == SSA_NAME)
> > +    {
> > +      struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1);
> > +      if (!pi1
> > +         || pi1->pt.vars_contains_restrict
> > +         || pi1->pt.vars_contains_interposable)
> > +       return false;
> > +      if (integer_zerop (ptr2) && !pi1->pt.null)
> > +       return true;
> > +      if (TREE_CODE (ptr2) == SSA_NAME)
> > +       {
> > +         struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2);
> > +         if (!pi2
> > +             || pi2->pt.vars_contains_restrict
> > +             || pi2->pt.vars_contains_interposable)
> > +         if (!pi1->pt.null || !pi2->pt.null)
> > +           return !pt_solutions_intersect (&pi1->pt, &pi2->pt);
> > +       }
> > +    }
> >  
> >    return false;
> >  }
> > 
> > 
> > but the testcase shows the non-null-ness is only conditional which means
> > we'd have to use a range query above which necessarily falls back to
> > the global ranges given we don't have any context available here.  The
> > old EVRP adjusted global ranges during the walk but this is no longer done.
> > 
> You mean it lied?  because x_1 is not NULL until after _8 = *x_1(D);
> executes.  It can still be NULL on that stmt can it not?   Did it reset the
> global value afterwards?

Yes and yes, old EVRP turned global ranges into "ranges at the point of
stmt evaluation/folding" (and restored them to the global values later).
Note that EVRP didn't do any sort of iteration for loop handling and it
folded stmts as it analyzed them.  Using the global ranges as "lattice"
had the advantage that all folding utilities picked up "local" ranges
for free.  IMO it was quite elegant and fast what EVRP did (with it's
obvious limitations of course).

> Contextually ranger knows both are non-null at EVRP time:
> a.0_27 : [irange] int[0:D.xxxx] * [1, +INF]
> 2->3  (T) x_1(D) :     [irange] int * [1, +INF]
> 2->3  (T) a.0_27 :      [irange] int[0:D.xxxx] * [1, +INF]
> 2->4  (F) x_1(D) :     [irange] int * [1, +INF]
> 2->4  (F) a.0_27 :      [irange] int[0:D.xxxx] * [1, +INF]
> 
> So we know x_1 is non-NULL after the de-reference for the rest of the block
> (and function).  It also sets a.0_27 globally to be [1, +INF].
> 
> > Note it's enough that one pointer is nonnull, so for your idea the
> > API could be extended with a bool one_ptr_nonnull parameter.
> 
> ranger currently sets a.0 globally to be non-null in EVRP.

After EVRP I see

  # PT = nonlocal null
  unsigned int * x_8(D) = x;
...
  <bb 2> :
  _1 = *x_8(D);
  # RANGE [irange] long unsigned int [0, 4294967295] MASK 0xffffffff VALUE 0x0
  _2 = (long unsigned int) _1;
  # PT = null { D.2781 }
  # ALIGN = 8, MISALIGN = 0
  # USE = nonlocal escaped
  # CLB = nonlocal escaped
  a_10 = malloc (_2);
  if (a_10 == 0B)
...
  <bb 4> :
  if (x_8(D) != a_10)

the last test is the one we want to eliminate.  The proposed change (with
a missing 'return false' fixed) isn't enough since it just looks at
global ranges where both x_8 and a_10 can be null.  In the
ptrs_compare_unequal function I could at most use range_of_expr without
a stmt context (as I don't have that) which wouldn't help.  EVRP with
the trick to adjust global ranges effectively had a "global context"
it would use.  I suppose that one could have something like that for
ranger as well, add ranger::set_context (gimple *) which EVRP could set
when folding a stmt (set it to right before 'stmt' execution) and which
would be the context to fall back to when a folding dependent utility
didn't specify one?

Adding a global (not ranger specific) "folding context stack" might do
the trick as well.  Any utility that could take advantage of a context
could look at the stack top (which might be NULL).  That would be less
churn than wrapping each and every folding function inside a "folder"
class containing a context.

Of course one has to be careful with such a thing, like with recursively
invoking number of iteration or SCEV analysis which work on a more fuzzy
context than a specific stmt contained in a loop.

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

end of thread, other threads:[~2024-03-12  7:37 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-11  7:30 [Bug middle-end/96564] New: New maybe use of uninitialized variable warning since GCC >10 stefansf at linux dot ibm.com
2020-08-11  9:27 ` [Bug middle-end/96564] " glisse at gcc dot gnu.org
2020-08-11  9:47 ` [Bug middle-end/96564] [11 Regression] New maybe use of uninitialized variable warning since r11-959 jakub at gcc dot gnu.org
2020-08-11 17:10 ` msebor at gcc dot gnu.org
2020-08-11 17:24 ` msebor at gcc dot gnu.org
2020-08-25  8:20 ` rguenth at gcc dot gnu.org
2021-01-14  9:19 ` rguenth at gcc dot gnu.org
2021-02-11 10:48 ` jakub at gcc dot gnu.org
2021-04-27 11:39 ` [Bug middle-end/96564] [11/12 " jakub at gcc dot gnu.org
2021-07-28  7:05 ` rguenth at gcc dot gnu.org
2022-04-21  7:48 ` rguenth at gcc dot gnu.org
2023-03-14  5:00 ` [Bug middle-end/96564] [11/12/13 " pinskia at gcc dot gnu.org
2023-05-29 10:03 ` [Bug middle-end/96564] [11/12/13/14 " jakub at gcc dot gnu.org
2024-03-10 22:49 ` law at gcc dot gnu.org
2024-03-11 10:23 ` rguenth at gcc dot gnu.org
2024-03-11 13:26 ` rguenth at gcc dot gnu.org
2024-03-11 15:20 ` amacleod at redhat dot com
2024-03-12  7:37 ` rguenth at gcc dot gnu.org

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