public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/107465] [10/11 Regression] Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
Date: Tue, 02 May 2023 20:15:32 +0000	[thread overview]
Message-ID: <bug-107465-4-R5Gy8QVkRu@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-107465-4@http.gcc.gnu.org/bugzilla/>

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)

  parent reply	other threads:[~2023-05-02 20:15 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-30 17:59 [Bug c/107465] New: " 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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-107465-4-R5Gy8QVkRu@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).