[Bug c++/96241] New: ICE in verify_ctor_sanity
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96241 Bug ID: 96241 Summary: ICE in verify_ctor_sanity Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- The following generates internal compiler error: in verify_ctor_sanity, at cp/constexpr.c:3869 for gcc-10.1.0 (x86_64 and i686, Linux), gcc-9.x also ICEs. gcc-8.x and gcc-7.x are fine, so are clang and intel-compiler. enum struct enu : int { o = 0, p = 1, }; constexpr enu& operator|=(enu& a, enu b) { return a = enu(static_cast(a) + static_cast(b)); } struct s { enu e = enu::o; }; template struct my_array { T data[N]; }; static constexpr auto make_ss = []{ my_array ss = {}; //ss.data[0] = {}; //work-around to avoid ICE on next line ss.data[0].e |= enu::p; //ICE return ss; }();
[Bug c++/92332] New: invalid optimization in certain situations involving placement new on i686
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92332 Bug ID: 92332 Summary: invalid optimization in certain situations involving placement new on i686 Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- Created attachment 47157 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47157&action=edit minimal example showing problem See code below and attached (running ubuntu linux on intel). g++-9 -m64 compiles and runs fine, all optimization levels. g++-9 -m32 -O1 and below compile and run fine. g++-9 -m32 -O2 and above generate incorrect warning and incorrect code. g++-8 (8.3.0) behaves same as g++-9. #include #include #include using std::size_t; using std::uint32_t; using std::uint64_t; template struct myarray { T data[N]; }; myarray mul(uint32_t a, uint32_t b) noexcept { alignas(uint64_t) myarray ab; #if 1 //no bug for #if 0 ::new(&ab) uint64_t(uint64_t(a) * b); #else uint64_t const c = uint64_t(a) * b; ab.data[0] = uint32_t(c); ab.data[1] = uint32_t(c >> 32); #endif return ab; } struct bar : myarray { bar& operator+=(uint32_t a) noexcept { this->data[0] += a; //no bug when commented out this->data[1] += a; //no bug when commented out return *this; } }; struct foo : myarray { foo() noexcept { static_cast(*::new(this) myarray(mul(0xdeadbeef, 0xdeadbeef))) += 1; } }; int main() { foo f; std::printf("0x%x, 0x%x\n", f.data[0], f.data[1]); std::printf("0x%x, 0x%x\n", 0x216da322, 0xc1b1cd13); return 0; } /* $ g++-9 -m64 -Wall -O2 -o bug bug.cpp //OK $ g++-9 -m32 -Wall -O1 -o bug bug.cpp //Ok $ g++-9 -m32 -Wall -O2 -o bug bug.cpp bug.cpp: In function ‘int main()’: bug.cpp:24:23: warning: ‘f.bar::.myarray::data[0]’ is used uninitialized in this function [-Wuninitiali 24 | this->data[0] += a; //no bug when commented out | ~~^~~~ bug.cpp:35:9: note: ‘f.bar::.myarray::data[0]’ was declared here 35 | foo f; | ^ bug.cpp:25:23: warning: ‘f.bar::.myarray::data[1]’ is used uninitialized in this function [-Wuninitiali 25 | this->data[1] += a; //no bug when commented out | ~~^~~~ bug.cpp:35:9: note: ‘f.bar::.myarray::data[1]’ was declared here 35 | foo f; | ^ */
[Bug libstdc++/56862] New: std::complex constructor ambiguous overload
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56862 Bug #: 56862 Summary: std::complex constructor ambiguous overload Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: minor Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: cbc...@gmail.com #include struct number { number() {} operator std::complex() const { return 0; } operator int(); //OK if this line is commented out }; int main() { number const a; std::complex ca(a); //OK number b; std::complex cb(b); //error: call of overloaded 'complex(number&)' is ambiguous std::complex cc(number()); //OK return 0; } /* Ambiguous overload for all gcc versions I tried (4.5 to 4.8) on all platforms I tried (linux amd64, mingw32, cygwin). Not sure if the problem is in libstdc++'s or in g++. */
[Bug c/87139] New: 6.4 x86_64 incorrect code generation with -O3 around _addcarry_u64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87139 Bug ID: 87139 Summary: 6.4 x86_64 incorrect code generation with -O3 around _addcarry_u64 Product: gcc Version: 6.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- x86_64 gcc-6 (tested with 6.4.0 and 6.3.0 under linux and 6.4.0 under windows/mingw) generates incorrect code when optimizing with -O3 in certain situations around _addcarry_u64. gcc-6 with -O2 is fine. gcc-5, gcc-7 and gcc-8 with -O3 are all fine. It is difficult to pinpoint the exact problem but the following should narrow it down enough to be helpful. #include #include #include #include #include using std::size_t; using std::uint64_t; static_assert(sizeof(size_t) == sizeof(uint64_t), ""); //big-integer multiplication, limb-size is size_t is uint64_t template std::array big_mul(std::array const& aa, std::array const& bb) noexcept { static constexpr size_t const Nc = Na + Nb; std::array cc = {{0,}}; for (size_t na = 0; na != Na; ++na) { for (size_t nb = 0; nb != Nb; ++nb) { alignas(__uint128_t) size_t lohi[2]; reinterpret_cast<__uint128_t&>(lohi) = __uint128_t(aa[na]) * __uint128_t(bb[nb]); //Note: placement-new instead of reinterpret_cast makes no difference size_t n = na + nb; unsigned char c = __builtin_add_overflow(cc[n], lohi[0], &cc[n]); #if 1 //Note: x86_64-gcc-6 -O3 generates bad code; gcc-6 -O2 is fine; gcc-5 and gcc-7 and above are fine c = _addcarry_u64(c, cc[n + 1], lohi[1], &reinterpret_cast(cc[n + 1])); for (n += 2; n <= Nc - 1; ++n) c = __builtin_add_overflow(cc[n], c, &cc[n]); #elif 1 //Note: added 'c &&' in for-loop condition: problem goes away c = _addcarry_u64(c, cc[n + 1], lohi[1], &reinterpret_cast(cc[n + 1])); for (n += 2; c && n <= Nc - 1; ++n) c = __builtin_add_overflow(cc[n], c, &cc[n]); #else //Note: inserted '++n' between add_overflow and add_carry: problem goes away ++n; c = _addcarry_u64(c, cc[n], lohi[1], &reinterpret_cast(cc[n])); for (++n; c && n <= Nc - 1; ++n) c = __builtin_add_overflow(cc[n], c, &cc[n]); #endif } } return cc; } //simple random-number-generator, https://github.com/svaarala/duktape/blob/master/misc/splitmix64.c static uint64_t rnd_state = 1; static inline uint64_t rnd() { uint64_t z = rnd_state += 0x9e3779b97f4a7c15; z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; z = (z ^ (z >> 27)) * 0x94d049bb133111eb; return z ^ (z >> 31); } //main() writes python3-script; pipe into python3; no output means no error //g++-6 -std=c++11 -O3 -o test test.cpp && ./test 100 | python3 #bad //g++-6 -std=c++11 -O2 -o test test.cpp && ./test 100 | python3 #Ok //g++-5 -std=c++11 -O3 -o test test.cpp && ./test 100 | python3 #Ok //g++-7 -std=c++11 -O3 -o test test.cpp && ./test 100 | python3 #Ok //g++-8 -std=c++11 -O3 -o test test.cpp && ./test 100 | python3 #Ok int main(int argc, char const** argv) { assert(argc == 2); size_t const M = size_t(std::strtoull(argv[1], nullptr, 0)); static constexpr size_t const Na = 2, Nb = 2; //Note: any combination of Na>=2, Nb>=2 causes the problem std::array aa; std::array bb; std::array cc; for (size_t m = 0; m != M; ++m) { for (size_t& a: aa) a = rnd(); for (size_t& b: bb) b = rnd(); cc = big_mul(aa, bb); std::printf( "a=0x");for (size_t n = Na;n--;) std::printf("%016zx", aa[n]); std::printf("; b=0x");for (size_t n = Nb;n--;) std::printf("%016zx", bb[n]); std::printf("; c=0x");for (size_t n = Na+Nb; n--;) std::printf("%016zx", cc[n]); std::printf("\nif a*b!=c: print(hex(a),'*', hex(b),'\\n=',hex(a*b),'\\n?',hex(c))\n"); } return 0; }
[Bug target/87139] 6.4 x86_64 incorrect code generation with -O3 around _addcarry_u64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87139 cbcode at gmail dot com changed: What|Removed |Added CC||cbcode at gmail dot com --- Comment #2 from cbcode at gmail dot com --- Created attachment 44621 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44621&action=edit test reproducing the problem
[Bug target/87139] 6.4 x86_64 incorrect code generation with -O3 around _addcarry_u64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87139 --- Comment #3 from cbcode at gmail dot com --- -fno-strict-aliasing makes no difference.
[Bug target/87139] 6.4 x86_64 incorrect code generation with -O3 around _addcarry_u64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87139 --- Comment #5 from cbcode at gmail dot com --- (In reply to H.J. Lu from comment #4) > (In reply to cbcode from comment #2) > > Created attachment 44621 [details] > > test reproducing the problem > > How to show the problem? Save the attachment as test.cpp, compile, run and look at the output: g++ -std=c++11 -O3 -o test test.cpp && ./test 10 function bigmul() multiplies two arbitrary-precision integers, and main() generates a few random examples and format them as a python3-script, consisting of lines of the form: if a * b != expected: print a, b, expected, a * b To run the tests, do: g++ -std=c++11 -O3 -o test test.cpp && ./test 10 | python3 If the gcc version is not 6, or if the optimization level is below -O3, all checks will pass and there is no output. With the default g++ in amd64-debian-stable at the time of this writing (gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)) I get the following output: $ g++ -std=c++11 -O3 -o test test.cpp && ./test 10 | python3 0xbeeb8da1658eec67910a2dec89025cc1 * 0x71c18690ee42c90bf893a2eefb32555e = 0x54d64d7566d4996250f93066b9e161138d4d6f3a582b5c4f9f3bd72d705c23de ? 0x54d64d7566d4996250f93066b9e161128d4d6f3a582b5c4f9f3bd72d705c23de 0xc34d0bff9015028071bb54d8d101b5b9 * 0x85e7bb0f12278575e099ec6cd7363ca5 = 0x6627d0766096e0e087e772aabc35719b32092fcf64d348f16eb53cc1d0b77c3d ? 0x6627d0766096e0e087e772aabc35719a32092fcf64d348f16eb53cc1d0b77c3d 0xcb435c8e74616796491718de357e3da8 * 0x9afcd44d14cf8bfe6775dc7701564f61 = 0x7b0f448dcaac0546958108e31e6bff5afc779f31bc686ccf2bbb7e72984c34a8 ? 0x7b0f448dcaac0546958108e31e6bff59fc779f31bc686ccf2bbb7e72984c34a8 0x87b341d690d7a28a7476cf8a4baa5dc0 * 0x2ac2ce17a5794a3b6f9b6dae6f4c57a8 = 0x16aaabe3e0298b6b287985777faad3121c5e6216bd208bf75d540032a2a9c600 ? 0x16aaabe3e0298b6b287985777faad3111c5e6216bd208bf75d540032a2a9c600 0xd0bad0da572baaf1a534a6a6b7fd0b63 * 0xe263183773ef6508ae84379630af89ee = 0xb895b85e3fa2b67d1b3b3243d7509b6b0ca8fe779ebdc9d4475c5094d105910a ? 0xb895b85e3fa2b67d1b3b3243d7509b6a0ca8fe779ebdc9d4475c5094d105910a 0x70616f2f48dce01c65ace2685a072c6d * 0x879e2e2256feff0c40d6824e2ef3fc17 = 0x3b88d20523b761dd4aec1ed139f28c4baa0e1564fccd5926707eb1ffe7d749cb ? 0x3b88d20523b761dd4aec1ed139f28c4aaa0e1564fccd5926707eb1ffe7d749cb 0xbf8c59bb003553c18b2e02445e4be0f5 * 0xab27a171be5b133cd16aa4b296eb9d18 = 0x8010671df4712da0478a910d2b8b019bd201c56c8ce38b81bf08880e6efa57f8 ? 0x8010671df4712da0478a910d2b8b019ad201c56c8ce38b81bf08880e6efa57f8 7 out of 10 tests fail, there is bit flipped somewhere in the middle. g++ -std=c++11 -O2 -o test test.cpp && ./test 10 | python3 passes all tests, as does g++ -O3 with a gcc version other than 6.x. The problem seems to require the presence of loops (and presumably their unrolling), and the add_overflow and add_carry need to appear next to each other without anything in between. I was not able to narrow it down further.
[Bug middle-end/26461] liveness of thread local references across function calls
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461 cbcode at gmail dot com changed: What|Removed |Added CC||cbcode at gmail dot com --- Comment #19 from cbcode at gmail dot com --- As a compromise, I would like to suggest that '__thread volatile' or 'volatile __thread' always reloads the thread-local storage while __thread without volatile keeps the current caching behavior. The C and C++ standards recognize that stack-switching exists and indicate existing situations where variables need to be volatile-qualified in order to survive a task-switch, see e.g. http://en.cppreference.com/w/cpp/utility/program/setjmp .
[Bug c++/103885] New: ICE in capturing lambda for certain constexpr/auto combination
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103885 Bug ID: 103885 Summary: ICE in capturing lambda for certain constexpr/auto combination Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- ICE on the line indicated below. void test() { constexpr int N = 1; constexpr auto a1 = [](auto){ static_assert(N == 1); //OK return 2; }(3); constexpr auto a2 = [=](auto){ static_assert(N == 1); //OK return 2; }(3); constexpr auto a3 = [&](int){ static_assert(N == 1); //OK return 2; }(3); constexpr auto a4 = [&](auto){ static_assert(N == 1); //ICE in tsubst_copy, at cp/pt.c:16780 return 2; }(3); }
[Bug c++/103943] New: ICE building qualified name inside class with variadic CTAD
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103943 Bug ID: 103943 Summary: ICE building qualified name inside class with variadic CTAD Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cbcode at gmail dot com Target Milestone: --- // gcc has known problems with variadic CTAD, not sure if this is related. // regression (was fine in v8.3.0). template struct F0 { //OK R(*fun_ptr)(AA...); }; template struct F1 { //OK R(*fun_ptr)(AA...); F1(R(*fun_ptr)(AA...)) : fun_ptr(fun_ptr) {} }; template struct F2 { //OK R(*fun_ptr)(AA...); using fun_ptr_t = decltype(fun_ptr); F2(fun_ptr_t fun_ptr) : fun_ptr(fun_ptr) {} }; template struct F3 { R(*fun_ptr)(AA...); // using fun_ptr_t = decltype(fun_ptr); //OK as in F2 using fun_ptr_t = decltype(F3::fun_ptr); //ICE: Segmentation fault // using fun_ptr_t = decltype(F3::fun_ptr); //ICE: Segmentation fault F3(fun_ptr_t fun_ptr) : fun_ptr(fun_ptr) {} }; template struct F4 { static R fun_not_implemented(AA...); // using fun_ptr_t = decltype(&fun_not_implemented); //OK using fun_ptr_t = decltype(&F4::fun_not_implemented); //OK with aggregate initialization (no ctor) // using fun_ptr_t = decltype(&F4::fun_not_implemented); //OK with aggregate initialization (no ctor) fun_ptr_t fun_ptr; }; template struct F5 { //OK static R fun_not_implemented(AA...); using fun_ptr_t = decltype(&fun_not_implemented); fun_ptr_t fun_ptr; F5(fun_ptr_t fun_ptr) : fun_ptr(fun_ptr) {} }; template struct F6 { static R fun_not_implemented(AA...); // using fun_ptr_t = decltype(&fun_not_implemented); //OK as in F5 using fun_ptr_t = decltype(&F6::fun_not_implemented); //ICE: in build_qualified_name, at cp/tree.c:2238 // using fun_ptr_t = decltype(&F6::fun_not_implemented); //ICE: in build_qualified_name, at cp/tree.c:2238 fun_ptr_t fun_ptr; F6(fun_ptr_t fun_ptr) : fun_ptr(fun_ptr) {} }; template F0(R(*fun_ptr)(AA...)) -> F0; template F1(R(*fun_ptr)(AA...)) -> F1; template F2(R(*fun_ptr)(AA...)) -> F2; template F3(R(*fun_ptr)(AA...)) -> F3; template F4(R(*fun_ptr)(AA...)) -> F4; template F5(R(*fun_ptr)(AA...)) -> F5; template F6(R(*fun_ptr)(AA...)) -> F6; int fun(int a) { return a + 1; } #pragma GCC diagnostic ignored "-Wunused-but-set-variable" void test() { auto f0 = F0{&fun}; //OK auto f1 = F1{&fun}; //OK auto f2 = F2{&fun}; //OK auto f3 = F3{&fun}; //ICE: Segmentation fault auto f4 = F4{&fun}; //OK auto f5 = F5{&fun}; //OK auto f6 = F6{&fun}; //ICE: in build_qualified_name, at cp/tree.c:2238 }