[Bug c/112339] ICE with clang::no_sanitize and -fsanitize=
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112339 --- Comment #3 from Niall Douglas --- Thanks for the patch. I've sent it on to the originator of the bug, if they confirm it fixes their issue to me I'll let you know.
[Bug c++/112339] New: ICE with namespaced attribute on function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112339 Bug ID: 112339 Summary: ICE with namespaced attribute on function Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- This, if compiled with trunk GCC or any recent major version of GCC: ``` [[clang::no_sanitize("bounds")]] void foo() { } ``` ... with options `-Wno-attributes=clang::no_sanitize -fsanitize=undefined` produces ICE: ``` : In function 'void foo()': :3:1: internal compiler error: in tree_to_uhwi, at tree.cc:6469 3 | } | ^ 0x266430e internal_error(char const*, ...) ???:0 0xb01c2c fancy_abort(char const*, int, char const*) ???:0 0xb97938 cp_genericize(tree_node*) ???:0 0xbe33ef finish_function(bool) ???:0 0xcebe49 c_parse_file() ???:0 0xe2ceb9 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. Compiler returned: 1 ``` Godbolt demo: https://godbolt.org/z/hs3xqeqn1
[Bug c++/111041] New: Malformed requires syntax should produce better diagnostics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111041 Bug ID: 111041 Summary: Malformed requires syntax should produce better diagnostics Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- I know this will be a minor enhancement request, however I would like this to produce more useful diagnostics: template concept test1 = requires(T x) { x.foo() -> bool;}; Currently we get "error: expected unqualified-id before 'bool'". template concept test1 = requires(T x) { x.foo() -> std::same_as;}; Currently we get "error: wrong number of template arguments (1, should be 2)". I would like something like "error: requires item needs curly brackets if requiring return type yielded from an expression". I know this will seem an inconsequential enhancement request, but I lost several hours of productivity today because I forgot the curly brackets in some deeply nested requires clauses, and the current GCC diagnostics did not help my tired old eyes see I had forgotten the curly brackets. I kept staring at it, couldn't see the issue, and it was curly brackets all along.
[Bug target/108659] Suboptimal 128 bit atomics codegen on AArch64 and x64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108659 --- Comment #10 from Niall Douglas --- (In reply to Jakub Jelinek from comment #9) > (In reply to Wilco from comment #8) > > Yes that sounds like a reasonable approach. > > I don't think so. Not all variables on which __atomic_* intrinsics are used > are actually _Atomic, the vars can be embedded in const aggregates etc. I'd have the attribute propagate to enclosing types, like over-alignment.
[Bug target/108659] Suboptimal 128 bit atomics codegen on AArch64 and x64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108659 --- Comment #7 from Niall Douglas --- (In reply to Andrew Pinski from comment #4) > (In reply to Niall Douglas from comment #3) > > You may be interested in reading https://reviews.llvm.org/D110069. It wanted > > to have LLVM generate a 128 bit AArch64 CAS for atomics. LLVM merged that > > change, it'll be in the next release. > > Using CAS for atomic load is not valid thing to do ... > Because atomic load from constant rodata needs to work. > LLVM breaks this case as they don't care about it. GCC does though. I've heard that argument before, and I've always wondered why _Atomic128 types couldn't have an attribute which applies attribute section to their static const variable incarnations to force them into r/w memory. That would also solve the LLVM issue. Said attribute is not unuseful in general actually, it would help avoid having to mess with mprotect to apply copy on write perms on regions in .rodata when you need to modify static const variable values. I don't think that the standard *guarantees* that static const variables go into read only memory, and besides, before C23 128 bit integers weren't supported anyway so one could argue as a proprietary extension (__int128) you get proprietary special casing. Niall
[Bug target/108659] Suboptimal 128 bit atomics codegen on AArch64 and x64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108659 --- Comment #3 from Niall Douglas --- > AMD has guaranteed it, but there is still VIA and Zhaoxin and while we have > some statement from the latter, I'm not sure it is enough and we don't have > anything from VIA. See PR104688 for details. I'm wondering if a compiler opt out flag like -no-msseatomic16 to turn off use of SSE for 128 bit atomics wouldn't be an idea? Given the small market share of those CPU vendors, seems a shame to hold up implementation. (Also, if you do turn it on by default and advertise that widely, I suspect those vendors will hurry up with their documentation) > FWIW, the GCC codegen for aarch64 is at https://godbolt.org/z/qvx9484nY (arm > and aarch64 are different targets). It emits a call to libatomic, which for > GCC 13 will use a lockless implementation when possible at runtime, see > g:d1288d850944f69a795e4ff444a427eba3fec11b Thanks for the catch, my mistake. It would seem the codegen is similarly inferior to the codegen from clang for both aarch64 and x64. You may be interested in reading https://reviews.llvm.org/D110069. It wanted to have LLVM generate a 128 bit AArch64 CAS for atomics. LLVM merged that change, it'll be in the next release.
[Bug c++/108659] New: Suboptimal 128 bit atomics codegen on AArch64 and x64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108659 Bug ID: 108659 Summary: Suboptimal 128 bit atomics codegen on AArch64 and x64 Product: gcc Version: 12.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- Related: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94649 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688 I got bitten by this again, latest GCC still does not emit single instruction 128 bit atomics, even when the -march is easily new enough. Here is a godbolt comparing latest MSVC, latest GCC and latest clang for the skylake-avx512 architecture, which unquestionably supports cmpxchg16b. Only clang emits the single instruction atomic: https://godbolt.org/z/EnbeeW4az I'm gathering from the issue comments and from the comments at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104688 that you're going to wait for AMD to guarantee atomicity of SSE instructions before changing the codegen here, which makes sense. However I also wanted to raise potentially suboptimal 128 bit atomic codegen by GCC for AArch64 as compared to clang: https://godbolt.org/z/oKv4o81nv GCC emits `dmb` to force a global memory fence, whereas clang does not. I think clang is in the right here, the seq_cst atomic semantics are not supposed to globally memory fence.
[Bug c++/101133] [coroutines] co_await doesn't accept a valid awaitable object if await_resume()'s return type is not a built-in type.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101133 Niall Douglas changed: What|Removed |Added CC||s_gccbugzilla at nedprod dot com --- Comment #4 from Niall Douglas --- Looks like this fix didn't get backported into the 11 branch, as the 11.3 release is also broken. https://godbolt.org/z/ojo759Md1
[Bug libstdc++/95609] span could have better layout
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95609 --- Comment #8 from Niall Douglas --- (In reply to Jonathan Wakely from comment #7) > (In reply to Niall Douglas from comment #0) > > I would assume that the ABI ship has sailed, as usual, but if libstdc++'s > > span could instead have the layout: > > > > { > > T *p; > > size_t l; > > } > > > > ... then a span would be layout-compatible with struct iovec, > > No it won't, because iovec has a void* member, and span has a byte* > member, which makes them not layout-compatible. Similarly for span char> or any other specialization of span. It is indeed a shame that the compiler won't optimise this appropriately without additional markup on the iovec structure: https://godbolt.org/z/cTo5xPxjE I can tell you that in LLFIO we simply reinterpret cast on those platforms where we know they'll be bit identical because a bunch of static asserts wouldn't have allowed compilation otherwise. Niall
[Bug target/80878] -mcx16 (enable 128 bit CAS) on x86_64 seems not to work on 7.1.0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 --- Comment #35 from Niall Douglas --- (In reply to Jonathan Wakely from comment #34) > > Perhaps I ought to open a separate issue here, as my specific problem is > > that std::atomic<__int128>::compare_exchange_weak() is not using cmpxchg16b? > > Isn't that covered by PR 94649? That issue is definitely closer to mine, but still not the same. Still, I'll relocate this report from here to there. Thanks for pointing me at it.
[Bug target/94649] 16-byte aligned atomic_compare_exchange doesn not generate cmpxcg16b on x86_64
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94649 Niall Douglas changed: What|Removed |Added CC||s_gccbugzilla at nedprod dot com --- Comment #4 from Niall Douglas --- Relocating my issue from PR 80878 to here: I got bit by this GCC regression today at work. Consider https://godbolt.org/z/M9fd7nhdh where std::atomic<__int128>::compare_exchange_weak() is called with option -march=sandybridge passed to the command line: - On GCC 6.4 and earlier, this emits lock cmpxchg16b, as you would expect. - From GCC 7 up to trunk (12?), this emits __atomic_compare_exchange_16. - On clang, this emits lock cmpxchg16b, as you would expect. This is clearly a regression. GCCs before 7 did the right thing. GCCs from 7 onwards do not. clangs with libstdc++ do do the right thing. Please mark this bug as a regression affecting all versions of GCC from 7 to trunk. --- cut --- NOTE that unlike the original PR above where the struct is a UDT, I am talking here about std::atomic<__int128>::compare_exchange_weak(). It seems weird that __int128 is treated as a UDT when the CPU is perfectly capable of hardware CAS. Common feedback from this and other PRs: 1. Changing this would break ABI Firstly, I told GCC -march=sandybridge, and we know that libatomic will choose cmpxchg16b to implement __atomic_compare_exchange_16 because cpuid for sandybridge will say cmpxchg16b is supported. So, it's the same implementation for __atomic_compare_exchange_16, nothing breaks here. 2. static const std::atomic<__int128>::load() will segfault std::atomic<__int128> could examine the macro environment (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 et al) and if only 128 bit compare and swap is available, but 128 bit atomics are not, then std::atomic<__int128> could be conditionally marked with attribute section to prevent it being stored into the read only code section. That said, I don't actually consider static const std::atomic<__int128>::load() segfaulting important enough to special case, in my opinion. 3. This was changed in GCC 7 because _Atomic is broken _Atomic is indeed broken, but I am talking about std::atomic the C++ library type here. As Mr. Wakely said in another PR: > std::atomic just calls the relevant __atomic built-in for all operations. > What the built-in does is not up to libstdc++. ... to this I would say both yes and no. __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 is not defined if the architecture relies on software emulation (libatomic) to implement 128 bit CAS. So std::atomic::compare_exchange_X() *could* examine macros for architecture and presence of __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 and inline some assembler for certain architectures as a QoI measure, which is not ABI breaking because if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 is 1, then libatomic will be choosing that same assembler in any case. Note that I refer to the CAS operation only, for load and store it's trivial to write CAS based emulations, but you could just leave those continue to call libatomic. Ultimately I probably agree that because _Atomic is broken, the compiler is not the right thing to change here. But libstdc++'s std::atomic implementation is another matter.
[Bug target/80878] -mcx16 (enable 128 bit CAS) on x86_64 seems not to work on 7.1.0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 --- Comment #33 from Niall Douglas --- (In reply to Andrew Pinski from comment #31) > > Again the problem is stuff like: > static const _Atomic __int128_t t = 2000; > > __int128_t g(void) > { > return t; > } > > DOES NOT WORK if you use CAS (or ldaxp/stlxp). I think we are talking about different things here. You are talking about calling convention. I'm talking about std::atomic<__int128>::compare_exchange_weak() i.e. that the specific member function compare_exchange_weak() is not generating cmpxchg16b if compiled with GCC, but does with clang. Re: your original point, I cannot say anything about _Atomic. However, for std::atomic<__int128>, as __int128 is not an integral type it seems reasonable to me that its specialisation tell the compiler to not store it in read only memory. Mark it with attribute section, give it a non-trivial destructor, or whatever it needs. Perhaps I ought to open a separate issue here, as my specific problem is that std::atomic<__int128>::compare_exchange_weak() is not using cmpxchg16b? Mr. Wakely your thoughts?
[Bug target/80878] -mcx16 (enable 128 bit CAS) on x86_64 seems not to work on 7.1.0
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 Niall Douglas changed: What|Removed |Added CC||s_gccbugzilla at nedprod dot com --- Comment #30 from Niall Douglas --- I got bit by this GCC regression today at work. Consider https://godbolt.org/z/M9fd7nhdh where std::atomic<__int128> is compare exchanged with -march=sandybridge: - On GCC 6.4 and earlier, this emits lock cmpxchg16b, as you would expect. - From GCC 7 up to trunk (12?), this emits __atomic_compare_exchange_16. - On clang, this emits lock cmpxchg16b, as you would expect. This is clearly a regression. GCCs before 7 did the right thing. GCCs from 7 onwards do not. clangs with libstdc++ do do the right thing. This isn't just an x64 thing, either. Consider https://godbolt.org/z/x6d5GE4o6 where GCC on ARM64 emits __atomic_compare_exchange_16, whereas clang on ARM64 emits ldaxp/stlxp, as you would expect. Please mark this bug as a regression affecting all versions of GCC from 7 to trunk, and affecting all 128 bit atomic capable architectures not just x64.
[Bug libstdc++/95609] span could have better layout
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95609 --- Comment #6 from Niall Douglas --- Cool, thanks. I believe that all three major STLs now implement struct iovec compatibility with span. That's a nice win.
[Bug c++/96485] Lambda parsing regression in GCCs 9 and onwards
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96485 --- Comment #3 from Niall Douglas --- (In reply to Jakub Jelinek from comment #2) > [[gnu::no_sanitize_undefined]] instead of the GNU __attribute__ is accepted, > but as the C++ specification requires it applies to the type not the > declaration and therefore it is ignored. Obviously the above is an extract from production code. We were using lambdas to wrap individual bits of unsafe code which trips the UB sanitiser. It would be useful to retain that ability, as having to sprinkle the code with: struct { auto operator()(auto...) const __attribute__((no_sanitize_undefined)) { } }()(...); ... seems retrograde.
[Bug c++/96485] New: Lambda parsing regression in GCCs 9 and onwards
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96485 Bug ID: 96485 Summary: Lambda parsing regression in GCCs 9 and onwards Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- As the repro at https://godbolt.org/z/Gvx75e shows, the following code compiled fine in GCCs up to and including GCC 8.3: ``` void test() { []() #if 1 __attribute__((no_sanitize_undefined)) #endif ->int { return 0; }; } ``` >From GCC 9 onwards, we get: ``` : In lambda function: :7:5: error: expected '{' before '->' token 7 | ->int { | ^~ : In function 'void test()': :7:5: error: base operand of '->' has non-pointer type 'test()::' :7:7: error: expected unqualified-id before 'int' 7 | ->int { | ^~~ Compiler returned: 1 ``` This code compiles fine in clang, incidentally, though it doesn't recognise the attribute.
[Bug c++/95609] span could have better layout
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95609 --- Comment #2 from Niall Douglas --- (In reply to Jonathan Wakely from comment #1) > (In reply to Niall Douglas from comment #0) > > I would assume that the ABI ship has sailed, as usual > > Nope. Ok, so if you did want to reuse span as any future std::file_handle::buffer_type, the following program would compile: ``` #include #include #include using buffer_type = std::span; static_assert(sizeof(buffer_type) == sizeof(struct iovec)); static_assert(std::is_trivially_copyable_v); static_assert(std::is_standard_layout_v); static_assert(std::is_layout_compatible_v); ```
[Bug c++/95609] New: span could have better layout
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95609 Bug ID: 95609 Summary: span could have better layout Product: gcc Version: 10.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- I would assume that the ABI ship has sailed, as usual, but if libstdc++'s span could instead have the layout: { T *p; size_t l; } ... then a span would be layout-compatible with struct iovec, which would save libstdc++ having to reimplement span<> with a struct iovec compatible layout for any future std::file_handle::buffer_type, if that gets standardised. I put notice of this out onto lib-ext last year requesting this of span implementations. libc++ heeded my request, MSVC have very kindly undone their initial implementation to meet the pointer + size layout plus add standard layout, so they'll be on that too going forth. In the end, this request is about as unimportant for right now as you can get. It's purely for saving you, Jonathan, avoidable work later on. Niall
[Bug c++/95233] New: Failure to compile regression in GCC 10.1 and 11 trunk with C++ 20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95233 Bug ID: 95233 Summary: Failure to compile regression in GCC 10.1 and 11 trunk with C++ 20 Product: gcc Version: c++-concepts Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- Reported originally at https://github.com/ned14/outcome/issues/225 Works on GCC 9.3 with -std=c++2a -O3 -DNDEBUG -fconcepts: https://godbolt.org/z/cRyrj- Works on GCC trunk with -std=c++17 -O3 -DNDEBUG -fconcepts: https://godbolt.org/z/T3c88K Works on clang trunk with -std=c++20 -O3 -DNDEBUG: https://godbolt.org/z/ahbRsA Fails on GCC trunk with -std=c++20 -O3 -DNDEBUG: https://godbolt.org/z/NBdpqx (It also fails with the same error on GCC 10.1. The cause is switching into C++ 20, or using a GCC newer than 9.3 which works fine in C++ 20. GCC 10 and trunk work fine in C++ 17 with Concepts forced on) In file included from /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/bits/move.h:57, from /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/bits/nested_exception.h:40, from /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/exception:148, from /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/new:41, from /opt/compiler-explorer/libs/outcome/single-header/outcome.hpp:1008, from :1: /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits: In instantiation of 'constexpr outcome_v2_cdb9621d::basic_result::basic_result(T&&, outcome_v2_cdb9621d::basic_result::value_converting_constructor_tag) [with T = const outcome_v2_cdb9621d::basic_result >&; R = std::filesystem::__cxx11::path; S = std::error_code; NoValuePolicy = outcome_v2_cdb9621d::policy::error_code_throw_as_system_error]': /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:901:30: required from 'struct std::__is_constructible_impl >, const outcome_v2_cdb9621d::basic_result >&>' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:906:12: required from 'struct std::is_constructible >, const outcome_v2_cdb9621d::basic_result >&>' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:3105:38: required from 'constexpr const bool std::is_constructible_v >, const outcome_v2_cdb9621d::basic_result >&>' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/concepts:139:30: required from 'struct std::iterator_traits > >' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/bits/fs_path.h:88:11: required by substitution of 'template using __is_path_iter_src = std::__and_::type, char>, std::is_same::type, char8_t>, std::is_same::type, wchar_t>, std::is_same::type, char16_t>, std::is_same::type, char32_t> >, std::is_base_of > [with _Iter = outcome_v2_cdb9621d::basic_result >; _Iter_traits = std::iterator_traits > >]' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/bits/fs_path.h:95:5: [ skipping 13 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] /opt/compiler-explorer/libs/outcome/single-header/outcome.hpp:4248:3: required from 'constexpr outcome_v2_cdb9621d::basic_result::basic_result(T&&, outcome_v2_cdb9621d::basic_result::value_converting_constructor_tag) [with T = const outcome_v2_cdb9621d::basic_result >&; R = std::filesystem::__cxx11::path; S = std::error_code; NoValuePolicy = outcome_v2_cdb9621d::policy::error_code_throw_as_system_error]' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:1239:4: required from 'struct std::__is_trivially_copy_constructible_impl >, true>' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:1244:12: required from 'struct std::is_trivially_copy_constructible > >' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:3131:43: required from 'constexpr const bool std::is_trivially_copy_constructible_v > >' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/optional:659:11: required from 'class std::optional > >' :10:57: required from here /opt/compiler-explorer/libs/outcome/single-header/outcome.hpp:4249:13: required by the constraints of 'template template requires outcome_v2_cdb9621d::basic_result::predicate::enable_value_converting_constructor constexpr outcome_v2_cdb9621d::basic_result::basic_result(T&&, outcome_v2_cdb9621d::basic_result::value_converting_constructor_tag)' /opt/compiler-explorer/gcc-trunk-20200512/include/c++/11.0.0/type_traits:901:30: error: the value of 'outcome_v2_cdb9621d::basic_result >::predicate::enable_
[Bug tree-optimization/95001] std::terminate() and abort() do not have __builtin_unreachable() semantics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95001 --- Comment #5 from Niall Douglas --- Just to clarify what I'm asking for: Calling a [[noreturn]] function ought to have the same effects on codegen as: ``` [[noreturn]] void theend(); ... if(a) { theend(); __builtin_unreachable(); } ``` Right now, the [[noreturn]] attribute causes the __builtin_unreachable() to be ignored, which is not helpful. I think there should be an implicit __builtin_unreachable() if a [[noreturn]] function ever would return. To be specific here: I only care about codegen. If that's not doable, can you please make a __builtin_unreachable() called after a [[noreturn]] function not be ignored please?
[Bug c++/95001] New: std::terminate() and abort() do not have __builtin_unreachable() semantics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95001 Bug ID: 95001 Summary: std::terminate() and abort() do not have __builtin_unreachable() semantics Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- Consider the codegen from https://godbolt.org/z/xhmBrL: ``` #include #include #include #include void sum(uint32_t *__restrict a, const uint32_t *__restrict b, const uint32_t *__restrict c, size_t count) { auto invoke_terminate = []{ #ifdef USE_UNREACHABLE __builtin_unreachable(); #else std::terminate(); #endif }; ifuintptr_t)a) & 15)!=0) invoke_terminate(); ifuintptr_t)b) & 15)!=0) invoke_terminate(); ifuintptr_t)c) & 15)!=0) invoke_terminate(); if((count & 15) != 0) invoke_terminate(); while(count != 0) { *a++ = *b++ + *c++; count--; } } ``` It would seem that functions marked with both [[noreturn]] and noexcept do not have the same improvements on codegen as __builtin_unreachable() has. This is despite that [[noreturn]] functions returning is explicitly required to be UB in the standard, and if they are noexcept then they cannot throw an exception either. Can noexcept functions marked [[noreturn]] please gain the same effects on codegen as __builtin_unreachable() has please?
[Bug c++/90534] New: ICE in consteval in GCCs 8.3, 8.2, 8.1, 7.3, 7.2 and 7.1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90534 Bug ID: 90534 Summary: ICE in consteval in GCCs 8.3, 8.2, 8.1, 7.3, 7.2 and 7.1 Product: gcc Version: 8.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- 8.3: https://wandbox.org/permlink/2pmM3pg8Fygh5Gi5 8.2: https://wandbox.org/permlink/RIobfNd409w0uQRT 8.1: https://wandbox.org/permlink/jVz65UsIz0jLCKKQ 7.3: https://wandbox.org/permlink/GwlNwWCsKSWdWsGF 7.2: https://wandbox.org/permlink/attxpIAIXr7JO2Zl 7.1: https://wandbox.org/permlink/1I1dWqqhMHjRQOtc GCCs 6.3, 9.1, and 10.0 trunk all work fine.
[Bug tree-optimization/90285] Poor optimised codegen for memmove() back on top of oneself
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90285 --- Comment #4 from Niall Douglas --- > "non-aliasing reinterpret cast"? Whatever that means. > > // Reinterpret bytes by copying (not UB for TC types) > memmove(temp, , sizeof(T)); > > // Put reinterpreted bytes back. This avoids the UB > // of reinterpret casting without creating new objects. > memmove(ret, temp, sizeof(T)); > > not sure I understand this. Note that mem{cpy,move} transfer the > effective type, this is a no-op. > > But well, C++ folks go wild these days... WG21 hasn't formally seen this proposal yet. I report only WG14 feedback, which is that a unidirectional reinterpreting cast where input object lifetime ends within the abstract machine would be valuable. Then the compiler can know for a fact that pointers to the input object are invalidated, and thus cannot alias pointers derived from the returned value. Under the C2x object model, the effective type of non-allocated storage propagates to the destination. As we memmove() from non-allocated storage (the stack allocated type), the effective type written to `ret` is that of `temp`. The object lifetime for input object v ends, if input object v is not stored in allocated storage. So basically these operations are greenlit for the C2x object model, which is why I presented them here, and the C committee says they are fine under the existing C abstract machine. (Yes, as reported here they are written in C++, but just as easily could be implemented as a C macro) We will find out what WG21 SG12 thinks of this proposal come July. Niall
[Bug tree-optimization/90285] Poor optimised codegen for memmove() back on top of oneself
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90285 --- Comment #2 from Niall Douglas --- To put this into a wider context, the detach and attach cast proposal passed muster earlier this week at the WG14 meeting that I am currently sitting in. The current C2x draft allows this implementation of "unidirectional reinterpret casting with no aliasing of input with output" under its "effective type" object model. (I will be taking this proposal to WG21 in July. Its paper number will be P1631 "Object detachment and attachment") The ability to specify a non-aliasing reinterpret cast is valuable. If you shrink the size of the Foo object e.g. https://godbolt.org/z/a1Fajj, GCC generates ideal codegen. So I suspect the cause of this issue is probably quite easy to fix. Niall
[Bug c++/90285] New: Poor optimised codegen for memmove() back on top of oneself
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90285 Bug ID: 90285 Summary: Poor optimised codegen for memmove() back on top of oneself Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- The following code produces poor optimised codegen on trunk GCC at the time of writing (2019-04-29): // Reinterprets a T into its array of bytes // Currently defined behaviour in C++ 20 for // trivially copyable types only. The proposal // would be that this would become defined // behaviour for most possible C++ types. template constexpr inline byte_array_ref detach_cast(T ) noexcept { byte_array_ref ret = reinterpret_cast>(v); byte temp[sizeof(T)]; // Reinterpret bytes by copying (not UB for TC types) memmove(temp, , sizeof(T)); // Put reinterpreted bytes back. This avoids the UB // of reinterpret casting without creating new objects. memmove(ret, temp, sizeof(T)); return ret; } You can see GCC's codegen here (it does two copies of 40Kb): https://godbolt.org/z/sJWSc1 You can see clang's codegen here (which is optimal, nothing is copied): https://godbolt.org/z/ou8VFT I think GCC ought to not perform memory copies for the above code sequence. Niall
[Bug libstdc++/60555] std::system_category().default_error_condition() doesn't map system errno values to std::generic_category()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60555 --- Comment #12 from Niall Douglas --- Excellent. Thanks guys!
[Bug libstdc++/60555] std::system_category().default_error_condition() doesn't map system errno values to std::generic_category()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60555 --- Comment #9 from Niall Douglas --- Transferring over from #86750: --- cut --- Got bitten by this yet again today in Boost.Outcome and the P1031 LLFIO reference implementation, so despite it being already reported at #60555, I'd like to get this fixed already. It's been four years of writing libstdc++ specific workarounds, no fix on the horizon :( This should not fail. It does on libstdc++ 9.0 trunk: ``` #include #include #include bool test() { return std::error_code(EEXIST, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` https://wandbox.org/permlink/jYpIIMlXKJ4zX3ud Jonathan says in #60555 'The standard also says "What constitutes correspondence for any given operating system is unspecified."' for mapping POSIX error codes onto generic codes. However the full text for system_category() is actually: ``` If the argument ev corresponds to a POSIX errno value posv, the function shall return error_condition(posv, generic_category()). Otherwise, the function shall return error_condition(ev, system_category()). What constitutes correspondence for any given operating system is unspecified. [ Note: The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value. Thus implementations are given latitude in determining correspondence. — end note ] ``` So what the standard means here is that on POSIX systems, system_category is by definition a superset of generic_category. All generic_category codes are guaranteed to map onto system_category if the system is POSIX compliant. The reverse is not the case, because the POSIX implementation may have proprietary error codes which have no valid mapping in generic_category. My test program above compares a system category error code of EEXIST - which is a POSIX error code - to the generic code errc::file_exists. This is supposed to return true. See the equivalent Boost.System based test example https://wandbox.org/permlink/FQ9u6DtTkw2Uno1A and it indeed works correctly. Windows, despite not being POSIX, also gets this right: ``` #include #include #include #include bool test() { return std::error_code(ERROR_FILE_EXISTS, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` Please fix libstdc++.
[Bug libstdc++/60555] std::system_category().default_error_condition() doesn't map system errno values to std::generic_category()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60555 Niall Douglas changed: What|Removed |Added CC||s_gccbugzilla at nedprod dot com --- Comment #7 from Niall Douglas --- Related #86750
[Bug libstdc++/86750] New: libstdc++ std::system_category() does not map onto std::generic_category()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86750 Bug ID: 86750 Summary: libstdc++ std::system_category() does not map onto std::generic_category() Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- Got bitten by this yet again today in Boost.Outcome and the P1031 LLFIO reference implementation, so despite it being already reported at #60555, I'd like to get this fixed already. It's been four years of writing libstdc++ specific workarounds, no fix on the horizon :( This should not fail. It does on libstdc++ 9.0 trunk: ``` #include #include #include bool test() { return std::error_code(EEXIST, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` https://wandbox.org/permlink/jYpIIMlXKJ4zX3ud Jonathan says in #60555 'The standard also says "What constitutes correspondence for any given operating system is unspecified."' for mapping POSIX error codes onto generic codes. However the full text for system_category() is actually: ``` If the argument ev corresponds to a POSIX errno value posv, the function shall return error_condition(posv, generic_category()). Otherwise, the function shall return error_condition(ev, system_category()). What constitutes correspondence for any given operating system is unspecified. [ Note: The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value. Thus implementations are given latitude in determining correspondence. — end note ] ``` So what the standard means here is that on POSIX systems, system_category is by definition a superset of generic_category. All generic_category codes are guaranteed to map onto system_category if the system is POSIX compliant. The reverse is not the case, because the POSIX implementation may have proprietary error codes which have no valid mapping in generic_category. My test program above compares a system category error code of EEXIST - which is a POSIX error code - to the generic code errc::file_exists. This is supposed to return true. See the equivalent Boost.System based test example https://wandbox.org/permlink/FQ9u6DtTkw2Uno1A and it indeed works correctly. Windows, despite not being POSIX, also gets this right: ``` #include #include #include #include bool test() { return std::error_code(ERROR_FILE_EXISTS, std::system_category()) == std::errc::file_exists; } int main() { std::cout << test() << std::endl; assert(test() == true); return 0; } ``` Please fix libstdc++.
[Bug c++/86590] Codegen is poor when passing std::string by value with _GLIBCXX_EXTERN_TEMPLATE undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590 Niall Douglas changed: What|Removed |Added Summary|Codegen regression when |Codegen is poor when |passing std::string by |passing std::string by |value in C++ 17 and C++ 20 |value with ||_GLIBCXX_EXTERN_TEMPLATE ||undefined --- Comment #4 from Niall Douglas --- Title made more accurate as per Jonathan's request
[Bug c++/86590] Codegen regression when passing std::string by value in C++ 17 and C++ 20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590 --- Comment #1 from Niall Douglas --- Quoting from bug 86573 regarding this bug: > The real difference in -std=c++17 is _GLIBCXX_EXTERN_TEMPLATE. With > -std=c++14, we have many extern templates which the compiler almost never > inlines. This leaves existing inline functions small enough to be inlined in > main (once it is renamed). With -std=c++17, extern templates are gone, > everything is inlined, and the function that used to be small enough to be > inlined is now too big (several smaller functions have been inlined into it > first). Without inlining, the compiler cannot notice all the simplifications. > (this is in large part guesswork, feel free to verify) > > If someone wants to improve it, I would look into the inliner heuristics, > but that's probably going to be hard.
[Bug tree-optimization/86573] Failure to optimise passing simple values to inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86573 --- Comment #8 from Niall Douglas --- Added revised bug to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590
[Bug c++/86590] New: Codegen regression when passing std::string by value in C++ 17 and C++ 20
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590 Bug ID: 86590 Summary: Codegen regression when passing std::string by value in C++ 17 and C++ 20 Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- If compiled as C++ 14: #include inline size_t calc(std::string a, std::string b) { return a.size() + b.size(); } int foo() { std::string a = "Hello world", b = "Goodbye world"; return calc(a, b); } ...one gets: foo(): mov eax, 24 ret But if compiled as C++ 17 or later, one gets lots of spew: https://godbolt.org/g/jCzpAS Using std::move() generates the right result in C++ 17 or later: https://godbolt.org/g/tHXpyy. I think it should also work by value, like it did in C++ 11 and C++ 14.
[Bug tree-optimization/86573] Failure to optimise passing simple values to inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86573 --- Comment #5 from Niall Douglas --- Thanks for the rapid feedback. Very very interesting that -std=c++17 causes spew for the copy case https://godbolt.org/g/Xnrgg2, yet -std=c++14 or -std=c++11 does not. Is the -std=c++17 case worth opening a new bug report for?
[Bug c++/86573] New: Failure to optimise passing simple values to inlined function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86573 Bug ID: 86573 Summary: Failure to optimise passing simple values to inlined function Product: gcc Version: tree-ssa Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- #include inline size_t calc(std::string a, std::string b) { return a.size() + b.size(); } int main() { std::string a = "Hello world", b = "Goodbye world"; return calc(std::move(a), std::move(b)); } This should generate: main: # @main mov eax, 24 ret Like clang does. See https://godbolt.org/g/EAggKH. But it instead generates this spew with gcc trunk: https://godbolt.org/g/3LmfTc Also it should generate the above return of 24 if passing by value. clang currently fails that, I have reported a bug to them about it.
[Bug c++/79118] [7 Regression] internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2258
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79118 --- Comment #8 from Niall Douglas --- (In reply to Marek Polacek from comment #7) > I'm giving up; there's just too much C++. Thanks for looking into it. You should know that the above code works without issue on clang and VS2017 (with C++ 14 constexpr enabled too!). In your reduced test case I don't think you're packing the storage and the type of storage into a single byte. That's what the original does, and appears to be the cause of the ICE on GCC: use of bitfields in constexpr. It certainly should not be the case that the constexpr is accessing storage not initialised by constexpr e.g. a bit 8 when valid bits are 0 ... 7. Niall
[Bug c++/79118] New: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2258
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79118 Bug ID: 79118 Summary: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2258 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: s_gccbugzilla at nedprod dot com Target Milestone: --- Created attachment 40531 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40531=edit preprocessed source ned@KATE:/mnt/g/boostish/outcome/build_posix$ g++ --version g++ (Ubuntu 6.2.0-3ubuntu11~14.04) 6.2.0 20160901 ned@KATE:/mnt/g/boostish/outcome/build_posix$ /usr/bin/c++ -DBOOST_OUTCOME_ENABLE_ADVANCED=1 -isystem /mnt/g/boostish/.use_boostish_siblings -fPIE -fstack-protector-strong -Wall -Wextra -std=gnu++14 -o CMakeFiles/outcome_hl--unittests.dir/test/unittests.cpp.o -c /mnt/g/boostish/outcome/test/unittests.cpp --save-temps /mnt/g/boostish/outcome/test/unittests.cpp: In function ‘void boostlite_auto_test_suite0::boostlite_auto_test_case5()’: /mnt/g/boostish/outcome/test/unittests.cpp:497:25: in constexpr expansion of ‘boost::outcome::_1_0_std_std_f724e3c2::basic_monad<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >(false).boost::outcome::_1_0_std_std_f724e3c2::basic_monad<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >::.boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy_base<monad_storage, value_type, error_type, exception_type>::get<boost::outcome::_1_0_std_std_f724e3c2::detail::basic_monad_storage<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >, bool, void, void>()’ /mnt/g/boostish/outcome/test/../include/boost/outcome/v1.0/detail/monad_policy.ipp:137:21: in constexpr expansion of boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy_base<monad_storage, value_type, error_type, exception_type>::_pre_get_value<boost::outcome::_1_0_std_std_f724e3c2::detail::basic_monad_storage<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >, bool, void, void>()’ /mnt/g/boostish/outcome/test/../include/boost/outcome/v1.0/detail/monad_policy.ipp:66:34: in constexpr expansion of ‘((const boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy_base<boost::outcome::_1_0_std_std_f724e3c2::detail::basic_monad_storage<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >, bool, void, void>*)this)->boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy_base<boost::outcome::_1_0_std_std_f724e3c2::detail::basic_monad_storage<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >, bool, void, void>::.boost::outcome::_1_0_std_std_f724e3c2::detail::basic_monad_storage<_implementation_policy>::is_ready<boost::outcome::_1_0_std_std_f724e3c2::detail::option_policy >()’ /mnt/g/boostish/outcome/test/unittests.cpp:497:31: internal compiler error: in cxx_eval_bit_field_ref, at cp/constexpr.c:2258 BOOST_CHECK(option(false).get() == false); ^ Please submit a full bug report, with preprocessed source if appropriate. See for instructions.
[Bug libstdc++/53673] Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 --- Comment #10 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-18 10:01:19 UTC --- (In reply to comment #9) I'm ambivalent. Ok then. Well, thanks for all your help and very useful input. As we have something now which is very close to a code patch, I suppose we leave it for now and see how the issue tracks into the future. I encourage anyone supporting the addition of this feature, or otherwise having C++11 and C++98 interop problems to subscribe here and to indicate their support. If you don't indicate support it won't get added. If we get enough support I'm happy to write the documentation patch. Not so the code patch - too much paperwork as I learned the hard way last time with my -fvisibility=X patch :) Thanks, Niall
[Bug libstdc++/53673] Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 Niall Douglas s_gccbugzilla at nedprod dot com changed: What|Removed |Added Component|c++ |libstdc++ --- Comment #8 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-16 14:19:18 UTC --- (In reply to comment #7) (In reply to comment #6) Technically, you could add it to the top of stddef.h or whatever is a guaranteed included library header: libstdc++'s bits/c++config.h would be the right place and as part of the std lib the symbol should probably be named __glibcxx_blah I think you'd also need an actual definition or nothing will be emitted for the declaration alone: #if __GXX_WEAK__ #if __cplusplus == 201103L extern C void __glibcxx_std_cxx11() __attribute__((weak)); extern C void __glibcxx_std_cxx11() { } #else if __cplusplus == 199711L extern C void __glibcxx_std_cxx98() __attribute__((weak)); extern C void __glibcxx_std_cxx98() { } #else #warning Unknown C++ standard version #endif #endif Do I take this as your support of the above patch to bits/c++config.h? Or do you still feel it unnecessary? Niall
[Bug c++/53673] Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 --- Comment #3 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-15 15:13:37 UTC --- (In reply to comment #1) There's no point differentiating the gnu variants, they don't have any ABI impact. They don't have any ABI impact that we know of at the present time in this present generation of GCCs. As a debug aid that's likely to be there from now on and forever, who's to say about the future. Better to cover all bases now I'd say, just in case. This could (and probably should) be done in the library because the output of G++ is ABI compatible, it's only standard library components that are not. There are no shortage of third party libraries which enable special new stuff when compiled with GNU additions turned on. Also, the ISO C++ standard is quite clear that ABI between C++03 and C++11 compiled code is not guaranteed in the case where C++11 libraries/shared objects are linked into a C++03 compiled program. Indeed, really an error ought to be thrown if this happens for safety's sake, a warning as a minimum. Niall
[Bug c++/53673] Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 --- Comment #4 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-15 15:23:21 UTC --- (In reply to comment #2) you can use -frecord-gcc-switches to detect mixed objects in linked library. Indeed, one could grok the .text section this adds, parse the command line and determine the build settings. However, this is why that would be a poorer choice: 1. Last time I looked record-gcc-switches only works with ELF outputs. 2. You can't debug prebuilt system provided shared objects as these won't have been compiled with -frecord-gcc-switches. 3. Parsing an ELF .text section is hard from within programs as compared to dlsym(dll, __gplusplus_std_cplusplus11) 4. Automated build config tools already have machinery for seeing if some symbol is exported by some binary object. That lets the proposed system fit into said existing machinery easily, whereas groking .text sections is considerably harder. For example, an automated build config might adapt how it builds itself according to how system provided shared libraries were built. 5. Future GCC command line switches may change. Indeed, one day -std will default to c++11, not c++98. When that happens your .text section parsing will break. The proposed system doesn't have that problem and is more futureproof. Niall
[Bug c++/53673] Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 --- Comment #6 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-15 16:53:01 UTC --- (In reply to comment #5) They don't have any ABI impact that we know of at the present time in this present generation of GCCs. As a debug aid that's likely to be there from now on and forever, who's to say about the future. The GCC maintainers are to say. It's safer to fail safe. And no maintainer is omniscient. Better to cover all bases now I'd say, just in case. There's no point adding (and maintaining) yet another feature to handle hypothetical differences which *by*design* should not happen. There's the ideal world and there's the real world. This is a very likely ongoing real world problem whose fix requires perhaps five lines of new code - hardly a big new feature requiring umpteen lines of code. I'd write the patch myself except I'd put those five lines in the wrong place because GCC's code base is so monolithic. Technically, you could add it to the top of stddef.h or whatever is a guaranteed included library header: #if defined(__cpluscplus) and __cplusplus==201103L extern C void __gplusplus_std_cplusplus11() __attribute__ ((weak)); #elif defined(__cpluscplus) and __cplusplus==199711L extern C void __gplusplus_std_cplusplus97() __attribute__ ((weak)); #elif ... #else #error Unknown C++ variant, cannot set magic symbol #endif ... assuming that compiles which I can't test on this laptop. Far more relevant than c++11 vs gnu++11 is -fabi-version=n, which your scheme doesn't cover. ABI is a GCC issue :). I'd certainly recommend it for that too. You may need to bump ABI if needed to solve C++11 and C++03 interop and a way for checking for that would also be useful. There are no shortage of third party libraries which enable special new stuff when compiled with GNU additions turned on. Not GCC's problem, and no different to libraries which enable new things when -fno-rtti or -fno-exceptions is used Look, it's a debug aid, and if GCC offers special extra features then it's GCC's problem if libraries use them. In the future GCC is going to see lots of C++11 bugs submitted. You're going to ask the question are you *really* sure you compiled everything with C++11?. Right now they'll say yes, but they may well be wrong. This debug aid is as much for your future sanity as anything. Also, the ISO C++ standard is quite clear that ABI between C++03 and C++11 compiled code is not guaranteed in the case where C++11 libraries/shared objects are linked into a C++03 compiled program. Indeed, really an error ought to be thrown if this happens for safety's sake, a warning as a minimum. [citation needed] ;) :) ... I don't suppose you'd take my word as ISO SC22 convenor for Ireland would you? ;) No, it's fair enough, I only know that from watching the discussions on ISO and I have no idea if it's actually written in the final published standard. It is however written in Nicolai Josuttis' updated C++11 The C++ standard library in the chapter on C++11 core language changes. And if you think it through, there has to be in practice ABI breakage in 03 ABIs because no one could have anticipated during their design of what 11 would require [1]. [1]: This may not apply to GCC as it revised its ABI quite recently, and I'm sure its designers took into account likely future 11 requirements. The standard says nothing about libraries/shared objects I know only too well. I have an early draft for shared library implementation on my desk for WG14. It's too ambitious for WG14 as it explicitly adds interop for non-C languages. It's entirely possible to use G++ to build 100% ABI compatible applications using a mixture of -std=c++98 and -std=c++11 objects, if you don't use the parts of the standard library that are incompatible. A mandatory or warning would cause problems for anyone doing that. Sure. Any C++ implementation may choose to go beyond what is needed. However, I personally can see lots of potential for monsters to lurk there. I think the proposed debug aid will save a lot of time for a lot of people in the long run, and for the cost of implementation and almost nil cost of maintenance I'd just go ahead and implement it if I were ye. Which I'm not, so all I can do is try to persuade and advocate. Niall
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #11 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-14 11:49:01 UTC --- (In reply to comment #9) maybe related: https://svn.boost.org/trac/boost/ticket/6919 Had similar crash issue. Though in my case (which may well be different from the OP) rebuilding boost with new flags fixed it. If OP posts crashtest.cpp source, I'll be happy to run it through. Here's how I rebuilt the f17 rpms: # cat ~/.rpmrc optflags: x86_64 -O2 -g -std=c++11 -fno-strict-aliasing # rpmbuild --rebuild boost-1.48.0-11.fc17.src.rpm With respect to the Boost bugtracker, if this is an aliasing bug then it's a bug in Boost. Strict aliasing isn't an optional part of the ISO standard. They shouldn't have closed that issue because -fno-strict-aliasing fixes the bug on 4.7. Equally, it could still be that GCC 4.7 is performing an unsafe strict aliasing optimisation which it didn't do in 4.6. Weirdly the Boost bugtracker thinks the bug fixed in GCC 4.7, whereas this bug is about a 4.7 regression from 4.6. Niall
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #15 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-14 13:24:58 UTC --- Agreed, but it is highly unlikely to happen anytime soon unless a new sponsor turns up. BPL needs a fair bit of post-bitrot work as it is. Niall (In reply to comment #12) Maybe someone should look at fixing these warnings in Boost.Python, or ensure -fno-strict-aliasing is used g++ -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall -m64 -pthread -fPIC -DBOOST_ALL_NO_LIB=1 -DBOOST_PYTHON_SOURCE -DNDEBUG -I. -I/apps/infra/3rd-party/gcc-4.4-64/python-2.6.5/include/python2.6 -c -o bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/enum.o libs/python/src/object/enum.cpp libs/python/src/object/enum.cpp: In function 'boost::python::api::object boost::python::objects::{anonymous}::new_enum_type(const char*, const char*)': libs/python/src/object/enum.cpp:150:11: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] g++ -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall -m64 -pthread -fPIC -DBOOST_ALL_NO_LIB=1 -DBOOST_PYTHON_SOURCE -DNDEBUG -I. -I/apps/infra/3rd-party/gcc-4.4-64/python-2.6.5/include/python2.6 -c -o bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/class.o libs/python/src/object/class.cpp libs/python/src/object/class.cpp: In function 'PyObject* boost::python::objects::static_data()': libs/python/src/object/class.cpp:211:11: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] libs/python/src/object/class.cpp: In function 'boost::python::type_handle boost::python::objects::class_metatype()': libs/python/src/object/class.cpp:319:11: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] libs/python/src/object/class.cpp: In function 'boost::python::type_handle boost::python::objects::class_type()': libs/python/src/object/class.cpp:473:11: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] gcc.compile.c++ bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/life_support.o g++ -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall -m64 -pthread -fPIC -DBOOST_ALL_NO_LIB=1 -DBOOST_PYTHON_SOURCE -DNDEBUG -I. -I/apps/infra/3rd-party/gcc-4.4-64/python-2.6.5/include/python2.6 -c -o bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/life_support.o libs/python/src/object/life_support.cpp libs/python/src/object/life_support.cpp: In function 'PyObject* boost::python::objects::make_nurse_and_patient(PyObject*, PyObject*)': libs/python/src/object/life_support.cpp:94:9: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] libs/python/src/object/life_support.cpp:96:9: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] gcc.compile.c++ bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/function.o g++ -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall -m64 -pthread -fPIC -DBOOST_ALL_NO_LIB=1 -DBOOST_PYTHON_SOURCE -DNDEBUG -I. -I/apps/infra/3rd-party/gcc-4.4-64/python-2.6.5/include/python2.6 -c -o bin.v2/libs/python/build/gcc-4.7.0/release/threading-multi/object/function.o libs/python/src/object/function.cpp libs/python/src/object/function.cpp: In constructor 'boost::python::objects::function::function(const boost::python::objects::py_function, const boost::python::detail::keyword*, unsigned int)': libs/python/src/object/function.cpp:108:9: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] libs/python/src/object/function.cpp:110:9: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #18 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-14 15:15:30 UTC --- (In reply to comment #17) (In reply to comment #16) I think I built it correctly with std=c++11, but is there a way to verify this properly in the built library? crashtest.cpp doesn't crash ;) I think he means something like a magic weak symbol emitted to indicate a binary was built with C++11. If there isn't such a magic symbol yet, there should be. Niall
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #22 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-14 16:16:19 UTC --- (In reply to comment #20) That wouldn't help if you built one object with -std=c++11 and another with -std=c++98 and linked them both into the same .so, you'd have the symbol, but wouldn't have built everything with -std=c++11 Anyway, it's the same bug, it happens when passing a std::pair between c++11 code and c++98 code and if you make the std::pair move-ctor trivial then there's no crash. You miss my point: If built under C++03, a magic symbol __gplusplus_cplusplus_03 might be emitted; if built under C++11, a magic symbol __gplusplus_cplusplus_11 might be emitted. You can then tell if mixed build object files have been combined - and you can also tell if a given binary is pure. ld can then be patched to emit a warning if both symbols appear in the same binary. After all, mixing C++03 and C++11 is likely bad for your health forever into the future. Indeed, if it becomes a fatal problem for a lot of end users, gcc may need to mangle things specially for C++11 versus C++03 code for code so affected in order to prevent bad linking. The loss of std::pair interop between C++03 and C++11 in my mind is pretty fatal for a lot of end users. I can submit a wishlist issue for GCC for the above if it doesn't already exist? Niall
[Bug c++/53673] New: Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53673 Bug #: 53673 Summary: Add magic weak symbol to indicate C++ standard setting (C++03, C++11 etc) to help debug ABI problems Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: s_gccbugzi...@nedprod.com Can we have a magic weak symbol output by G++ into compilands saying what -std setting was used? For example: No -std outputs __gplusplus_std_cpluscplus98 -std=c++03 outputs __gplusplus_std_cplusplus03 -std=gnu++03 outputs __gplusplus_std_gnu03 -std=c++11 outputs __gplusplus_std_cplusplus11 -std=gnu++11 outputs __gplusplus_std_gnu11 ... and so on ... Why? Because right now it's too easy to accidentally link object files compiled with 98 with those compiled with 11 and not then know why things spontaneously fail: http://gcc.gnu.org/ml/gcc/2012-06/msg00201.html http://gcc.gnu.org/wiki/Cxx11AbiCompatibility If __gplusplus_std_cpluscplus98 and __gplusplus_std_cplusplus11 both turn up in a shared object or executable, then we know we have combined 98 and 11 built code. Indeed, a future ld could warn if this happens. Niall
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #25 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-06-14 16:37:15 UTC --- (In reply to comment #24) (In reply to comment #22) I can submit a wishlist issue for GCC for the above if it doesn't already exist? Sure. Added as #53673. Niall
[Bug c++/53455] g++ builds segfault in boost::python
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 Niall Douglas s_gccbugzilla at nedprod dot com changed: What|Removed |Added CC||s_gccbugzilla at nedprod ||dot com --- Comment #3 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-05-22 18:34:39 UTC --- CC-ing
[Bug c++/53455] boost::python segfault
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53455 --- Comment #5 from Niall Douglas s_gccbugzilla at nedprod dot com 2012-05-22 19:51:04 UTC --- Link to the c++-sig discussion thread: http://mail.python.org/pipermail/cplusplus-sig/2012-May/016581.html For the purposes of assigning tags, this bug is C++11 mode only, GCC 4.7.x only, affects code doing virtual inheritance.
[Bug c++/36461] [c++0x] Exception throws don't use rvalue reference constructors
--- Comment #1 from s_gccbugzilla at nedprod dot com 2008-06-08 17:07 --- Created an attachment (id=15732) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15732action=view) Test Case -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36461
[Bug c++/36461] [c++0x] Exception throws don't use rvalue reference constructors
--- Comment #2 from s_gccbugzilla at nedprod dot com 2008-06-08 17:19 --- This problem actually seems to be one of subclassing: child class rvalue constructors invoke base class lvalue constructors!!! I have attached an example. As is, it compiles and works. If however you throw a Thing2 instead of Thing, you get: [EMAIL PROTECTED]:~/Tornado/Tn/TClient/TnFOX$ g++ -o TestCPP0x -std=c++0x TestCPP0x.cpp TestCPP0x.cpp: In copy constructor Thing2::Thing2(const Thing2): TestCPP0x.cpp:9: error: Thing::Thing(const Thing) is private TestCPP0x.cpp:12: error: within this context TestCPP0x.cpp: In function Thing2 f(bool): TestCPP0x.cpp:23: note: synthesized method Thing2::Thing2(const Thing2) first required here This is despite that Thing2 defines no constructors at all apart from the default. Ok, so I tried manually disabling the lvalue constructor in Thing2 like this: class Thing2 : public Thing { public: Thing2() { } Thing2(Thing2 o) : Thing(o) { } private: Thing2(const Thing2); }; ... and now I get: [EMAIL PROTECTED]:~/Tornado/Tn/TClient/TnFOX$ g++ -o TestCPP0x -std=c++0x TestCPP0x.cpp TestCPP0x.cpp: In constructor Thing2::Thing2(Thing2): TestCPP0x.cpp:9: error: Thing::Thing(const Thing) is private TestCPP0x.cpp:15: error: within this context In other words, the rvalue constructor in Thing2 is trying to invoke the lvalue constructor in Thing!!! This is surely utterly wrong unless Thing has no rvalue constructor. Our Thing class has the lvalue disabled and rvalue enabled, so GCC is surely making a big mistake. This is the shortest example of what went wrong with my exception throwing problem. There's an additional problem. If I don't specify any constructors at all for Thing2 apart the default constructor, GCC /should/ generate synthesised ones based on what's available in the parent classes. Unfortunately, GCC is ignoring that the lvalue constructor has been disabled and tries to generate a lvalue constructor anyway which is obviously doomed to failure. GCC 3.4.1 just went into the Ubuntu repositories, so I'll try that next. Niall -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36461
[Bug c++/36461] [c++0x] Exception throws don't use rvalue reference constructors
--- Comment #3 from s_gccbugzilla at nedprod dot com 2008-06-08 17:19 --- Created an attachment (id=15733) -- (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15733action=view) Failing -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36461
[Bug c++/36461] New: [C++-0X] Exception throws don't use rvalue reference constructors
I will firstly admit that I don't know if exception throws /should/ use rvalue reference constructors - the proposed working at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html doesn't mention it, but one certainly would have thought it would. In my project I have a destructively copied exception class. Currently, the standard copy constructor simply moves a pointer to an internal state object which contains a large amount of debug data eg; stack backtraces. Without this the debug build can be very slow and stack usage dangerous (there is a bug in MSVC where copy construction of an exception during a throw doesn't release previous copies which causes quick exhaustion of the stack). I have tried to add an rvalue reference constructor under the idea that with -std=c++0x it would implement move semantics more legally than at current. Unfortunately, g++ really wants to use the copy constructor for a thrown exception and won't accept a rvalue copy constructor. Is this intentional? -- Summary: [C++-0X] Exception throws don't use rvalue reference constructors Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: s_gccbugzilla at nedprod dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36461
[Bug c++/29763] New: Non-ISO template qualifiers
Don't suppose you can deprecate this non-ISO C++ standard usage of the following proprietary G++ extensions: extern template int max (int, int); inline template class Fooint; static template class Fooint; ... as summarised at http://www.dis.com/gnu/gcc/Template-Instantiation.html. The problem with these is that they tempt some programmers to use them (a) without really understanding what they are doing as documentation is somewhat light on these extensions (b) in the mistaken belief it is standard C++, not a proprietary G++ extension (c) that non-G++ compilers ignore it, which they may or may not do in a predictable fashion. As an example, various versions of MSVC as well as other compilers can throw some odd errors. I have no problem with these being replaced with something like say: __attribute__((template_extern)) template int max (int, int); __attribute__((template_inline)) template class Fooint; __attribute__((template_static)) template class Fooint; This then does not give the illusion that these misuses of extern, inline and static with template declarations is proper C++. Cheers, Niall -- Summary: Non-ISO template qualifiers Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: s_gccbugzilla at nedprod dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29763
[Bug c++/29757] New: Non-ISO template qualifiers
Don't suppose you can deprecate this non-ISO C++ standard usage of the following proprietary G++ extensions: extern template int max (int, int); inline template class Fooint; static template class Fooint; ... as summarised at http://www.dis.com/gnu/gcc/Template-Instantiation.html. The problem with these is that they tempt some programmers to use them (a) without really understanding what they are doing as documentation is somewhat light on these extensions (b) in the mistaken belief it is standard C++, not a proprietary G++ extension (c) that non-G++ compilers ignore it, which they may or may not do in a predictable fashion. As an example, various versions of MSVC as well as other compilers can throw some odd errors. I have no problem with these being replaced with something like say: __attribute__((template_extern)) template int max (int, int); __attribute__((template_inline)) template class Fooint; __attribute__((template_static)) template class Fooint; This then does not give the illusion that these misuses of extern, inline and static with template declarations is proper C++. Cheers, Niall -- Summary: Non-ISO template qualifiers Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: s_gccbugzilla at nedprod dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29757
[Bug c++/23628] Typeinfo comparison code easily breaks shared libs
--- Additional Comments From s_gccbugzilla at nedprod dot com 2005-09-01 10:42 --- Vladimir Prus Wrote: It's is mess, but I hope that we don't just agree on *that*. The situation is that the whole -fvisibility thing does not work reliably for C++ dynamic libraries which is rather bad. I wouldn't go /that/ far - if you know what you're doing, it's completely reliable. The problem is that it involves a lot of knowledge of ELF internals which most people using GCC don't have and IMHO, shouldn't need to have. The problem I see here is that Andrew knows the internals of GCC extremely well, and so to him IMHO he can't see why users are having such a problem. You might be formally right, but what about practical consequences? Unless *all* libraries I use have push/pops in *every single header*, using -fvisibility for my own library can result in crash. So for a large application you'd need to get authors of all used libraries to fix them! Note that even libstdc++ does not have this at the moment. This makes -fvisibility just useless. One of our overriding goals when making this patch was to AVOID patching any existing library headers! See PR 9283 and PR 15000. The way I see it is that GCC's current behaviour interferes with the ODR. If you define a type in one compilation unit and then again in another, and you compare the two, currently it works if those compilation units are in the same shared object but it fails if they are in different shared objects. This to me is confusing at best, and causes hard-to-find bugs at worst. It also isn't compatible with MSVC's behaviour which was also one of the original goals of the patch - to allow existing MSVC DLL macro support to be reused in GCC. Now I raised this originally back in the day, but I was told that the performance penalty of memcmp()-ing symbols was too much - even though MSVC does just this and I haven't seen many complaints about its typeinfo performance. However, I am very certain that so long as it remains this way, you're just going to get more and more people complaining in here. So how about this - how about we get GCC to emit a special linkonce symbol called say __gcc_linkonce_nondefaultvisibility if a compilation unit uses non- default visibility? And if that symbol is present, the GCC runtime uses memcmp() instead of address comparison during typeinfo work - if I remember, there's about two or three places where code would need altering. This solves the problem, and keeps everyone happy. If people agree, I could contribute a little to this patch. Cheers, Niall -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23628
[Bug c++/18479] New: __attribute__ ((visibility(default))) in C causes internal compiler error
Using GCC v4.0_20041107 on FreeBSD v5.3: struct __attribute__ ((visibility(default))) Foo { int foo; }; int main(void) { Foo foo; return 0; } If compiled as a C++ file, all is fine. If compiled as C you get: internal compiler error: tree check: expected class 'declaration', have 'exceptional' (identifier_node) in handle_visibility_attribute, at c-common.c: 4648 Please submit a full bug report, with preprocessed source if appropriate. See URL:http://gcc.gnu.org/bugs.html for instructions. I think it's perfectly valid for C code to mark structures as having visibility though it means nothing useful (so it could simply be ignored). It certainly shouldn't generate an internal compiler error. Cheers, Niall -- Summary: __attribute__ ((visibility(default))) in C causes internal compiler error Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: s_gccbugzilla at nedprod dot com CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18479
[Bug c/18479] __attribute__ ((visibility(default))) in C causes internal compiler error
-- What|Removed |Added Component|c++ |c http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18479