public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
@ 2022-10-30 17:59 lavr at ncbi dot nlm.nih.gov
  2022-10-31  1:51 ` [Bug c/107465] " pinskia at gcc dot gnu.org
                   ` (22 more replies)
  0 siblings, 23 replies; 24+ messages in thread
From: lavr at ncbi dot nlm.nih.gov @ 2022-10-30 17:59 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107465
           Summary: Bogus warning: promoted bitwise complement of an
                    unsigned value is always nonzero
           Product: gcc
           Version: 11.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lavr at ncbi dot nlm.nih.gov
  Target Milestone: ---

Tried on both Ubuntu and Cygwin, the same gcc-11.3.0 -- and the same problem:

$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc --version
gcc (GCC) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The code:
$ cat test.c
extern void fun2(void);

#ifdef BOGUS_WARNING
typedef unsigned short uint2;
#else
#define uint2 unsigned short
#endif

static void fun(uint2 x)
{
    if (!(x ^ 0xFFFF))
        fun2();
}


int main(void)
{
    fun(0);
}


The compilation:
$ gcc -Wall -Wextra -O6 -c test.c
(clean)

BUT:
$ gcc -Wall -Wextra -O6 -c -DBOGUS_WARNING test.c
test.c: In function ‘fun’:
test.c:11:9: warning: promoted bitwise complement of an unsigned value is
always nonzero [-Wsign-compare]
   11 |     if (!(x ^ 0xFFFF))
      |         ^

The variable "x" is an unsigned short, so it gets promoted to int without the
sign extension; the second argument to XOR is a 32-bit int with only 16 bits
set to 1.  The result of XOR is not necessarily non-0 because it does not flip
all the bits in an int, but only the lower 16 (so there's no promotion of any
sort, IMO).  Also, it's weird that the warning is only issued with a typedef
for the type of "x".

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

* [Bug c/107465] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
@ 2022-10-31  1:51 ` pinskia at gcc dot gnu.org
  2022-10-31  1:59 ` [Bug c/107465] [10/11/12/13 Regression] " pinskia at gcc dot gnu.org
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-31  1:51 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |11.3.0, 12.1.0, 6.1.0,
                   |                            |8.1.0

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The diagnostic changed between GCC 9 and 10.
9:
promoted ~unsigned is always non-zero
10:
promoted bitwise complement of an unsigned value is always nonzero

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
  2022-10-31  1:51 ` [Bug c/107465] " pinskia at gcc dot gnu.org
@ 2022-10-31  1:59 ` pinskia at gcc dot gnu.org
  2022-10-31  2:03 ` pinskia at gcc dot gnu.org
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-31  1:59 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |10.5
      Known to work|                            |4.1.2
            Summary|Bogus warning: promoted     |[10/11/12/13 Regression]
                   |bitwise complement of an    |Bogus warning: promoted
                   |unsigned value is always    |bitwise complement of an
                   |nonzero                     |unsigned value is always
                   |                            |nonzero
     Ever confirmed|0                           |1
      Known to fail|                            |4.4.7, 4.8.1
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=8715
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2022-10-31

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>Also, it's weird that the warning is only issued with a typedef for the type of "x".

My bet there is some IR difference (inside GCC) which is causing an extra
NOP_EXPR (a cast) being added due to the typedef and "unsigned short" are not
represented the same internally for diagnostic reasons.


Confirmed.

r0-88988-g2d12797c692346 (PR 8715) introduced the warning in GCC 4.4.0 which
seems to point to that is what is causing the bogus warning to show up.

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
  2022-10-31  1:51 ` [Bug c/107465] " pinskia at gcc dot gnu.org
  2022-10-31  1:59 ` [Bug c/107465] [10/11/12/13 Regression] " pinskia at gcc dot gnu.org
@ 2022-10-31  2:03 ` pinskia at gcc dot gnu.org
  2022-10-31  2:03 ` pinskia at gcc dot gnu.org
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-31  2:03 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I have not tested this at all but I suspect this patch will fix the issue:
apinski@xeond:~/src/upstream-gcc/gcc/gcc/c-family$ git diff c-warn.cc
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index 6742f447ff5..44d16111370 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -2302,8 +2302,8 @@ warn_for_sign_compare (location_t location,
       sop = fold_for_warn (sop);
       uop = fold_for_warn (uop);

-      STRIP_TYPE_NOPS (sop);
-      STRIP_TYPE_NOPS (uop);
+      STRIP_SIGN_NOPS (sop);
+      STRIP_SIGN_NOPS (uop);
       base_type = (TREE_CODE (result_type) == COMPLEX_TYPE
                   ? TREE_TYPE (result_type) : result_type);


------ CUT ----
And if it does, then I was right on the reason why typedef vs using unsigned
short directly too.

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (2 preceding siblings ...)
  2022-10-31  2:03 ` pinskia at gcc dot gnu.org
@ 2022-10-31  2:03 ` pinskia at gcc dot gnu.org
  2022-11-05 10:25 ` rguenth at gcc dot gnu.org
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-10-31  2:03 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #3)
> I have not tested this at all but I suspect this patch will fix the issue:
Oh I don't have time to submit this patch either. But maybe someone else could
do it.

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (3 preceding siblings ...)
  2022-10-31  2:03 ` pinskia at gcc dot gnu.org
@ 2022-11-05 10:25 ` rguenth at gcc dot gnu.org
  2022-11-21 14:32 ` jakub at gcc dot gnu.org
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-11-05 10:25 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (4 preceding siblings ...)
  2022-11-05 10:25 ` rguenth at gcc dot gnu.org
@ 2022-11-21 14:32 ` jakub at gcc dot gnu.org
  2022-11-21 14:51 ` jakub at gcc dot gnu.org
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-11-21 14:32 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #3)
> --- a/gcc/c-family/c-warn.cc
> +++ b/gcc/c-family/c-warn.cc
> @@ -2302,8 +2302,8 @@ warn_for_sign_compare (location_t location,
>        sop = fold_for_warn (sop);
>        uop = fold_for_warn (uop);
> 
> -      STRIP_TYPE_NOPS (sop);
> -      STRIP_TYPE_NOPS (uop);
> +      STRIP_SIGN_NOPS (sop);
> +      STRIP_SIGN_NOPS (uop);
>        base_type = (TREE_CODE (result_type) == COMPLEX_TYPE
>                    ? TREE_TYPE (result_type) : result_type);
> 
> 

No, this has nothing to do with it.
The problem is purely in incorrect use of get_narrower/c_common_get_narrower.
  op0 = c_common_get_narrower (op0, &unsignedp0);
  op1 = c_common_get_narrower (op1, &unsignedp1);

  if ((TREE_CODE (op0) == BIT_NOT_EXPR)
      ^ (TREE_CODE (op1) == BIT_NOT_EXPR))
    {
      if (TREE_CODE (op0) == BIT_NOT_EXPR)
        op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
      if (TREE_CODE (op1) == BIT_NOT_EXPR)
        op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
What get_narrower/c_common_get_narrower store into the integer pointed by the
second argument doesn't mean anything at all if the function doesn't return
something narrower, it is purely about whether if there needs to be some
extension from what {,c_common_}get_narrower returns to what has been passed to
it as the first argument needs to be a sign or zero extension.
E.g. shorten_binary_op does it get right and uses:
  arg0 = c_common_get_narrower (op0, &unsigned0);
  arg1 = c_common_get_narrower (op1, &unsigned1);

  /* UNS is 1 if the operation to be done is an unsigned one.  */
  uns = TYPE_UNSIGNED (result_type);

  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
     but it *requires* conversion to FINAL_TYPE.  */

  if ((TYPE_PRECISION (TREE_TYPE (op0))
       == TYPE_PRECISION (TREE_TYPE (arg0)))
      && TREE_TYPE (op0) != result_type)
    unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
  if ((TYPE_PRECISION (TREE_TYPE (op1))
       == TYPE_PRECISION (TREE_TYPE (arg1)))
      && TREE_TYPE (op1) != result_type)
    unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
I guess for the first pair of c_common_get_narrower we can do something
similar.
The problem is that there is another pair of them.
For those one can surely do that as well, but there is a further problem.
If the precision changes in both the c_common_get_narrower (op{0,1},
&unsignedp{0,1}) and c_common_get_narrower (TREE_OPERAND (op{0,1}, 0),
&unsignedp{0,1}) calls, we need to take into account also what actually
it means.

Note, this has been introduced already in
r0-9641-g64c01f8071113aff84414204e9d63cff3701bfb7
And, the bits < HOST_BITS_PER_LONG && part made sense in 1995 when it was using
long, but it doesn't make any sense to me now (we check tree_fits_shwi_p and
that verifies it fits into HOST_WIDE_INT).

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (5 preceding siblings ...)
  2022-11-21 14:32 ` jakub at gcc dot gnu.org
@ 2022-11-21 14:51 ` jakub at gcc dot gnu.org
  2022-11-21 15:28 ` jakub at gcc dot gnu.org
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-11-21 14:51 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I bet the warning also doesn't make really sense for the case where we'd have
unfolded BIT_NOT_EXPR of a constant compared to non-constant, so which of the
operands is BIT_NOT_EXPR should determine which operand to check
tree_fits_shwi_p on (the other one).

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (6 preceding siblings ...)
  2022-11-21 14:51 ` jakub at gcc dot gnu.org
@ 2022-11-21 15:28 ` jakub at gcc dot gnu.org
  2022-11-21 19:22 ` jakub at gcc dot gnu.org
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-11-21 15:28 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Untested fix, just know it fixes the testcase.
But I need to see what changes does it cause in the C/C++ testsuites and
probably write more extensive testsuite coverage.
--- gcc/c/c-warn.cc.jj  2022-10-28 11:00:53.738247032 +0200
+++ gcc/c/c-warn.cc     2022-11-21 16:27:13.997773107 +0100
@@ -2344,42 +2344,40 @@ warn_for_sign_compare (location_t locati
      have all bits set that are set in the ~ operand when it is
      extended.  */

-  op0 = c_common_get_narrower (op0, &unsignedp0);
-  op1 = c_common_get_narrower (op1, &unsignedp1);
+  tree arg0 = c_common_get_narrower (op0, &unsignedp0);
+  if (TYPE_PRECISION (TREE_TYPE (arg0)) == TYPE_PRECISION (TREE_TYPE (op0)))
+    unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (op0));
+  op0 = arg0;
+  tree arg1 = c_common_get_narrower (op1, &unsignedp1);
+  if (TYPE_PRECISION (TREE_TYPE (arg1)) == TYPE_PRECISION (TREE_TYPE (op1)))
+    unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (op1));
+  op1 = arg1;

   if ((TREE_CODE (op0) == BIT_NOT_EXPR)
       ^ (TREE_CODE (op1) == BIT_NOT_EXPR))
     {
-      if (TREE_CODE (op0) == BIT_NOT_EXPR)
-       op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0);
       if (TREE_CODE (op1) == BIT_NOT_EXPR)
-       op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1);
-
-      if (tree_fits_shwi_p (op0) || tree_fits_shwi_p (op1))
        {
-         tree primop;
-         HOST_WIDE_INT constant, mask;
-         int unsignedp;
-         unsigned int bits;
+         std::swap (op0, op1);
+         std::swap (unsignedp0, unsignedp1);
+       }

-         if (tree_fits_shwi_p (op0))
-           {
-             primop = op1;
-             unsignedp = unsignedp1;
-             constant = tree_to_shwi (op0);
-           }
-         else
-           {
-             primop = op0;
-             unsignedp = unsignedp0;
-             constant = tree_to_shwi (op1);
-           }
+      int unsignedp;
+      arg0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp);

-         bits = TYPE_PRECISION (TREE_TYPE (primop));
-         if (bits < TYPE_PRECISION (result_type)
-             && bits < HOST_BITS_PER_LONG && unsignedp)
+      /* For these warnings, we need BIT_NOT_EXPR operand to be
+        zero extended from narrower type to BIT_NOT_EXPR's type.
+        In that case, all those bits above the narrower's type
+        are after BIT_NOT_EXPR set to 1.  */
+      if (tree_fits_shwi_p (op1))
+       {
+         HOST_WIDE_INT constant = tree_to_shwi (op1);
+         unsigned int bits = TYPE_PRECISION (TREE_TYPE (arg0));
+         if (unsignedp
+             && bits < TYPE_PRECISION (TREE_TYPE (op0))
+             && bits < HOST_BITS_PER_WIDE_INT)
            {
-             mask = HOST_WIDE_INT_M1U << bits;
+             HOST_WIDE_INT mask = HOST_WIDE_INT_M1U << bits;
              if ((mask & constant) != mask)
                {
                  if (constant == 0)
@@ -2393,11 +2391,28 @@ warn_for_sign_compare (location_t locati
                }
            }
        }
-      else if (unsignedp0 && unsignedp1
-              && (TYPE_PRECISION (TREE_TYPE (op0))
-                  < TYPE_PRECISION (result_type))
+      else if ((TYPE_PRECISION (TREE_TYPE (arg0))
+               < TYPE_PRECISION (TREE_TYPE (op0)))
+              && unsignedp
+              && unsignedp1
+              /* If unsignedp0, the BIT_NOT_EXPR result is
+                 zero extended, so say if op0 is unsigned char
+                 variable, BIT_NOT_EXPR is unsigned short and
+                 result type int and op0 has value 0x55, the
+                 int value will be 0xffaa, or for op0 0xaa it
+                 will be 0xff55.  In these cases, warn if
+                 op1 is unsigned and narrower than unsigned short.
+                 While if unsignedp0 is false, the BIT_NOT_EXPR
+                 result is sign extended and because of the
+                 above TYPE_PRECISION comparison we know the
+                 MSB of BIT_NOT_EXPR is set (perhaps with some
+                 further bits below it).  The sign extension will
+                 then ensure all bits above BIT_NOT_EXPR up to
+                 result_type's precision are set.  */
               && (TYPE_PRECISION (TREE_TYPE (op1))
-                  < TYPE_PRECISION (result_type)))
+                  < TYPE_PRECISION (unsignedp0
+                                    ? TREE_TYPE (op0)
+                                    : result_type)))
        warning_at (location, OPT_Wsign_compare,
                    "comparison of promoted bitwise complement "
                    "of an unsigned value with unsigned");

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (7 preceding siblings ...)
  2022-11-21 15:28 ` jakub at gcc dot gnu.org
@ 2022-11-21 19:22 ` jakub at gcc dot gnu.org
  2023-03-04  9:19 ` cvs-commit at gcc dot gnu.org
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-11-21 19:22 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 53937
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53937&action=edit
gcc13-pr107465.patch

Full patch, so far just lightly tested.

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (8 preceding siblings ...)
  2022-11-21 19:22 ` jakub at gcc dot gnu.org
@ 2023-03-04  9:19 ` cvs-commit at gcc dot gnu.org
  2023-03-04  9:22 ` cvs-commit at gcc dot gnu.org
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-03-04  9:19 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:daaf74a714c41c8dbaf9954bcc58462c63062b4f

commit r13-6475-gdaaf74a714c41c8dbaf9954bcc58462c63062b4f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:18:37 2023 +0100

    c-family: Fix up -Wsign-compare BIT_NOT_EXPR handling [PR107465]

    The following patch fixes multiple bugs in warn_for_sign_compare related to
    the BIT_NOT_EXPR related warnings.
    My understanding is that what those 3 warnings are meant to warn (since
1995
    apparently) is the case where we have BIT_NOT_EXPR of a zero-extended
    value, so in result_type the value is something like:
    0b11111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension)
    0b000000000000000011111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then zero extended to 32 bits)
    0b111111111111111111111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then sign extended to 32 bits)
    and the intention of the warning is to warn when this is compared against
    something that has some 0 bits at the place where the above has guaranteed
    1 bits, either ensured through comparison against constant where we know
    the bits exactly, or through zero extension from some narrower type where
    again we know at least some upper bits are zero extended.
    The bugs in the warning code are:
    1) misunderstanding of the {,c_common_}get_narrower APIs - the unsignedp
       it sets is only meaningful if the function actually returns something
       narrower (in that case it says whether the narrower value is then
       sign (0) or zero (1) extended to the originally passed value.
       Though op0 or op1 at this point might be already narrower than
       result_type, and if the function doesn't return anything narrower,
       it all depends on whether the passed in op{0,1} had TYPE_UNSIGNED
       type or not
    2) the code didn't check at all whether the BIT_NOT_EXPR operand
       was actually zero extended (i.e. that it was narrower and unsignedp
       was set to 1 for it), all it did is check that unsignedp from the
       call was 1.  But that isn't well defined thing, if the argument
       is returned as is, the function sets unsignedp to 0, but if there
       is e.g. a useless cast to the same or compatible type in between,
       it can return 1 if the cast is unsigned; now, if BIT_NOT_EXPR
       operand is not zero extended, we know nothing at all about any bits
       in the operand containing BIT_NOT_EXPR, so there is nothing to warn
       about
    3) the code was actually testing both operands after calling
       c_common_get_narrower on them and on the one with BIT_NOT_EXPR
       again for constants; I think that is just wrong in case the BIT_NOT_EXPR
       operand wouldn't be fully folded, the warning makes sense only if the
       other operand not having BIT_NOT_EXPR in it is constant
    4) as can be seen from the above bit pattern examples, the upper bits above
       (in the patch arg0) aren't always all 1s, there could be some zero
extension
       above it and from it one would have 0s, so that needs to be taken into
       account for the choice which constant bits to test for being always set
       otherwise warning is emitted, or for the zero extension guaranteed zero
       bits
    5) the patch also simplifies the handling, we only do it if one but not
       both operands are BIT_NOT_EXPR after first {,c_common_}get_narrower,
       so we can just use std::swap to ensure it is the first one
    6) the code compared bits against HOST_BITS_PER_LONG, which made sense
       back in 1995 when the values were stored into long, but now that they
       are HOST_WIDE_INT should test HOST_BITS_PER_WIDE_INT (or we could
rewrite
       the stuff to wide_int, not done in the patch)

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.cc (warn_for_sign_compare): If c_common_get_narrower
            doesn't return a narrower result, use TYPE_UNSIGNED to set
unsignedp0
            and unsignedp1.  For the one BIT_NOT_EXPR case vs. one without,
            only check for constant in the non-BIT_NOT_EXPR operand, use
std::swap
            to simplify the code, only warn if BIT_NOT_EXPR operand is extended
            from narrower unsigned, fix up computation of mask for the constant
            cases and for unsigned other operand case handle differently
            BIT_NOT_EXPR result being sign vs. zero extended.

            * c-c++-common/Wsign-compare-2.c: New test.
            * c-c++-common/pr107465.c: New test.

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

* [Bug c/107465] [10/11/12/13 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (9 preceding siblings ...)
  2023-03-04  9:19 ` cvs-commit at gcc dot gnu.org
@ 2023-03-04  9:22 ` cvs-commit at gcc dot gnu.org
  2023-03-04  9:25 ` [Bug c/107465] [10/11/12 " jakub at gcc dot gnu.org
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-03-04  9:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:3ec9a8728086ad86a2d421e067329f305f40e005

commit r13-6476-g3ec9a8728086ad86a2d421e067329f305f40e005
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:21:45 2023 +0100

    c-family: Incremental fix for -Wsign-compare BIT_NOT_EXPR handling
[PR107465]

    There can be too many extensions and seems I didn't get everything right in
    the previously posted patch.

    The following incremental patch ought to fix that.
    The code can deal with quite a few sign/zero extensions at various spots
    and it is important to deal with all of them right.
    On the argument that contains BIT_NOT_EXPR we have:
    MSB bits#4 bits#3 BIT_NOT_EXPR bits#2 bits#1 LSB
    where bits#1 is one or more bits (TYPE_PRECISION (TREE_TYPE (arg0))
    at the end of the function) we don't know anything about, for the purposes
    of this warning it is VARYING that is inverted with BIT_NOT_EXPR to some
other
    VARYING bits;
    bits#2 is one or more bits (TYPE_PRECISION (TREE_TYPE (op0)) -
    TYPE_PRECISION (TREE_TYPE (arg0)) at the end of the function)
    which are known to be 0 before the BIT_NOT_EXPR and 1 after it.
    bits#3 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the end of function to the TYPE_PRECISION (TREE_TYPE (op0)) at the
    end of the function to TYPE_PRECISION (TREE_TYPE (op0)) at the start
    of the function, which are either zero extension or sign extension.
    And bits#4 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the start of the function to TYPE_PRECISION (result_type), which
    again can be zero or sign extension.

    Now, vanilla trunk as well as the previously posted patch mishandles the
    case where bits#3 are sign extended (as bits#2 are known to be all set,
    that means bits#3 are all set too) but bits#4 are zero extended and are
    thus all 0.

    The patch fixes it by tracking the lowest bit which is known to be clear
    above the known to be set bits (if any, otherwise it is precision of
    result_type).

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.cc (warn_for_sign_compare): Don't warn for unset bits
            above innermost zero extension of BIT_NOT_EXPR result.

            * c-c++-common/Wsign-compare-2.c (f18): New test.

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

* [Bug c/107465] [10/11/12 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (10 preceding siblings ...)
  2023-03-04  9:22 ` cvs-commit at gcc dot gnu.org
@ 2023-03-04  9:25 ` jakub at gcc dot gnu.org
  2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-04  9:25 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[10/11/12/13 Regression]    |[10/11/12 Regression] Bogus
                   |Bogus warning: promoted     |warning: promoted bitwise
                   |bitwise complement of an    |complement of an unsigned
                   |unsigned value is always    |value is always nonzero
                   |nonzero                     |

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed on the trunk so far.

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

* [Bug c/107465] [10/11/12 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (11 preceding siblings ...)
  2023-03-04  9:25 ` [Bug c/107465] [10/11/12 " jakub at gcc dot gnu.org
@ 2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
  2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-03-19  5:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #12 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-12 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:13d4c6e52003e7451f6e8bab4fd0a292089fbee2

commit r12-9285-g13d4c6e52003e7451f6e8bab4fd0a292089fbee2
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:18:37 2023 +0100

    c-family: Fix up -Wsign-compare BIT_NOT_EXPR handling [PR107465]

    The following patch fixes multiple bugs in warn_for_sign_compare related to
    the BIT_NOT_EXPR related warnings.
    My understanding is that what those 3 warnings are meant to warn (since
1995
    apparently) is the case where we have BIT_NOT_EXPR of a zero-extended
    value, so in result_type the value is something like:
    0b11111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension)
    0b000000000000000011111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then zero extended to 32 bits)
    0b111111111111111111111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then sign extended to 32 bits)
    and the intention of the warning is to warn when this is compared against
    something that has some 0 bits at the place where the above has guaranteed
    1 bits, either ensured through comparison against constant where we know
    the bits exactly, or through zero extension from some narrower type where
    again we know at least some upper bits are zero extended.
    The bugs in the warning code are:
    1) misunderstanding of the {,c_common_}get_narrower APIs - the unsignedp
       it sets is only meaningful if the function actually returns something
       narrower (in that case it says whether the narrower value is then
       sign (0) or zero (1) extended to the originally passed value.
       Though op0 or op1 at this point might be already narrower than
       result_type, and if the function doesn't return anything narrower,
       it all depends on whether the passed in op{0,1} had TYPE_UNSIGNED
       type or not
    2) the code didn't check at all whether the BIT_NOT_EXPR operand
       was actually zero extended (i.e. that it was narrower and unsignedp
       was set to 1 for it), all it did is check that unsignedp from the
       call was 1.  But that isn't well defined thing, if the argument
       is returned as is, the function sets unsignedp to 0, but if there
       is e.g. a useless cast to the same or compatible type in between,
       it can return 1 if the cast is unsigned; now, if BIT_NOT_EXPR
       operand is not zero extended, we know nothing at all about any bits
       in the operand containing BIT_NOT_EXPR, so there is nothing to warn
       about
    3) the code was actually testing both operands after calling
       c_common_get_narrower on them and on the one with BIT_NOT_EXPR
       again for constants; I think that is just wrong in case the BIT_NOT_EXPR
       operand wouldn't be fully folded, the warning makes sense only if the
       other operand not having BIT_NOT_EXPR in it is constant
    4) as can be seen from the above bit pattern examples, the upper bits above
       (in the patch arg0) aren't always all 1s, there could be some zero
extension
       above it and from it one would have 0s, so that needs to be taken into
       account for the choice which constant bits to test for being always set
       otherwise warning is emitted, or for the zero extension guaranteed zero
       bits
    5) the patch also simplifies the handling, we only do it if one but not
       both operands are BIT_NOT_EXPR after first {,c_common_}get_narrower,
       so we can just use std::swap to ensure it is the first one
    6) the code compared bits against HOST_BITS_PER_LONG, which made sense
       back in 1995 when the values were stored into long, but now that they
       are HOST_WIDE_INT should test HOST_BITS_PER_WIDE_INT (or we could
rewrite
       the stuff to wide_int, not done in the patch)

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.cc (warn_for_sign_compare): If c_common_get_narrower
            doesn't return a narrower result, use TYPE_UNSIGNED to set
unsignedp0
            and unsignedp1.  For the one BIT_NOT_EXPR case vs. one without,
            only check for constant in the non-BIT_NOT_EXPR operand, use
std::swap
            to simplify the code, only warn if BIT_NOT_EXPR operand is extended
            from narrower unsigned, fix up computation of mask for the constant
            cases and for unsigned other operand case handle differently
            BIT_NOT_EXPR result being sign vs. zero extended.

            * c-c++-common/Wsign-compare-2.c: New test.
            * c-c++-common/pr107465.c: New test.

    (cherry picked from commit daaf74a714c41c8dbaf9954bcc58462c63062b4f)

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

* [Bug c/107465] [10/11/12 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (12 preceding siblings ...)
  2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
@ 2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
  2023-03-20 10:28 ` [Bug c/107465] [10/11 " jakub at gcc dot gnu.org
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-03-19  5:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #13 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-12 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:93aafc14410388875313719a76b92812911a861a

commit r12-9286-g93aafc14410388875313719a76b92812911a861a
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:21:45 2023 +0100

    c-family: Incremental fix for -Wsign-compare BIT_NOT_EXPR handling
[PR107465]

    There can be too many extensions and seems I didn't get everything right in
    the previously posted patch.

    The following incremental patch ought to fix that.
    The code can deal with quite a few sign/zero extensions at various spots
    and it is important to deal with all of them right.
    On the argument that contains BIT_NOT_EXPR we have:
    MSB bits#4 bits#3 BIT_NOT_EXPR bits#2 bits#1 LSB
    where bits#1 is one or more bits (TYPE_PRECISION (TREE_TYPE (arg0))
    at the end of the function) we don't know anything about, for the purposes
    of this warning it is VARYING that is inverted with BIT_NOT_EXPR to some
other
    VARYING bits;
    bits#2 is one or more bits (TYPE_PRECISION (TREE_TYPE (op0)) -
    TYPE_PRECISION (TREE_TYPE (arg0)) at the end of the function)
    which are known to be 0 before the BIT_NOT_EXPR and 1 after it.
    bits#3 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the end of function to the TYPE_PRECISION (TREE_TYPE (op0)) at the
    end of the function to TYPE_PRECISION (TREE_TYPE (op0)) at the start
    of the function, which are either zero extension or sign extension.
    And bits#4 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the start of the function to TYPE_PRECISION (result_type), which
    again can be zero or sign extension.

    Now, vanilla trunk as well as the previously posted patch mishandles the
    case where bits#3 are sign extended (as bits#2 are known to be all set,
    that means bits#3 are all set too) but bits#4 are zero extended and are
    thus all 0.

    The patch fixes it by tracking the lowest bit which is known to be clear
    above the known to be set bits (if any, otherwise it is precision of
    result_type).

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.cc (warn_for_sign_compare): Don't warn for unset bits
            above innermost zero extension of BIT_NOT_EXPR result.

            * c-c++-common/Wsign-compare-2.c (f18): New test.

    (cherry picked from commit 3ec9a8728086ad86a2d421e067329f305f40e005)

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

* [Bug c/107465] [10/11 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (13 preceding siblings ...)
  2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
@ 2023-03-20 10:28 ` jakub at gcc dot gnu.org
  2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-03-20 10:28 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[10/11/12 Regression] Bogus |[10/11 Regression] Bogus
                   |warning: promoted bitwise   |warning: promoted bitwise
                   |complement of an unsigned   |complement of an unsigned
                   |value is always nonzero     |value is always nonzero

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed for 12.3 too.

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

* [Bug c/107465] [10/11 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (14 preceding siblings ...)
  2023-03-20 10:28 ` [Bug c/107465] [10/11 " jakub at gcc dot gnu.org
@ 2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
  2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-05-02 20:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #15 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:043793b1c11c51975d80454e99f0f3842e8ab2db

commit r11-10721-g043793b1c11c51975d80454e99f0f3842e8ab2db
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:18:37 2023 +0100

    c-family: Fix up -Wsign-compare BIT_NOT_EXPR handling [PR107465]

    The following patch fixes multiple bugs in warn_for_sign_compare related to
    the BIT_NOT_EXPR related warnings.
    My understanding is that what those 3 warnings are meant to warn (since
1995
    apparently) is the case where we have BIT_NOT_EXPR of a zero-extended
    value, so in result_type the value is something like:
    0b11111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension)
    0b000000000000000011111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then zero extended to 32 bits)
    0b111111111111111111111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then sign extended to 32 bits)
    and the intention of the warning is to warn when this is compared against
    something that has some 0 bits at the place where the above has guaranteed
    1 bits, either ensured through comparison against constant where we know
    the bits exactly, or through zero extension from some narrower type where
    again we know at least some upper bits are zero extended.
    The bugs in the warning code are:
    1) misunderstanding of the {,c_common_}get_narrower APIs - the unsignedp
       it sets is only meaningful if the function actually returns something
       narrower (in that case it says whether the narrower value is then
       sign (0) or zero (1) extended to the originally passed value.
       Though op0 or op1 at this point might be already narrower than
       result_type, and if the function doesn't return anything narrower,
       it all depends on whether the passed in op{0,1} had TYPE_UNSIGNED
       type or not
    2) the code didn't check at all whether the BIT_NOT_EXPR operand
       was actually zero extended (i.e. that it was narrower and unsignedp
       was set to 1 for it), all it did is check that unsignedp from the
       call was 1.  But that isn't well defined thing, if the argument
       is returned as is, the function sets unsignedp to 0, but if there
       is e.g. a useless cast to the same or compatible type in between,
       it can return 1 if the cast is unsigned; now, if BIT_NOT_EXPR
       operand is not zero extended, we know nothing at all about any bits
       in the operand containing BIT_NOT_EXPR, so there is nothing to warn
       about
    3) the code was actually testing both operands after calling
       c_common_get_narrower on them and on the one with BIT_NOT_EXPR
       again for constants; I think that is just wrong in case the BIT_NOT_EXPR
       operand wouldn't be fully folded, the warning makes sense only if the
       other operand not having BIT_NOT_EXPR in it is constant
    4) as can be seen from the above bit pattern examples, the upper bits above
       (in the patch arg0) aren't always all 1s, there could be some zero
extension
       above it and from it one would have 0s, so that needs to be taken into
       account for the choice which constant bits to test for being always set
       otherwise warning is emitted, or for the zero extension guaranteed zero
       bits
    5) the patch also simplifies the handling, we only do it if one but not
       both operands are BIT_NOT_EXPR after first {,c_common_}get_narrower,
       so we can just use std::swap to ensure it is the first one
    6) the code compared bits against HOST_BITS_PER_LONG, which made sense
       back in 1995 when the values were stored into long, but now that they
       are HOST_WIDE_INT should test HOST_BITS_PER_WIDE_INT (or we could
rewrite
       the stuff to wide_int, not done in the patch)

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.c (warn_for_sign_compare): If c_common_get_narrower
            doesn't return a narrower result, use TYPE_UNSIGNED to set
unsignedp0
            and unsignedp1.  For the one BIT_NOT_EXPR case vs. one without,
            only check for constant in the non-BIT_NOT_EXPR operand, use
std::swap
            to simplify the code, only warn if BIT_NOT_EXPR operand is extended
            from narrower unsigned, fix up computation of mask for the constant
            cases and for unsigned other operand case handle differently
            BIT_NOT_EXPR result being sign vs. zero extended.

            * c-c++-common/Wsign-compare-2.c: New test.
            * c-c++-common/pr107465.c: New test.

    (cherry picked from commit daaf74a714c41c8dbaf9954bcc58462c63062b4f)

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

* [Bug c/107465] [10/11 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (15 preceding siblings ...)
  2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
@ 2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
  2023-05-03  9:30 ` [Bug c/107465] [10 " jakub at gcc dot gnu.org
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-05-02 20:15 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #16 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:c61635e87903797b7e5b71683be93534290118e2

commit r11-10722-gc61635e87903797b7e5b71683be93534290118e2
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:21:45 2023 +0100

    c-family: Incremental fix for -Wsign-compare BIT_NOT_EXPR handling
[PR107465]

    There can be too many extensions and seems I didn't get everything right in
    the previously posted patch.

    The following incremental patch ought to fix that.
    The code can deal with quite a few sign/zero extensions at various spots
    and it is important to deal with all of them right.
    On the argument that contains BIT_NOT_EXPR we have:
    MSB bits#4 bits#3 BIT_NOT_EXPR bits#2 bits#1 LSB
    where bits#1 is one or more bits (TYPE_PRECISION (TREE_TYPE (arg0))
    at the end of the function) we don't know anything about, for the purposes
    of this warning it is VARYING that is inverted with BIT_NOT_EXPR to some
other
    VARYING bits;
    bits#2 is one or more bits (TYPE_PRECISION (TREE_TYPE (op0)) -
    TYPE_PRECISION (TREE_TYPE (arg0)) at the end of the function)
    which are known to be 0 before the BIT_NOT_EXPR and 1 after it.
    bits#3 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the end of function to the TYPE_PRECISION (TREE_TYPE (op0)) at the
    end of the function to TYPE_PRECISION (TREE_TYPE (op0)) at the start
    of the function, which are either zero extension or sign extension.
    And bits#4 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the start of the function to TYPE_PRECISION (result_type), which
    again can be zero or sign extension.

    Now, vanilla trunk as well as the previously posted patch mishandles the
    case where bits#3 are sign extended (as bits#2 are known to be all set,
    that means bits#3 are all set too) but bits#4 are zero extended and are
    thus all 0.

    The patch fixes it by tracking the lowest bit which is known to be clear
    above the known to be set bits (if any, otherwise it is precision of
    result_type).

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.c (warn_for_sign_compare): Don't warn for unset bits
            above innermost zero extension of BIT_NOT_EXPR result.

            * c-c++-common/Wsign-compare-2.c (f18): New test.

    (cherry picked from commit 3ec9a8728086ad86a2d421e067329f305f40e005)

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (16 preceding siblings ...)
  2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
@ 2023-05-03  9:30 ` jakub at gcc dot gnu.org
  2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-05-03  9:30 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[10/11 Regression] Bogus    |[10 Regression] Bogus
                   |warning: promoted bitwise   |warning: promoted bitwise
                   |complement of an unsigned   |complement of an unsigned
                   |value is always nonzero     |value is always nonzero

--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed for 11.4 as well.

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (17 preceding siblings ...)
  2023-05-03  9:30 ` [Bug c/107465] [10 " jakub at gcc dot gnu.org
@ 2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
  2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-05-03 15:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #18 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-10 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:e870422424310f7b5867e204360ec7094ba999c6

commit r10-11374-ge870422424310f7b5867e204360ec7094ba999c6
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:18:37 2023 +0100

    c-family: Fix up -Wsign-compare BIT_NOT_EXPR handling [PR107465]

    The following patch fixes multiple bugs in warn_for_sign_compare related to
    the BIT_NOT_EXPR related warnings.
    My understanding is that what those 3 warnings are meant to warn (since
1995
    apparently) is the case where we have BIT_NOT_EXPR of a zero-extended
    value, so in result_type the value is something like:
    0b11111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension)
    0b000000000000000011111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then zero extended to 32 bits)
    0b111111111111111111111111XXXXXXXX (e.g. ~ of a 8->16 bit zero extension
    then sign extended to 32 bits)
    and the intention of the warning is to warn when this is compared against
    something that has some 0 bits at the place where the above has guaranteed
    1 bits, either ensured through comparison against constant where we know
    the bits exactly, or through zero extension from some narrower type where
    again we know at least some upper bits are zero extended.
    The bugs in the warning code are:
    1) misunderstanding of the {,c_common_}get_narrower APIs - the unsignedp
       it sets is only meaningful if the function actually returns something
       narrower (in that case it says whether the narrower value is then
       sign (0) or zero (1) extended to the originally passed value.
       Though op0 or op1 at this point might be already narrower than
       result_type, and if the function doesn't return anything narrower,
       it all depends on whether the passed in op{0,1} had TYPE_UNSIGNED
       type or not
    2) the code didn't check at all whether the BIT_NOT_EXPR operand
       was actually zero extended (i.e. that it was narrower and unsignedp
       was set to 1 for it), all it did is check that unsignedp from the
       call was 1.  But that isn't well defined thing, if the argument
       is returned as is, the function sets unsignedp to 0, but if there
       is e.g. a useless cast to the same or compatible type in between,
       it can return 1 if the cast is unsigned; now, if BIT_NOT_EXPR
       operand is not zero extended, we know nothing at all about any bits
       in the operand containing BIT_NOT_EXPR, so there is nothing to warn
       about
    3) the code was actually testing both operands after calling
       c_common_get_narrower on them and on the one with BIT_NOT_EXPR
       again for constants; I think that is just wrong in case the BIT_NOT_EXPR
       operand wouldn't be fully folded, the warning makes sense only if the
       other operand not having BIT_NOT_EXPR in it is constant
    4) as can be seen from the above bit pattern examples, the upper bits above
       (in the patch arg0) aren't always all 1s, there could be some zero
extension
       above it and from it one would have 0s, so that needs to be taken into
       account for the choice which constant bits to test for being always set
       otherwise warning is emitted, or for the zero extension guaranteed zero
       bits
    5) the patch also simplifies the handling, we only do it if one but not
       both operands are BIT_NOT_EXPR after first {,c_common_}get_narrower,
       so we can just use std::swap to ensure it is the first one
    6) the code compared bits against HOST_BITS_PER_LONG, which made sense
       back in 1995 when the values were stored into long, but now that they
       are HOST_WIDE_INT should test HOST_BITS_PER_WIDE_INT (or we could
rewrite
       the stuff to wide_int, not done in the patch)

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.c (warn_for_sign_compare): If c_common_get_narrower
            doesn't return a narrower result, use TYPE_UNSIGNED to set
unsignedp0
            and unsignedp1.  For the one BIT_NOT_EXPR case vs. one without,
            only check for constant in the non-BIT_NOT_EXPR operand, use
std::swap
            to simplify the code, only warn if BIT_NOT_EXPR operand is extended
            from narrower unsigned, fix up computation of mask for the constant
            cases and for unsigned other operand case handle differently
            BIT_NOT_EXPR result being sign vs. zero extended.

            * c-c++-common/Wsign-compare-2.c: New test.
            * c-c++-common/pr107465.c: New test.

    (cherry picked from commit daaf74a714c41c8dbaf9954bcc58462c63062b4f)

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (18 preceding siblings ...)
  2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
@ 2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
  2023-05-04  7:21 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 24+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-05-03 15:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #19 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-10 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:42bbe4c068011e78f8cb264f56aaa4c392783326

commit r10-11375-g42bbe4c068011e78f8cb264f56aaa4c392783326
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Mar 4 10:21:45 2023 +0100

    c-family: Incremental fix for -Wsign-compare BIT_NOT_EXPR handling
[PR107465]

    There can be too many extensions and seems I didn't get everything right in
    the previously posted patch.

    The following incremental patch ought to fix that.
    The code can deal with quite a few sign/zero extensions at various spots
    and it is important to deal with all of them right.
    On the argument that contains BIT_NOT_EXPR we have:
    MSB bits#4 bits#3 BIT_NOT_EXPR bits#2 bits#1 LSB
    where bits#1 is one or more bits (TYPE_PRECISION (TREE_TYPE (arg0))
    at the end of the function) we don't know anything about, for the purposes
    of this warning it is VARYING that is inverted with BIT_NOT_EXPR to some
other
    VARYING bits;
    bits#2 is one or more bits (TYPE_PRECISION (TREE_TYPE (op0)) -
    TYPE_PRECISION (TREE_TYPE (arg0)) at the end of the function)
    which are known to be 0 before the BIT_NOT_EXPR and 1 after it.
    bits#3 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the end of function to the TYPE_PRECISION (TREE_TYPE (op0)) at the
    end of the function to TYPE_PRECISION (TREE_TYPE (op0)) at the start
    of the function, which are either zero extension or sign extension.
    And bits#4 is zero or more bits from the TYPE_PRECISION (TREE_TYPE (op0))
    at the start of the function to TYPE_PRECISION (result_type), which
    again can be zero or sign extension.

    Now, vanilla trunk as well as the previously posted patch mishandles the
    case where bits#3 are sign extended (as bits#2 are known to be all set,
    that means bits#3 are all set too) but bits#4 are zero extended and are
    thus all 0.

    The patch fixes it by tracking the lowest bit which is known to be clear
    above the known to be set bits (if any, otherwise it is precision of
    result_type).

    2023-03-04  Jakub Jelinek  <jakub@redhat.com>

            PR c/107465
            * c-warn.c (warn_for_sign_compare): Don't warn for unset bits
            above innermost zero extension of BIT_NOT_EXPR result.

            * c-c++-common/Wsign-compare-2.c (f18): New test.

    (cherry picked from commit 3ec9a8728086ad86a2d421e067329f305f40e005)

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (19 preceding siblings ...)
  2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
@ 2023-05-04  7:21 ` jakub at gcc dot gnu.org
  2023-05-20  4:26 ` pinskia at gcc dot gnu.org
  2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  22 siblings, 0 replies; 24+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-05-04  7:21 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed for 10.5 too.

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (20 preceding siblings ...)
  2023-05-04  7:21 ` jakub at gcc dot gnu.org
@ 2023-05-20  4:26 ` pinskia at gcc dot gnu.org
  2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-20  4:26 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fredrik.hederstierna@securi
                   |                            |tas-direct.com

--- Comment #21 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 38341 has been marked as a duplicate of this bug. ***

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

* [Bug c/107465] [10 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
  2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
                   ` (21 preceding siblings ...)
  2023-05-20  4:26 ` pinskia at gcc dot gnu.org
@ 2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  22 siblings, 0 replies; 24+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-20  4:33 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmattsson at dius dot com.au

--- Comment #22 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 59098 has been marked as a duplicate of this bug. ***

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

end of thread, other threads:[~2023-05-20  4:33 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-30 17:59 [Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero lavr at ncbi dot nlm.nih.gov
2022-10-31  1:51 ` [Bug c/107465] " pinskia at gcc dot gnu.org
2022-10-31  1:59 ` [Bug c/107465] [10/11/12/13 Regression] " pinskia at gcc dot gnu.org
2022-10-31  2:03 ` pinskia at gcc dot gnu.org
2022-10-31  2:03 ` pinskia at gcc dot gnu.org
2022-11-05 10:25 ` rguenth at gcc dot gnu.org
2022-11-21 14:32 ` jakub at gcc dot gnu.org
2022-11-21 14:51 ` jakub at gcc dot gnu.org
2022-11-21 15:28 ` jakub at gcc dot gnu.org
2022-11-21 19:22 ` jakub at gcc dot gnu.org
2023-03-04  9:19 ` cvs-commit at gcc dot gnu.org
2023-03-04  9:22 ` cvs-commit at gcc dot gnu.org
2023-03-04  9:25 ` [Bug c/107465] [10/11/12 " jakub at gcc dot gnu.org
2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
2023-03-19  5:30 ` cvs-commit at gcc dot gnu.org
2023-03-20 10:28 ` [Bug c/107465] [10/11 " jakub at gcc dot gnu.org
2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
2023-05-02 20:15 ` cvs-commit at gcc dot gnu.org
2023-05-03  9:30 ` [Bug c/107465] [10 " jakub at gcc dot gnu.org
2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
2023-05-03 15:22 ` cvs-commit at gcc dot gnu.org
2023-05-04  7:21 ` jakub at gcc dot gnu.org
2023-05-20  4:26 ` pinskia at gcc dot gnu.org
2023-05-20  4:33 ` pinskia 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).