[Bug c++/114706] New: ICE - std::bit_cast in consteval function involving union
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114706 Bug ID: 114706 Summary: ICE - std::bit_cast in consteval function involving union Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- ICE in a consteval function bit_casting an array of unions. The code isn't valid due to the union, but the compiler is not handling it properly (since gcc11...trunk). Reduced to the following program: CODE #include union U { int u; }; consteval void f() { U result[]{0, 0}; auto x = std::bit_cast(result); } int main() { f(); } LIVE: https://godbolt.org/z/Y943bc5zK OUTPUT /opt/compiler-explorer/gcc-trunk-20240412/include/c++/14.0.1/bit:94:33: internal compiler error: in native_encode_initializer, at fold-const.cc:8468 94 | return __builtin_bit_cast(_To, __from); | ^~~ 0x267826c internal_error(char const*, ...) ???:0 0xa58c63 fancy_abort(char const*, int, char const*) ???:0 0xfa0eaf native_encode_initializer(tree_node*, unsigned char*, int, int, unsigned char*) ???:0 0xacf0f0 maybe_constant_value(tree_node*, tree_node*, mce_value) ???:0 0xd3a75f store_init_value(tree_node*, tree_node*, vec**, int) ???:0 0xb474fe cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int, cp_decomp*) ???:0 0xc5c81a c_parse_file() ???:0 0xdb1489 c_common_parse_file() ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
[Bug c++/111742] Misaligned generated code with MI using aligned virtual base
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111742 --- Comment #2 from Chris Uzdavinis --- No, this is not a ubsan report. Code *crashes* and I thought showing the UBsan warning was enough to demonstrate it. A minimal change to make the code crash instead of just report ubsan errors: struct X { void * a = nullptr; void * b = nullptr; }; struct alignas(16) AlignedData { }; struct A : virtual AlignedData { int x = 0; // << add this X xxx; int& ref = x;// << and this }; struct B : virtual AlignedData {}; struct Test : B, A {}; Test* t = new Test; int main() {} *** SEGFAULT *** https://godbolt.org/z/f57vs7jxP
[Bug c++/111742] New: Misaligned generated code with MI using aligned virtual base
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111742 Bug ID: 111742 Summary: Misaligned generated code with MI using aligned virtual base Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Generated code is misaligned (and crashes in slightly more complex code), in trunk all the way back to gcc 8.1, when built in c++11 or higher, with O3. (Linux, x86) Complete code: // struct X { void * a = nullptr; void * b = nullptr; }; struct alignas(16) AlignedData { }; struct A : virtual AlignedData { X xxx; }; struct B : virtual AlignedData {}; struct Test : B, A {}; Test* t = new Test; int main() {} // Compiler Explorer demo: https://godbolt.org/z/aodTdaedW Running with UB-san reports this: /app/example.cpp:14:8: runtime error: constructor call on misaligned address 0x0227f2b8 for type 'struct A', which requires 16 byte alignment 0x0227f2b8: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ /app/example.cpp:8:8: runtime error: member access within misaligned address 0x0227f2b8 for type 'struct A', which requires 16 byte alignment 0x0227f2b8: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^
[Bug c++/110810] New: ICE in check_noexcept_r, at cp/except.cc:1068
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110810 Bug ID: 110810 Summary: ICE in check_noexcept_r, at cp/except.cc:1068 Product: gcc Version: 12.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 55634 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55634&action=edit preprocessed code, zipped Starting with x86_64 version of gcc 12.1 (linux), and through all newer versions (including the trunk) on Compiler explorer, I receive an internal compiler error on the following code: Some overlap with https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109899 but there is enough difference that I thought it might still be useful to report. https://godbolt.org/z/ThTdxqzKG #include struct Foo { Foo() {} ~Foo() {} }; struct X { Foo data[4]; }; template void f() { char storage[256]; auto& object = *new(storage) X{}; object.~X(); } * removing {} in the call to placement new "fixes" it, or replacing with parenthesis. Another fix is removing either the default ctor or destructor from Foo, or making data not be an array, or f() not be a template. It's a strange and specific combination. Output: source>: In function 'void f()': :15:36: internal compiler error: in check_noexcept_r, at cp/except.cc:1068 15 | auto& object = *new(storage) X{}; |^ 0x246af2e internal_error(char const*, ...) ???:0 0xac8ab6 fancy_abort(char const*, int, char const*) ???:0 0x16d661c walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, hash_set >*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set >*)) ???:0 0x16d9912 walk_tree_without_duplicates_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*, tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set >*)) ???:0 0xbd04a3 expr_noexcept_p(tree_node*, int) ???:0 0xbd64f0 build_vec_delete(unsigned int, tree_node*, tree_node*, special_function_kind, int, int) ???:0 0xbd6a1e build_delete(unsigned int, tree_node*, tree_node*, special_function_kind, int, int, int) ???:0 0xb8c5cc cxx_maybe_build_cleanup(tree_node*, int) ???:0 0xaf6b55 build_new_method_call(tree_node*, tree_node*, vec**, tree_node*, int, tree_node**, int) ???:0 0xaf78e7 build_special_member_call(tree_node*, tree_node*, vec**, tree_node*, int, int) ???:0 0xbde5fc build_new(unsigned int, vec**, tree_node*, tree_node*, vec**, int, int) ???:0 0xcae89f c_parse_file() ???:0 0xdee919 c_common_parse_file() ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
[Bug tree-optimization/110620] spurious array-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620 --- Comment #4 from Chris Uzdavinis --- (Sorry I was getting bugzilla errors about collisions when adding comments, but they seemed to have gone through after all.)
[Bug tree-optimization/110620] spurious array-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620 --- Comment #3 from Chris Uzdavinis --- Starting with Gcc12.1 (at least on x86) and through all versions up to the trunk (post 13.1) This warning hits with optimization -O2 or higher. https://godbolt.org/z/q3T39Wf8c #include void foo(std::vector>& vec) { if (vec.size() > 5) { vec[3].first = 0; } } int main() { auto v1 = std::vector{std::pair(1, 2)}; foo(v1); } What is interesting to me is that the analyzer is missing the fact that size is explicitly tested, and the index is a constant expression that is lower. There are a lot of array-bounds bugs reported, and all have similarities and I'm not sure if this is a dupe or not, though I went through the open ones in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456 And did not see an example quite like this. In function 'void foo(std::vector >&)', inlined from 'int main()' at :11:8: :5:22: error: array subscript 3 is outside array bounds of 'std::pair [1]' [-Werror=array-bounds=] 5 | vec[3].first = 0; In file included from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/x86_64-linux-gnu/bits/c++allocator.h:33, from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:46, from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:63, from :1: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = std::pair]', inlined from 'constexpr _Tp* std::allocator< >::allocate(std::size_t) [with _Tp = std::pair]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:198:40, inlined from 'static constexpr _Tp* std::allocator_traits >::allocate(allocator_type&, size_type) [with _Tp = std::pair]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/alloc_traits.h:482:28, inlined from 'constexpr std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:378:33, inlined from 'constexpr void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::pair*; _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:1687:25, inlined from 'constexpr std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:677:21, inlined from 'int main()' at :10:42: /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/new_allocator.h:147:55: note: at offset 24 into object of size 8 allocated by 'operator new' 147 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); | ^ cc1plus: all warnings being treated as errors Compiler returned: 1
[Bug tree-optimization/110620] spurious array-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620 --- Comment #2 from Chris Uzdavinis --- Created attachment 55516 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55516&action=edit preprocessed code
[Bug tree-optimization/110620] spurious array-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620 --- Comment #1 from Chris Uzdavinis --- Starting with Gcc12.1 (at least on x86) and through all versions up to the trunk (post 13.1) This warning hits with optimization -O2 or higher. https://godbolt.org/z/q3T39Wf8c #include void foo(std::vector>& vec) { if (vec.size() > 5) { vec[3].first = 0; } } int main() { auto v1 = std::vector{std::pair(1, 2)}; foo(v1); } What is interesting to me is that the analyzer is missing the fact that size is explicitly tested, and the index is a constant expression that is lower. There are a lot of array-bounds bugs reported, and all have similarities and I'm not sure if this is a dupe or not, though I went through the open ones in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456 And did not see an example quite like this. In function 'void foo(std::vector >&)', inlined from 'int main()' at :11:8: :5:22: error: array subscript 3 is outside array bounds of 'std::pair [1]' [-Werror=array-bounds=] 5 | vec[3].first = 0; In file included from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/x86_64-linux-gnu/bits/c++allocator.h:33, from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:46, from /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/vector:63, from :1: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = std::pair]', inlined from 'constexpr _Tp* std::allocator< >::allocate(std::size_t) [with _Tp = std::pair]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:198:40, inlined from 'static constexpr _Tp* std::allocator_traits >::allocate(allocator_type&, size_type) [with _Tp = std::pair]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/alloc_traits.h:482:28, inlined from 'constexpr std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:378:33, inlined from 'constexpr void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const std::pair*; _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:1687:25, inlined from 'constexpr std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = std::pair; _Alloc = std::allocator >]' at /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/stl_vector.h:677:21, inlined from 'int main()' at :10:42: /opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/new_allocator.h:147:55: note: at offset 24 into object of size 8 allocated by 'operator new' 147 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); | ^ cc1plus: all warnings being treated as errors Compiler returned: 1
[Bug c++/110620] New: spurious array-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620 Bug ID: 110620 Summary: spurious array-bounds Product: gcc Version: 12.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: ---
[Bug c++/107532] [13 Regression] -Werror=dangling-reference false positives in libcamera-0.0.1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532 Chris Uzdavinis changed: What|Removed |Added CC||cuzdav at gmail dot com --- Comment #33 from Chris Uzdavinis --- Could an attribute or annotation be added so we can mark our classes to opt-out of this warning for them? I like the warning in general but it is hitting one of our core "span-like" classes that stores pointers, and is going off so much that I'm going to need to disable it. I'd be much happier disabling it on a per-object basis, rather than globally.
[Bug tree-optimization/107852] New: Spurious warnings stringop-overflow and array-bounds copying data as bytes into vector
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107852 Bug ID: 107852 Summary: Spurious warnings stringop-overflow and array-bounds copying data as bytes into vector Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 53957 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53957&action=edit preprocessed source code, if that's useful. Starting with gcc 12 and continuing into the current trunk, with optimizations enabled, the compiler emits warnings from static analysis regarding copying data internal to the vector class, both on Compiler Explorer, and on my local linux box running Centos9. Options: g++ warnings.cpp -Werror -O2 -Warray-bounds Code: #include std::vector bytes; int value{}; void copyValueBytes() { bytes.clear(); auto ptr = reinterpret_cast(&value); bytes.insert(bytes.end(), ptr, ptr + sizeof(value)); } https://godbolt.org/z/MfjM9xKjP Observations: * if I don't clear() the vector first, it does not report any errors * if I call bytes.resize(0) it reports the same output * if I call bytes.resize(1) it compiles cleanly * if I use a std::deque instead of a vector, it compiles cleanly A reinterpret_cast always is eye-raising, but I think this is a valid use since its address is casted to a char*, a compatible type. Output: In file included from /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/vector:60, from :1: In static member function 'static _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = char; bool _IsMove = true]', inlined from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = true; _II = char*; _OI = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_algobase.h:495:30, inlined from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = true; _II = char*; _OI = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_algobase.h:522:42, inlined from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = true; _II = char*; _OI = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_algobase.h:529:31, inlined from '_OI std::copy(_II, _II, _OI) [with _II = move_iterator; _OI = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_algobase.h:620:7, inlined from 'static _ForwardIterator std::__uninitialized_copy::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_uninitialized.h:147:27, inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = move_iterator; _ForwardIterator = char*]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_uninitialized.h:185:15, inlined from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = move_iterator; _ForwardIterator = char*; _Tp = char]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_uninitialized.h:372:37, inlined from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = char*; _ForwardIterator = char*; _Allocator = allocator]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_uninitialized.h:397:2, inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const char*; _Tp = char; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/vector.tcc:801:9, inlined from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(iterator, _InputIterator, _InputIterator, std::__false_type) [with _InputIterator = const char*; _Tp = char; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:1779:19, inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = const char*; = void; _Tp = char; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:1481:22, inlined from 'void copyValueBytes()' at :9:17: /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/b
[Bug analyzer/107725] Spurious warning: use of uninitialized value with std::any
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107725 --- Comment #3 from Chris Uzdavinis --- Ah, sorry I didn't realize that. Its use was suggested by Jason Turner in his most recent C++ Weekly so I started to give it a try. Perhaps there will be an influx of such premature reports since it was put on the radar.
[Bug analyzer/107725] Spurious warning: use of uninitialized value with std::any
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107725 --- Comment #1 from Chris Uzdavinis --- I get a similar warning with this code. Unsure if it's the same underlying issue. Also does not warn with g++10 or g++11, but does with newer versions. #include #include std::string create() { std::ostringstream oss; return oss.str(); } https://godbolt.org/z/cz66zhKn5 :6:20: warning: use of uninitialized value '' [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 6 | return oss.str(); |^ 'std::string create()': events 1-2 | |4 | std::string create() { | |^ | || | |(1) region created on stack here |5 | std::ostringstream oss; |6 | return oss.str(); | |~ | || | |(2) use of uninitialized value '' here
[Bug analyzer/107725] New: Spurious warning: use of uninitialized value with std::any
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107725 Bug ID: 107725 Summary: Spurious warning: use of uninitialized value with std::any Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 53914 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53914&action=edit preprocessed code With the analyzer (-fanalyzer), this built cleanly with GCC10 and GCC11, but starting with GCC 12 (still occurring in trunk) in either C++17 or c++20 mode, I see this warning (x86 linux): :4:13: warning: use of uninitialized value '' [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 4 | return {}; | ^ 'std::any create()': events 1-2 | |3 | std::any create() { | | ^ | | | | | (1) region created on stack here |4 | return {}; | | ~ | | | | | (2) use of uninitialized value '' here | Compiler returned: 0 This is the code in its entirety: #include std::any create() { return {}; } https://godbolt.org/z/TWPcaW4Kn
[Bug libstdc++/106275] unordered_map with std::string key, std::hash, and custom equality predicate weirdness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106275 --- Comment #6 from Chris Uzdavinis --- Thank you for the information. If the equality comparison function is slow enough, the large number of extra calls may not be an optimization. While looking into it, the vastly different runtime behavior of it jumped out to me as an indication of a problem, and seemed to be the answer to why internal tests drew my attention to this in the first place. (Behavior is normal without this optimization, but tests complained with it.) But now I understand it better, being a combination of the new behavior and characteristics of the custom predicate in "real code" of which this is a minimization. The extra calls are a symptom, not a cause.
[Bug libstdc++/106275] unordered_map with std::string key, std::hash, and custom equality predicate weirdness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106275 --- Comment #1 from Chris Uzdavinis --- Created attachment 53293 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53293&action=edit preprocessed code
[Bug libstdc++/106275] New: unordered_map with std::string key, std::hash, and custom equality predicate weirdness
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106275 Bug ID: 106275 Summary: unordered_map with std::string key, std::hash, and custom equality predicate weirdness Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- g++12.1 (on linux), Does not occur on GCC 11 or earlier. std::unordered_map, CustomPred> acts strangely such that finds do not seem to use the hasher properly, and seem to use a linear search, invoking the equality predicate against every key. A custom hasher implemented in terms of std::hash fixes it, as does using the default equality predicate. It also does not happen with key type of, say, "int". I've only seen it for std::string (in my limited experimentation.) I added output to the predicate to indicate when it's called, and it shows excessive calls printed when "SHOWBUG" macro is defined. #include #include #include #include struct EqualToWrapper{ bool operator()(const std::string& key1, const std::string& key2) const { std::cout << "equal_to(key1=" << key1 << ", key2=" << key2 << ")\n"; return std::equal_to<>{}(key1, key2); } }; #ifdef SHOWBUG using UsageMap = std::unordered_map, EqualToWrapper>; #else struct MyHash : public std::hash {}; using UsageMap = std::unordered_map; #endif int main() { UsageMap m; m.insert(std::make_pair("A", 111)); m.insert(std::make_pair("B", 222)); m.insert(std::make_pair("C", 333)); m.insert(std::make_pair("D", 444)); m.insert(std::make_pair("E", 555)); m.insert(std::make_pair("F", 666)); m.find("foo"); } With a custom equality predicate and my derived-from-std::hash hasher, output on g++ 12 is: equal_to(key1=C, key2=A) When run with -DSHOWBUG macro defined, output is: equal_to(key1=B, key2=A) equal_to(key1=C, key2=B) equal_to(key1=C, key2=A) equal_to(key1=D, key2=B) equal_to(key1=D, key2=C) equal_to(key1=D, key2=A) equal_to(key1=E, key2=B) equal_to(key1=E, key2=D) equal_to(key1=E, key2=C) equal_to(key1=E, key2=A) equal_to(key1=F, key2=E) equal_to(key1=F, key2=B) equal_to(key1=F, key2=D) equal_to(key1=F, key2=C) equal_to(key1=F, key2=A) equal_to(key1=foo, key2=F) equal_to(key1=foo, key2=E) equal_to(key1=foo, key2=B) equal_to(key1=foo, key2=D) equal_to(key1=foo, key2=C) equal_to(key1=foo, key2=A) On Godbolt: https://godbolt.org/z/GP5dox1qs $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/imc/gcc-12.1.0/libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-12.1.0/configure --prefix=/opt/imc/gcc-12.1.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/build/INSTALLDIR//opt/imc/gcc-12.1.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.1.0 (GCC)
[Bug tree-optimization/106044] Spurious warning: -Wrestrict for adding std::strings (__builtin_memcpy)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106044 --- Comment #2 from Chris Uzdavinis --- Even marginally simpler: #include auto f() { return "_" + std::string(" "); } Originally I marked it as tree-optimization since it's only with -O3, but it could be an issue in the standard library itself. I didn't consider that initially.
[Bug tree-optimization/106044] Spurious warning: -Wrestrict for adding std::strings (__builtin_memcpy)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106044 --- Comment #1 from Chris Uzdavinis --- only in c++20, too.
[Bug tree-optimization/106044] New: Spurious warning: -Wrestrict for adding std::strings (__builtin_memcpy)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106044 Bug ID: 106044 Summary: Spurious warning: -Wrestrict for adding std::strings (__builtin_memcpy) Product: gcc Version: 12.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 53182 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53182&action=edit preprocessed code At optimization O3, beginning in g++ 12.1 (and still present in trunk) with -Wrestrict enabled I see the following warning: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict] Here is the code: /// #include std::string f(std::size_t n) { return "_" + std::to_string(n); } /// On Compiler explorer: https://godbolt.org/z/KMWehnscM Command line: g++12 -O3 --std=c++20 -Wrestrict source.cpp Output: In file included from /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/string:40, from :1: In static member function 'static constexpr std::char_traits::char_type* std::char_traits::copy(char_type*, const char_type*, std::size_t)', inlined from 'static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/basic_string.h:423:21, inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Allocator>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/basic_string.tcc:532:22, inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/basic_string.h:2171:19, inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(size_type, const _CharT*) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/basic_string.h:1928:22, inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, __cxx11::basic_string<_CharT, _Traits, _Allocator>&&) [with _CharT = char; _Traits = char_traits; _Alloc = allocator]' at /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/basic_string.h:3594:36, inlined from 'std::string f(std::size_t)' at :4:34: /opt/compiler-explorer/gcc-trunk-20220621/include/c++/13.0.0/bits/char_traits.h:434:56: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' accessing 9223372036854775810 or more bytes at offsets [2, 9223372036854775807] and 1 may overlap up to 9223372036854775813 bytes at offset -3 [-Wrestrict] 434 | return static_cast(__builtin_memcpy(__s1, __s2, __n)); | ^ Compiler returned: 0 // local machine g++ output (where I first encountered it) [cuzdav@docker tmp]$ /opt/imc/gcc-12.1.0/bin/g++ -v Using built-in specs. COLLECT_GCC=/opt/imc/gcc-12.1.0/bin/g++ COLLECT_LTO_WRAPPER=/opt/imc/gcc-12.1.0/libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-12.1.0/configure --prefix=/opt/imc/gcc-12.1.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/build/INSTALLDIR//opt/imc/gcc-12.1.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.1.0 (GCC)
[Bug c++/105726] New: spurious warning with -Warray-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105726 Bug ID: 105726 Summary: spurious warning with -Warray-bounds Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 53030 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53030&action=edit preprocessed version I just ran into an issue that seems to have appeared in Gcc 10.1 and is still there in 11, 12, and in the trunk. The following code produces a spurious warning about reading out of bounds, but if I remove the "pad" field, or change from std::array to a "raw" array, the warning goes away. //=== #include #include struct X { char pad[4]; std::array mField; }; void encode(char* aBuffer, const X& aMessage) { strncpy(aBuffer, aMessage.mField.data(), 1); } //=== LIVE: https://godbolt.org/z/zEsx5P8eP : In function 'void encode(char*, const X&)': :10:16: warning: 'char* strncpy(char*, const char*, size_t)' offset 4 from the object at 'aMessage' is out of the bounds of referenced subobject 'std::array::_M_elems' with type 'char [1]' at offset 4 [-Warray-bounds] 10 | strncpy(aBuffer, aMessage.mField.data(), 1); | ~~~^~~~ In file included from :1: /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/array:115:56: note: subobject 'std::array::_M_elems' declared here 115 | typename _AT_Type::_Type _M_elems; |^~~~ Compiler returned: 0 OUTPUT of g++ -v Using built-in specs. COLLECT_GCC=/opt/imc/gcc-12.1.0/bin/g++ COLLECT_LTO_WRAPPER=/opt/imc/gcc-12.1.0/libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-12.1.0/configure --prefix=/opt/imc/gcc-12.1.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/build/INSTALLDIR//opt/imc/gcc-12.1.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.1.0 (GCC)
[Bug c++/105589] New: [ICE] templated type alias over std::array with bound type in template function fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105589 Bug ID: 105589 Summary: [ICE] templated type alias over std::array with bound type in template function fails Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 52969 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52969&action=edit preprocessed code Internal compiler error - new in gcc12 COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/opt/imc/gcc-12.1.0/libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-12.1.0/configure --prefix=/opt/imc/gcc-12.1.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/home/trading/cuzdav/code/imc-gcc/gcc/12.1.0/INSTALLDIR//opt/imc/gcc-12.1.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.1.0 (GCC) Spent a long time minimizing it to this example, so it's contrived but small. The user-provided constructor in the element type seems related. The auto parameter in form() is also necessary, even if unused. /// #include struct X { X() {} }; template using C = std::array; void form(auto) { auto w = C<16>{}; } /// LIVE: (Also visible on the 12.1 on godbolt) https://godbolt.org/z/qWba56onf OUTPUT: foo2.cpp: In function ‘void form(auto:3)’: foo2.cpp:11:18: internal compiler error: in build_value_init, at cp/init.cc:347 11 | auto w = C<16>{}; | ^ 0x1b1211a diagnostic_impl(rich_location*, diagnostic_metadata const*, int, char const*, __va_list_tag (*) [1], diagnostic_t) ???:0 0x13637ff internal_error(char const*, ...) ???:0 0x13638d1 fancy_abort(char const*, int, char const*) ???:0 0x7665e6 build_value_init(tree_node*, int) [clone .cold] ???:0 0x1901bb1 build_vec_init_expr(tree_node*, tree_node*, int) ???:0 0x809217 digest_init_r(tree_node*, tree_node*, int, int, int) [clone .cold] ???:0 0x157c0ca massage_init_elt(tree_node*, tree_node*, int, int, int) ???:0 0x8096e7 digest_init_r(tree_node*, tree_node*, int, int, int) [clone .cold] ???:0 0x18ff96c finish_compound_literal(tree_node*, tree_node*, int, fcl_t) ???:0 0x15453de cp_parser_functional_cast(cp_parser*, tree_node*) ???:0 0x153e4ac cp_parser_postfix_expression(cp_parser*, bool, bool, bool, bool, cp_id_kind*) ???:0 0x153c5dc cp_parser_binary_expression(cp_parser*, bool, bool, bool, cp_parser_prec, cp_id_kind*) ???:0 0x153c2b2 cp_parser_assignment_expression(cp_parser*, cp_id_kind*, bool, bool) ???:0 0x153c130 cp_parser_constant_expression(cp_parser*, int, bool*, bool) ???:0 0x153bf7b cp_parser_initializer(cp_parser*, bool*, bool*, bool) ???:0 0x7a2ea4 cp_parser_init_declarator(cp_parser*, int, cp_decl_specifier_seq*, vec*, bool, bool, int, bool*, tree_node**, unsigned int*, tree_node**) [clone .cold] ???:0 0x15300c5 cp_parser_simple_declaration(cp_parser*, bool, tree_node**) ???:0 0x1542170 cp_parser_declaration_statement(cp_parser*) ???:0 0x1540bf3 cp_parser_statement(cp_parser*, tree_node*, bool, bool*, vec*, unsigned int*) ???:0 0x1540657 cp_parser_compound_statement(cp_parser*, tree_node*, int, bool) ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. Preprocessed code attached.
[Bug c++/105571] New: Spurious "set but not used" on static constexpr local, used in lambda
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105571 Bug ID: 105571 Summary: Spurious "set but not used" on static constexpr local, used in lambda Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- With -Wall, in every c++ language level on virtually every version of g++ as far back as 4.9, g++ warns ("variable 'THIS_IS_USED' set but not used") on the following complete code: template void for_each(IterT b, IterT e, FuncT f) { while (b != e) { f(*b++); } } volatile int sink; void xxx(int x) { sink = x; } void foo() { static constexpr auto THIS_IS_USED = 1; int arr[10]{1,2,3,4,5,6,7,8,9,10}; for_each(arr, arr+10, [](auto v) { xxx(THIS_IS_USED + v); }); } : In function 'void foo()': :15:27: warning: variable 'THIS_IS_USED' set but not used [-Wunused-but-set-variable] 15 | static constexpr auto THIS_IS_USED = 1; | ^~~~ Compiler returned: 0 https://godbolt.org/z/b1s5Yqb3r This appears to be related to the "auto" parameter in the lambda. Changing it to 'int' makes the problem go away.
[Bug c++/105511] New: Spurious warning: "expected 'template' keyword..." when lt and gt compare over ternary
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105511 Bug ID: 105511 Summary: Spurious warning: "expected 'template' keyword..." when lt and gt compare over ternary Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Only on g++ 12 (new warning). Building with the freshly released G++12 with warning enabled (-Werror=missing-template-keyword) Complete, minimized code: template bool before(bool ascending, X & a, X * b) { return ascending ? a.value < (*b).value : a.value > (*b).value; } :4:26: warning: expected 'template' keyword before dependent template name [-Wmissing-template-keyword] 4 | return ascending ? a.value < (*b).value : a.value > (*b).value; | ^ Visible on Compiler Explorer https://godbolt.org/z/dW9hjbdex Yes, the left-angle and right-angle brackets are present, but it's not looking quite hard enough to see that they are on opposite sides of a ternary ':'. My Compiler, if it matters: /opt/imc/gcc-12.1.0/bin/g++ (base) bash-4.2$ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/imc/gcc-12.1.0/libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-12.1.0/configure --prefix=/opt/imc/gcc-12.1.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/home/trading/cuzdav/code/imc-gcc/gcc/12.1.0/INSTALLDIR//opt/imc/gcc-12.1.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.1.0 (GCC)
[Bug c++/105386] New: Tuple in unevaluated context is instantiated; creates reference to void
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105386 Bug ID: 105386 Summary: Tuple in unevaluated context is instantiated; creates reference to void Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 52878 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52878&action=edit preprocessed code Starting with g++11.2 some of meta-programming code started to fail. While instantiating a tuple in an unevaluated context, it now complains that the tuple contains a void member and it's creating a reference to void, yet it is the same type as in the working case, just computed differently. Output of g++ -v (base) bash-4.2$ /opt/imc/gcc-11.2.0/bin/g++ -v Using built-in specs. COLLECT_GCC=/opt/imc/gcc-11.2.0/bin/g++ COLLECT_LTO_WRAPPER=/opt/imc/gcc-11.2.0/libexec/gcc/x86_64-pc-linux-gnu/11.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-11.2.0/configure --prefix=/opt/imc/gcc-11.2.0 --enable-languages=c,c++,fortran,lto --disable-multilib --with-build-time-tools=/opt/buildagent/work/d7a993299378ca7e/11.2.0/INSTALLDIR//opt/imc/gcc-11.2.0/bin --enable-libstdcxx-time=rt Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (GCC) Code appears in its entirety in attachment, but here is the main focus of the error: class Chunk { }; using ChunkMetaData = std::tuple; template ChunkMetaData chunkMetaData(MessageT&&); template class ChunkSeq { public: using good_type = ChunkMetaData; #ifdef SHOWBUG using bad_type = decltype(chunkMetaData(std::declval())); static_assert(std::is_same_v); using MetaData = bad_type; #else using MetaData = good_type; #endif In gcc10, when SHOWBUG is defined, it still builds. The static assertion passes. With gcc11 and 12, it fails, upset about a tuple creating a reference to void. Live example: https://godbolt.org/z/4Wq3s936W Errors: In file included from krx/feed/sr10/foo.cpp:1: /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple: In instantiation of ‘struct std::_Head_base<2, void, false>’: /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:407:12: required from ‘struct std::_Tuple_impl<2, void>’ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:244:12: required from ‘struct std::_Tuple_impl<0, void, Chunk, void>’ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:599:11: required from ‘class std::tuple’ krx/feed/sr10/foo.cpp:171:42: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] krx/feed/sr10/foo.cpp:111:57: required from ‘constexpr const bool InvertPredicate >::value >’ krx/feed/sr10/foo.cpp:122:11: required from ‘struct RemoveIfImpl >, std::tuple, PartialField<1> > >’ krx/feed/sr10/foo.cpp:235:7: required by substitution of ‘template using PartialStartField = typename KeepIf, typename RemoveIfImpl >, std::tuple, PartialField<1> > >::type>::type [with T = Chunk]’ krx/feed/sr10/foo.cpp:240:47: required from ‘constexpr const bool HasPartialBegin::value’ krx/feed/sr10/foo.cpp:111:57: required from ‘constexpr const bool InvertPredicate::value’ krx/feed/sr10/foo.cpp:122:11: required from ‘struct RemoveIfImpl, std::tuple >’ krx/feed/sr10/foo.cpp:247:6: required from here /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:182:17: error: forming reference to void 182 | constexpr _Head_base(const _Head& __h) | ^~ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:219:7: error: forming reference to void 219 | _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } | ^~~ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:222:7: error: forming reference to void 222 | _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } | ^~~ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:224:13: error: ‘std::_Head_base<_Idx, _Head, false>::_M_head_impl’ has incomplete type 224 | _Head _M_head_impl; | ^~~~ /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++/11.2.0/tuple:224:13: error: invalid use of ‘void’ In file included from krx/feed/sr10/foo.cpp:1: /opt/imc/gcc-11.2.0/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../include/c++
[Bug tree-optimization/80635] [8/9/10/11 regression] std::optional and bogus -Wmaybe-uninitialized warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 Chris Uzdavinis changed: What|Removed |Added CC||cuzdav at gmail dot com --- Comment #54 from Chris Uzdavinis --- I'm not sure if this is the same bug or a different one, but it's in the same family (I think). Visible in current trunk, 10.2 release, and as far back as 8.1. I found optimize level -Os is necessary https://godbolt.org/z/Ta55jM #include using Opt = std::optional; Opt f(int x) { Opt ret; Opt val = (x == 1) ? 999 : (x == 2) ? Opt(2) : std::nullopt; if (val.has_value()) ret = val.value(); return ret; } : In function 'Opt f(int)': :9:12: error: 'val.std::_Optional_payload_base::_Storage::_M_value' may be used uninitialized in this function [-Werror=maybe-uninitialized] 9 | return ret; |^~~
[Bug c++/97053] New: an O3 codegen bug
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97053 Bug ID: 97053 Summary: an O3 codegen bug Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 49217 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49217&action=edit preprocessed code in case something changes after submitting "Wrong" output codegen bug. Very sensitive, almost any code change prevents the problem, including O2 or less, as well as running under ubsan or asan, reordering variables, and in some cases changing the values involved (such as setting p=0 instead of 1) Copying a buffer of 8 bytes of data (null terminated) results in a 6-bytes (of data) null terminated "string", losing 2 bytes from the end. A variable "len" holds the strlen() of this string, reports 6, but some code affected by optimizer seems to think it is a larger value. Expected output: runtime len=8 orig=ABCD copy=ABCD actual output: runtime len=6 orig=ABCD copy=ABCDXX Even though above the actual output shows len=6 when printing "len", a separate line of code is not present in the assembly (presumably optimized away under a confused compile-time eval.) if (len < 8) printf("len < 8\n"); // but len == 6 Problem visible in 10.1 and 10.2 at -O2 and -O3, but not -O1 or less, nor in in 9.x or earlier. CODE: #include #include struct Data { short n; char name[8 + 1]; int p; char s; int b; }; int main(int argc, char** argv) { int p = 1; char orig[9]{""}; std::memcpy(orig, "ABCD", 4); Data data{}; data.n = 5u; // this should copy ABCD but loses final 2 XX's std::memcpy(data.name, orig, 8); data.s = 'X'; data.b = p; const size_t len = strlen(data.name); if (len < 8) printf("len < 8\n"); // does not print std::printf("runtime len=%lu\n", len); // this, however, prints 6 std::printf("orig=%s\ncopy=%s\n", orig, data.name); } Live on godbolt: https://godbolt.org/z/v6xqh8
[Bug c++/96592] New: Tuple element w/ member reference to incomplete template type rejected
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96592 Bug ID: 96592 Summary: Tuple element w/ member reference to incomplete template type rejected Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 49049 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49049&action=edit source as shown in preview, g++10.2 preprocessed code, and the error messages This code seems a regression introduced in g++ 10.1, is still in 10.2 and remains in the trunk. It works on 9.x and as far back as g++ 6, plus all versions of clang since 6, icc, msvc, etc. There are many independent changes that can make it work, including: * making SomeQuery constructor a template constructor (on SessionU) * changing the reference to a pointer * explicitly declaring Session as an incomplete type and not using templates #include template struct SomeQuery { SessionT& session_; SomeQuery(SessionT& session) : session_(session) {} }; template struct Handler { std::tuple> queries_; Handler(SessionT& session) : queries_(session) {} }; struct Session { Handler handler_; Session() : handler_{*this} {} }; int main() { Session session; } It looks like the tuple class is doing some concept checking that isn't quite working, but I haven't dug deeply enough to determine if it's a library or underlying compiler issue. Live example on Compiler Explorer https://godbolt.org/z/7naPMx
[Bug c++/94624] New: Nested lambda mutable capture of outer lambda non-mutable capture is not allowed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94624 Bug ID: 94624 Summary: Nested lambda mutable capture of outer lambda non-mutable capture is not allowed Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- An inner mutable lambda with a simple copy-capture of the outer lambda's immutable variable is not allowed to be modified. This applies to all versions of g++ since mutable lambdas were introduced. Live example https://godbolt.org/z/RkMeYL Full source code to reproduce: template void foo(F const&) {} template void bar(F const&) {} void bad() { int x = 5; foo([x]() { bar([x]() mutable { x = 10;// << modify local copy in mutable lambda should be ok }); }); } In lambda function: 8:15: error: assignment of read-only variable 'x' 8 | x = 10; | ~~^~~~ Compiler returned: 1 Adding "mutable" to the outer lambda works around this, so somehow the read-only behavior in the outer lambda is leaking into the inner lambda, even though it is a simple copy and the underlying type is "int". Additionally, clang accepts this all the way back to version 5.
[Bug c++/91465] New: unexpected expression of kind overload (ICE)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91465 Bug ID: 91465 Summary: unexpected expression of kind overload (ICE) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- This code results in an ICE: In member function 'Destination Bar::baz(Source)': internal compiler error: unexpected expression 'foo' of kind overload return Destination{foo(aLowValue)}; ^ // See it LIVE! https://godbolt.org/z/42c_Ll enum class Destination {}; enum class Source {}; Destination foo(Source value) { return Destination{}; } Destination foo(double value) { return Destination{}; } template struct Bar { Destination baz(Source aLowValue) { return Destination{foo(aLowValue)}; // <<<< HERE } }; Bug appears in 9.1 in c++17 (and up) in all higher g++ versions as well. OK if c++14 or lower, and OK if older g++.
[Bug c++/90301] New: RangeV3 usage, ICE internal compiler error: canonical types differ for identical types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90301 Bug ID: 90301 Summary: RangeV3 usage, ICE internal compiler error: canonical types differ for identical types Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Created attachment 46270 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46270&action=edit full output from compiler (since it's long) On Godbolt, version 8.3 and releases before it, this compiles. It compiles in Clang from trunk back to version 5. On the current g++ TRUNK version, it fails in -std=c++17 mode and -std=c++2a mode. (But it SUCCEEDS in TRUNK -std=c++14 mode) I didn't dig into rangeV3 implementation, so it may resemble some other existing reports: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52830 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89766 Here's the complete, minimal, reproducible extraction of the code triggering the bug //- #include #include int g() { int v[]{1, 2, 3}; return ranges::v3::accumulate( v | ranges::v3::view::filter([](int){return true;}), 0); } //- side-by-side on Godbolt: https://godbolt.org/z/q9z4mI OUTPUT: /opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/compressed_pair.hpp:51:27: internal compiler error: canonical types differ for identical types 'std::integral_constant::type::value ...> >' and 'std::integral_constant::type::value ...> >' 51 | constexpr compressed_tuple_(Args &&... args) | ^ Please submit a full bug report, with preprocessed source if appropriate. See <https://gcc.gnu.org/bugs/> for instructions. Compiler returned: 1 (Full output is attached)
[Bug c++/87921] New: Incorrect error "storage size of [array] isn't known (when it is)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87921 Bug ID: 87921 Summary: Incorrect error "storage size of [array] isn't known (when it is) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- I'm getting an error for what I believe to be valid code. Here's a complete, minimal example to reproduce it: // template struct X { static constexpr long Ary[] = { 1L }; long foo() { return Ary[0]; } }; void f() { class L{}; X foo{}; } // https://godbolt.org/z/2tGwxo #1 with x86-64 gcc (trunk) :3:27: error: storage size of 'X::Ary' isn't known 3 static constexpr long Ary[] = { 1L }; ^~~ Clearly the size of the array should be known. - locally, on both mac and linux I see same results - in g++6.3, C++17 mode it compiles - in 7.3 and all versions up through 8.2 and the trunk, in C++ 17 mode it does not compile. - in clang++, it compiles. - moving the function-local class L to file-scope fixes it. - moving the array outside of the template class fixes it. - explicitly providing a size to the array declaration fixes it.
[Bug tree-optimization/80726] New: Destructor not inlined anymore (regression)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80726 Bug ID: 80726 Summary: Destructor not inlined anymore (regression) Product: gcc Version: 7.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Inlining regression with noexcept(true) destructor that could possible throw, but doesn't. This code demonstrates that in main(), the destructor for Foo is no longer inlined using g++ 7.1 -O3 (also with the 8.0 snapshot). On the 6.x series it is inlined. Source: // --- bool shouldThrow = false; struct Foo { ~Foo() { if (shouldThrow) throw "hmm"; } }; int main() { Foo f; }// --- As evidenced on godbolt.org, for g++7.1, main() has function call for destructor .LC0: .string "hmm" Foo::~Foo(): movzx eax, BYTE PTR shouldThrow[rip] testal, al jne .L7 rep ret .L7: mov edi, 8 sub rsp, 8 call__cxa_allocate_exception xor edx, edx mov QWORD PTR [rax], OFFSET FLAT:.LC0 mov esi, OFFSET FLAT:typeinfo for char const* mov rdi, rax call__cxa_throw main: sub rsp, 24 lea rdi, [rsp+15] callFoo::~Foo() xor eax, eax add rsp, 24 ret shouldThrow: .zero 1 But with 6.3 the destructor is inlined: .LC0: .string "hmm" main: movzx eax, BYTE PTR shouldThrow[rip] testal, al jne .L7 xor eax, eax ret .L7: mov edi, 8 sub rsp, 8 call__cxa_allocate_exception xor edx, edx mov QWORD PTR [rax], OFFSET FLAT:.LC0 mov esi, OFFSET FLAT:typeinfo for char const* mov rdi, rax call__cxa_throw shouldThrow: .zero 1
[Bug tree-optimization/80275] New: Poor (but valid) code generated by optimizer passing optimizer list to function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80275 Bug ID: 80275 Summary: Poor (but valid) code generated by optimizer passing optimizer list to function Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cuzdav at gmail dot com Target Milestone: --- Codegen regression from the 5.x series of g++. After 6.1, g++ produces poor code for f2() below, when it should be identical to f1(). Command line: g++ -O2 -v -std=c++14 minbad.cpp // minbad.cpp #include int g() { return 1234; } int f1() { return std::min(std::min(1, g()), 4); } int f2() { return std::min({1, g(), 4}); } The actual disassembly looks like this: g(): mov eax, 1234 ret f1(): mov eax, 1 ret f2(): lea rsi, [rsp-24] lea rax, [rsp-24] mov DWORD PTR [rsp-24], 1 mov DWORD PTR [rsp-20], 1234 mov DWORD PTR [rsp-16], 4 lea rcx, [rsi+12] lea rdx, [rax+4] mov eax, 1 .L4: add rdx, 4 cmp rdx, rcx je .L3 .L8: cmp eax, DWORD PTR [rdx] jle .L4 mov eax, DWORD PTR [rdx] add rdx, 4 cmp rdx, rcx jne .L8 .L3: rep ret Compiler Info (this is not a mac-specific problem.) - g++-6 -v -std=c++14 /tmp/minbad.cpp Using built-in specs. COLLECT_GCC=g++-6 COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/6.3.0_1/libexec/gcc/x86_64-apple-darwin16.3.0/6.3.0/lto-wrapper Target: x86_64-apple-darwin16.3.0 Configured with: ../configure --build=x86_64-apple-darwin16.3.0 --prefix=/usr/local/Cellar/gcc/6.3.0_1 --libdir=/usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-6 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --with-build-config=bootstrap-debug --disable-werror --with-pkgversion='Homebrew GCC 6.3.0_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --enable-plugin --disable-nls --enable-multilib Thread model: posix gcc version 6.3.0 (Homebrew GCC 6.3.0_1) COLLECT_GCC_OPTIONS='-v' '-std=c++14' '-mmacosx-version-min=10.12.4' '-asm_macosx_version_min=10.12' '-shared-libgcc' '-mtune=core2' /usr/local/Cellar/gcc/6.3.0_1/libexec/gcc/x86_64-apple-darwin16.3.0/6.3.0/cc1plus -quiet -v -D__DYNAMIC__ /tmp/minbad.cpp -fPIC -quiet -dumpbase minbad.cpp -mmacosx-version-min=10.12.4 -mtune=core2 -auxbase minbad -std=c++14 -version -o /var/folders/d_/97dm5hss6cq7y8jlfxh3k6xrsw2_zt/T//cc9vAOcI.s GNU C++14 (Homebrew GCC 6.3.0_1) version 6.3.0 (x86_64-apple-darwin16.3.0) compiled by GNU C version 6.3.0, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/../../../../../../x86_64-apple-darwin16.3.0/include" #include "..." search starts here: #include <...> search starts here: /usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/../../../../../../include/c++/6.3.0 /usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/../../../../../../include/c++/6.3.0/x86_64-apple-darwin16.3.0 /usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/../../../../../../include/c++/6.3.0/backward /usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/include /usr/local/include /usr/local/Cellar/gcc/6.3.0_1/include /usr/local/Cellar/gcc/6.3.0_1/lib/gcc/6/gcc/x86_64-apple-darwin16.3.0/6.3.0/include-fixed /usr/include /System/Library/Frameworks /Library/Frameworks End of search list. GNU C++14 (Homebrew GCC 6.3.0_1) version 6.3.0 (x86_64-apple-darwin16.3.0) compiled by GNU C version 6.3.0, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version 0.15 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 61c7027fd27bf9cda4c9b1dfc6e5d124 COLLECT_GCC_OPTIONS='-v' '-std=c++14' '-mmacosx-version-min=10.12.4' '-shared-libgcc' '-mtune=core2' as -arch x86_64 -v -force_cpusubtype_ALL -mmacosx-version-min=10.12 -o /var/folders/d_/97dm5hss6cq7y8jlfxh3k6xrsw2_zt/T//ccipBAqo.o /var/folders/d_/97dm5hss6cq7y8jlfxh3k6xrsw2_zt/T//cc9vAOcI.s Apple LLVM version 8.0.0 (clang-800.0.42.1) Target: x86_64-apple-darwin16.4.0 Thread model: posix InstalledD
[Bug c++/38799] New: using declaration appears to hide local declaration
When a namespace declares a function, and then "uses" another function with the same name from a different namespace, the using declaration seems to hide the function declaration. At least, when I define the function body later, the comiler complains that the function wasn't declared in the namespace. However, if I "use" the function first, and THEN declare it in the namespace, the definition of the function is accepted. (It's easer to show code than explain. See below.) Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu11' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu11) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-mtune=generic' /usr/lib/gcc/i486-linux-gnu/4.3.2/cc1plus -E -quiet -v -D_GNU_SOURCE asdf.cpp -D_FORTIFY_SOURCE=2 -mtune=generic -fpch-preprocess -o asdf.ii ignoring nonexistent directory "/usr/local/include/i486-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../i486-linux-gnu/include" ignoring nonexistent directory "/usr/include/i486-linux-gnu" #include "..." search starts here: #include <...> search starts here: /usr/include/c++/4.3 /usr/include/c++/4.3/i486-linux-gnu /usr/include/c++/4.3/backward /usr/local/include /usr/lib/gcc/i486-linux-gnu/4.3.2/include /usr/lib/gcc/i486-linux-gnu/4.3.2/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-mtune=generic' /usr/lib/gcc/i486-linux-gnu/4.3.2/cc1plus -fpreprocessed asdf.ii -quiet -dumpbase asdf.cpp -mtune=generic -auxbase asdf -version -fstack-protector -o asdf.s GNU C++ (Ubuntu 4.3.2-1ubuntu11) version 4.3.2 (i486-linux-gnu) compiled by GNU C version 4.3.2, GMP version 4.2.2, MPFR version 2.3.2. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: dc8f858cacda993dd8f70837f0d9565d asdf.cpp:15: error: void A::f(int) should have been declared inside A Source Code: void f() {} namespace A { void f(int); using ::f; } // // With the function declaration in namespace A appearing first, the // implementation below fails to compile. Switch the order (such that the // "using" appears first) and then it compiles. // // g++ /tmp/asdf.cpp // /tmp/asdf.cpp:15: error: void A::f(int) should have been declared inside A void A::f(int a) {} int main() { A::f(1); } -- Summary: using declaration appears to hide local declaration Product: gcc Version: 4.3.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: cuzdav at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38799