public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/59098] New: Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare]
@ 2013-11-13  1:37 jmattsson at dius dot com.au
  2013-11-13  3:09 ` [Bug c/59098] " manu at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: jmattsson at dius dot com.au @ 2013-11-13  1:37 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59098

            Bug ID: 59098
           Summary: Unwarranted warning: promoted ~unsigned is always
                    non-zero [-Wsign-compare]
           Product: gcc
           Version: 4.8.2
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jmattsson at dius dot com.au

Created attachment 31202
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31202&action=edit
Tiny test case for this issue

We recently switched to compiling existing warning-free code from IAR to gcc,
and are seeing "warning: promoted ~unsigned is always non-zero" for lines like
this:

  return (val ^ (small_type_t)0xfffffffful) == 0;

where "val" is of type "small_type_t" and "small_type_t" is typedef'd elsewhere
depending on the target platform/project to a uint8_t/uint16_t/uint32_t. The
code produced is correct, with or without optimization enabled.

Rewriting the code into two lines removes the warning:

  small_type_t mask = (small_type_t)0xfffffffful;
  return (val ^ mask) == 0;


As far as we can tell, the warning in the above is unwarranted and incorrect,
given that correct output is produced. It appears what the warning is really
trying to catch is this:

  return ~val == 0;

which due to promotion before the tilde application, does in fact end up always
non-zero and probably not what was intended/expected by the developer. Gcc
however also warns about

  return (small_type_t)~val == 0;

despite this producing the expected correct behavior.


We see this both on gcc 4.7.3 and 4.8.2 (and presumably others, but we haven't
tested).

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.8.2-1'
--with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.8 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls
--with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin
--with-system-zlib --disable-browser-plugin --enable-java-awt=gtk
--enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre
--enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.2 (Debian 4.8.2-1)

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.7.3-1ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs
--enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.7 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls
--with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin
--with-system-zlib --enable-objc-gc --with-cloog --enable-cloog-backend=ppl
--disable-cloog-version-check --disable-ppl-version-check --enable-multiarch
--disable-werror --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)


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

* [Bug c/59098] Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare]
  2013-11-13  1:37 [Bug c/59098] New: Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare] jmattsson at dius dot com.au
@ 2013-11-13  3:09 ` manu at gcc dot gnu.org
  2015-05-02  7:44 ` manu at gcc dot gnu.org
  2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: manu at gcc dot gnu.org @ 2013-11-13  3:09 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59098

Manuel López-Ibáñez <manu at gcc dot gnu.org> changed:

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

--- Comment #1 from Manuel López-Ibáñez <manu at gcc dot gnu.org> ---
Possibly related to bug 38341.

Note also that this simple change:

Index: c-common.c
===================================================================
--- c-common.c  (revision 204219)
+++ c-common.c  (working copy)
@@ -11236,11 +11236,11 @@ warn_for_sign_compare (location_t locati
             {
               mask = (~ (HOST_WIDE_INT) 0) << bits;
               if ((mask & constant) != mask)
                {
                  if (constant == 0)
-                   warning (OPT_Wsign_compare,
+                   warning_at (location, OPT_Wsign_compare,
                             "promoted ~unsigned is always non-zero");
                  else
                    warning_at (location, OPT_Wsign_compare,
                                "comparison of promoted ~unsigned with
constant");
                }


improves the caret information from:

small.c:6:3: warning: promoted ~unsigned is always non-zero [-Wsign-compare]
   return (val ^ (small_type_t)0xfffffffful) == 0;
   ^

to:

small.c:6:45: warning: promoted ~unsigned is always non-zero [-Wsign-compare]
   return (val ^ (small_type_t)0xfffffffful) != 0;
                                             ^
>From gcc-bugs-return-434405-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Wed Nov 13 04:31:01 2013
Return-Path: <gcc-bugs-return-434405-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 26638 invoked by alias); 13 Nov 2013 04:31:00 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 26618 invoked by uid 48); 13 Nov 2013 04:30:55 -0000
From: "regehr at cs dot utah.edu" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/59100] New: requesting optimization of safe rotate function
Date: Wed, 13 Nov 2013 04:31:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: c
X-Bugzilla-Version: 4.9.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: enhancement
X-Bugzilla-Who: regehr at cs dot utah.edu
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter
Message-ID: <bug-59100-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2013-11/txt/msg01182.txt.bz2
Content-length: 1658

http://gcc.gnu.org/bugzilla/show_bug.cgi?idY100

            Bug ID: 59100
           Summary: requesting optimization of safe rotate function
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: regehr at cs dot utah.edu

Here is the obvious rotate idiom in C (this code is from Nettle):

#define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))

GCC does an admirable job of recognizing the code and turning it into a rotate
instruction, when one is available.

The problem is that this code executes undefined behavior when n==0 or n=2.

Most crypto libraries are careful not to rotate by 32, but out of 10 libraries
that I examined, 5 execute undefined behavior when rotating by zero.

We can make the obvious modification to protect against undefined rotate by 0:

#define ROTL32(n,x) ((n)==0?(x):(((x)<<(n)) | ((x)>>(32-(n)))))

Notice that this can be turned into exactly the same object code as the earlier
macro since the rotate-by-0 special case is already handled by the rotate
instruction.  However, this isn't what we get out of the compiler:

rotl32c:
    movl    %edi, %eax
    movb    %sil, %cl
    roll    %cl, %eax
    testl    %esi, %esi
    cmove    %edi, %eax
    ret

I'm in the process of trying to convince crypto library maintainers to fix
their rotate functions and macros, and this will be easier if the fix doesn't
have a performance penalty.

So would it be possible for you folks to teach the compiler to emit the better
code for the safe rotate idiom?


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

* [Bug c/59098] Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare]
  2013-11-13  1:37 [Bug c/59098] New: Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare] jmattsson at dius dot com.au
  2013-11-13  3:09 ` [Bug c/59098] " manu at gcc dot gnu.org
@ 2015-05-02  7:44 ` manu at gcc dot gnu.org
  2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: manu at gcc dot gnu.org @ 2015-05-02  7:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Manuel López-Ibáñez <manu at gcc dot gnu.org> ---
(In reply to fenugrec from comment #3)
> Probable duplicate of Bug 38341

I don't think so. The problem here is not only whether the warning is correct
or not. A major issue is that the original code does not contain ~unsigned, but
GCC transforms (folds) the code too early. It is also unclear whether the code
paths that lead to this are the same. Two things may cause exactly the same
wrong warning but may be unrelated, or cause two different warnings, but have
the same root cause. Hard to say without running GCC under the debugger and
analyzing the execution (https://gcc.gnu.org/wiki/DebuggingGCC)
>From gcc-bugs-return-485226-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Sat May 02 07:46:30 2015
Return-Path: <gcc-bugs-return-485226-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 52151 invoked by alias); 2 May 2015 07:46:30 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 52116 invoked by uid 48); 2 May 2015 07:46:26 -0000
From: "rhalbersma at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/65977] New: Constexpr should be allowed in declaration of friend template specialization
Date: Sat, 02 May 2015 07:46:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: c++
X-Bugzilla-Version: 5.1.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: rhalbersma at gmail dot com
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Resolution:
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone
Message-ID: <bug-65977-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2015-05/txt/msg00066.txt.bz2
Content-length: 1834

https://gcc.gnu.org/bugzilla/show_bug.cgi?ide977

            Bug ID: 65977
           Summary: Constexpr should be allowed in declaration of friend
                    template specialization
           Product: gcc
           Version: 5.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rhalbersma at gmail dot com
  Target Milestone: ---

The following code comes from this StackOverflow Q&A (note this is not related
to std::bitset, it's just a homegrown class to experiment with constexpr):
http://stackoverflow.com/q/29871138/819272

#include <cstddef>

template<std::size_t>
class bitset;

template<std::size_t N>
constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept;

template<std::size_t N>
class bitset
{
    friend constexpr bool operator== <>(const bitset<N>&, const bitset<N>&)
noexcept;
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- error from this piece
};

template<std::size_t N>
constexpr bool operator==(const bitset<N>&, const bitset<N>&) noexcept
{
    return true;
}

int main() {}

The error I get with -std=c++11 on gcc 4.9.1 through gcc HEAD 6.0.0 20150501 is

'constexpr' is not allowed in declaration of friend template specialization

The same code on older gcc version (4.6 through 4.8) gives a slightly different
error

'inline' is not allowed in declaration of friend template specialization

which seems to have been introduced in 2013
https://gcc.gnu.org/ml/gcc-patches/2013-03/msg01028.html

Richard Smith's accepted answer on StackOverflow (
http://stackoverflow.com/a/29957648/819272 ) states that although constexpr
functions are implicitly inline, an inline function does not imply the inline
specifier. Therefore the above code should be valid.


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

* [Bug c/59098] Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare]
  2013-11-13  1:37 [Bug c/59098] New: Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare] jmattsson at dius dot com.au
  2013-11-13  3:09 ` [Bug c/59098] " manu at gcc dot gnu.org
  2015-05-02  7:44 ` manu at gcc dot gnu.org
@ 2023-05-20  4:33 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ 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=59098

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|NEW                         |RESOLVED

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Marking as a dup of bug 107465 as that is what fixed the issue here.

*** This bug has been marked as a duplicate of bug 107465 ***

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

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

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-13  1:37 [Bug c/59098] New: Unwarranted warning: promoted ~unsigned is always non-zero [-Wsign-compare] jmattsson at dius dot com.au
2013-11-13  3:09 ` [Bug c/59098] " manu at gcc dot gnu.org
2015-05-02  7:44 ` manu 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).