-
Enhancement
-
Resolution: Fixed
-
P4
-
15
-
None
-
b26
We should disable -Wshift-negative-value in gcc and clang builds. In C++98/03 the behavior is unmentioned. C++11 explicitly makes it undefined behavior and gcc -Wextra enables -Wshift-negative-value to produce warnings. C++20 permits shifts of negative values as part of specifying signed integers to behave as two's complement.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r3.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1236r1.html
We keep running afoul of these warnings and work around them in various ways, often with type changes that involve casts.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r4.html
points out that none of MSVC, gcc, or llvm support signed integer representations other than two's complement, and that no known modern machine uses both C++ and some representation other than two's complement.
From the gcc manual: 4.5 Integers
As an extension to the C language, GCC does not use the latitude given
in C99 and C11 only to treat certain aspects of signed ‘<<’ as
undefined. However, -fsanitize=shift (and -fsanitize=undefined) will
diagnose such cases. They are also diagnosed where constant
expressions are required.
Even ignoring any issues with backward compatibility, it would be very strange for gcc to change and treat left shift of negative values as UB now, given the coming soon C++20 explicitly permits it.
A question is whether that "diagnosed where constant expressions are required" causes constexpr failure, or only means warnings will be produced when enabled. Unfortunately, it appears that it does inhibit constexpr even if the -Wshift-negative-value warning is suppressed, at least for gcc in C++11 or later mode, though presumably only until C++20.
It's worth disabling the warning anyway, so we only need to deal with the problem in constexpr contexts.
It would be surprising if clang differed from gcc in this matter, though I've not found explicit documentation for that.
It would be surprising if MSVC did anything else either, though again I've not found explicit documentation. It does always use two's complement, but this doesn't mention left shift: https://docs.microsoft.com/en-us/cpp/c-language/integers?view=vs-2019 The fact that we have such code and have not run into problems with VS 2017+ is suggestive though.
So it seems we're not getting any benefit from these warnings, and just obfuscating code to avoid them.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r3.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1236r1.html
We keep running afoul of these warnings and work around them in various ways, often with type changes that involve casts.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r4.html
points out that none of MSVC, gcc, or llvm support signed integer representations other than two's complement, and that no known modern machine uses both C++ and some representation other than two's complement.
From the gcc manual: 4.5 Integers
As an extension to the C language, GCC does not use the latitude given
in C99 and C11 only to treat certain aspects of signed ‘<<’ as
undefined. However, -fsanitize=shift (and -fsanitize=undefined) will
diagnose such cases. They are also diagnosed where constant
expressions are required.
Even ignoring any issues with backward compatibility, it would be very strange for gcc to change and treat left shift of negative values as UB now, given the coming soon C++20 explicitly permits it.
A question is whether that "diagnosed where constant expressions are required" causes constexpr failure, or only means warnings will be produced when enabled. Unfortunately, it appears that it does inhibit constexpr even if the -Wshift-negative-value warning is suppressed, at least for gcc in C++11 or later mode, though presumably only until C++20.
It's worth disabling the warning anyway, so we only need to deal with the problem in constexpr contexts.
It would be surprising if clang differed from gcc in this matter, though I've not found explicit documentation for that.
It would be surprising if MSVC did anything else either, though again I've not found explicit documentation. It does always use two's complement, but this doesn't mention left shift: https://docs.microsoft.com/en-us/cpp/c-language/integers?view=vs-2019 The fact that we have such code and have not run into problems with VS 2017+ is suggestive though.
So it seems we're not getting any benefit from these warnings, and just obfuscating code to avoid them.
- blocks
-
JDK-8208089 JEP 347: Enable C++14 Language Features
- Closed
- relates to
-
JDK-8233144 undefined behavior: signed integer overflow
- Open
-
JDK-8300069 Left shift of negative value in share/adlc/dict2.cpp
- Resolved
-
JDK-8300797 UB: Left shift of negative value -1
- Closed