Compiler error: constexpr with bitfields.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
gcc-defaults |
Fix Released
|
Medium
|
|||
gcc-7 (Ubuntu) |
New
|
Undecided
|
Unassigned | ||
gcc-8 (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
GCC crashes when trying to compile the following program.
$> cat prog.cpp
struct Boolean {
bool is_true : 1;
constexpr explicit Boolean () : is_true(true) { }
constexpr explicit Boolean (bool init) : is_true(init) {
if (is_true != Boolean().is_true)
is_true = false;
}
};
int main() { Boolean x(false); }
$> g++ -O2 prog.cpp
prog.cpp: In function ‘int main()’:
prog.cpp:10:29: in constexpr expansion of ‘x.Boolean:
prog.cpp:10:29: internal compiler error: in cxx_eval_
int main() { Boolean x(false); }
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:/
Note that -O2 is required for reproducing the bug (otherwise, constexpr does not seem to be evaluated in the compile time). The program might seem a bit convoluted, but this is the minimum non-working example I was able to construct from a real-life scenario. The problem does not occur if line
bool is_true : 1;
is changed to
bool is_true;
-- Marcin.
ProblemType: Bug
DistroRelease: Ubuntu 18.04
Package: g++ 4:7.3.0-3ubuntu2
ProcVersionSign
Uname: Linux 4.15.0-33-generic x86_64
NonfreeKernelMo
ApportVersion: 2.20.9-0ubuntu7.2
Architecture: amd64
CurrentDesktop: GNOME
Date: Sat Sep 8 12:51:21 2018
InstallationDate: Installed on 2014-12-10 (1367 days ago)
InstallationMedia: Ubuntu 14.10 "Utopic Unicorn" - Release amd64 (20141022.1)
SourcePackage: gcc-defaults
UpgradeStatus: Upgraded to bionic on 2018-08-13 (26 days ago)
Changed in gcc-defaults: | |
importance: | Unknown → Medium |
status: | Unknown → Confirmed |
Changed in gcc-defaults: | |
status: | Confirmed → Fix Released |
Created attachment 44538
preprocessed file of a small test case for the constexpr crash
Hello,
I've created a small test case that produces a compiler crash. You can find attached the preprocessed file (main.ii) made by running the following command, with `G++ 7.3.1 20180303 (Red Hat 7.3.1-5)` on a CentOS 7 (with the devtoolset-7 installed), but it seems to exist on the last version too (see https:/ /wandbox. org/permlink/ zGZWdHIrRNJKfh5 Z):
g++ -O3 -Wall -Wextra -o main -save-temps -v main.cpp
I give at the end of the mail the output of the command.
You can find a run on the last G++ version (9) here: https:/ /wandbox. org/permlink/ zGZWdHIrRNJKfh5 Z
------- ------- ------- --
Here is the code:
#include <iostream> ------- ------- --
struct Bugged {
double x; bool isfreex; bool isfreey;
constexpr bool operator==(const Bugged& other) const noexcept {
return (x == other.x) && (isfreex == other.isfreex) && (isfreey == other.isfreey);
}
};
int main () {
std::cout << std::boolalpha << (Bugged{} == Bugged{}) << std::endl;
return 0;
}
-------
The bug only appears if I enable optimization (-02 or -O3), I guess constexpr optimization is not done otherwise.
The problem occurs on the operator==(). The compiler crashes because it can't compute the result of the constexpr. Note that if I change the struct so it doesn't hold booleans, but double instead, or if I remove any of the parentheses term in the operator== function, it doesn't crash.
Note that this code compiles on MSVC 2017 and on clang 6 (though it doesn't mean anything).
I search for a similar bug report but didn't find anything, sorry if this is a duplicate.
------- ------- ------- --
Below the output of the command:
Using built-in specs. LTO_WRAPPER= /opt/rh/ devtoolset- 7/root/ usr/libexec/ gcc/x86_ 64-redhat- linux/7/ lto-wrapper languages= c,c++,fortran, lto --prefix= /opt/rh/ devtoolset- 7/root/ usr --mandir= /opt/rh/ devtoolset- 7/root/ usr/share/ man --infodir= /opt/rh/ devtoolset- 7/root/ usr/share/ info --with-bugurl=http:// bugzilla. redhat. com/bugzilla --enable-shared --enable- threads= posix --enable- checking= release --enable-multilib --with-system-zlib --enable- __cxa_atexit --disable- libunwind- exceptions --enable- gnu-unique- object --enable- linker- build-id --with- gcc-major- version- only --enable-plugin --with- linker- hash-style= gnu --enable- initfini- array --with- default- libstdcxx- abi=gcc4- compatible --with- isl=/builddir/ build/BUILD/ gcc-7.3. 1-20180303/ obj-x86_ 64-redhat- linux/isl- install --enable-libmpx --enable- gnu-indirect- function --with-tune=generic --with-arch_32=i686 --build= x86_64- redhat- linux GCC_OPTIONS= '-O3' '-Wall' '-Wextra' '-o' 'main' '-save-temps' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' devtoolset- 7/root/ usr/libexec/ gcc/x86_ 64-redhat- linux/7/ cc1plus -E -quiet -v -D_GNU_SOURCE main.cpp -mtune=generic -march=x86-64 -Wall -Wextra -O3 -fpch-preprocess -o main.ii devtoolset- 7/root/ usr/lib/ gcc/x86_ 64-redhat- linux/7/ include- fixed"
COLLECT_GCC=g++
COLLECT_
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-
Thread model: posix
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
COLLECT_
/opt/rh/
ignoring nonexistent directory "/opt/rh/
i...