[Bug target/113149] Function multiversioning prefers arch=x86-64-v3 to actual processors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113149 --- Comment #1 from Ed Catmur --- >From b4ca8bf55100eddeaa14a52f1bc8e73fac565d83 Mon Sep 17 00:00:00 2001 From: Ed Catmur Date: Tue, 26 Dec 2023 11:46:26 -0600 Subject: [PATCH] Swap P_PROC_AVX2 with P_X86_64_V3, etc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113149 Any processor with feature priority P_PROC_AVX2 necessarily supports at least all of the x86-64-v3 psABI level, but almost certainly supports more instructions; e.g. Haswell supports pclmul and rdrnd. So if there are multiversion targets for arch=x86-64-v3 and e.g. arch=haswell, the target for the specific processor should be preferred. Similarly, swap P_PROC_AVX512F with P_X86_64_V4. --- gcc/common/config/i386/i386-cpuinfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 38fa7650de28f..593d71626e440 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -141,11 +141,11 @@ enum feature_priority P_PROC_FMA, P_BMI2, P_AVX2, - P_PROC_AVX2, P_X86_64_V3, + P_PROC_AVX2, P_AVX512F, - P_PROC_AVX512F, P_X86_64_V4, + P_PROC_AVX512F, P_PROC_DYNAMIC };
[Bug target/113149] New: Function multiversioning prefers arch=x86-64-v3 to actual processors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113149 Bug ID: 113149 Summary: Function multiversioning prefers arch=x86-64-v3 to actual processors Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since #101696, we can write __attribute__ ((target ("arch=x86-64-v3"))) char const* f() { return "x86-64-v3"; } But x86-64-v3 is preferred to any of the processors that support this feature set, which seems backwards - even Haswell supports pclmul and rdrnd, which aren't in x86-64-v3. It feels that it should be OK to swap the ordering of P_PROC_AVX2 with P_X86_64_V3, and P_PROC_AVX512F with P_X86_64_V4, in enum feature_priority.
[Bug c++/112354] New: mismatched types 'B' and 'B&' for generic lambda noexcept-specifier referencing enclosing function parameter
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112354 Bug ID: 112354 Summary: mismatched types 'B' and 'B&' for generic lambda noexcept-specifier referencing enclosing function parameter Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 4.9.0, template struct B { B(); B(B const&); }; template void g(B, int); auto f(B x) { return [](auto y) noexcept(noexcept(g(x, y))) { return 1; }; } int i = f({})(0); fails with: : In instantiation of 'f(B):: [with auto:1 = int]': :12:14: required from here 12 | int i = f({})(0); | ~^~~ :8:42: error: no matching function for call to 'g(B&&, int&)' 8 | return [](auto y) noexcept(noexcept(g(x, y))) { | ~^~ :6:24: note: candidate: 'template void g(B, int)' 6 | template void g(B, int); |^ :6:24: note: template argument deduction/substitution failed: :8:42: note: mismatched types 'B' and 'B&' 8 | return [](auto y) noexcept(noexcept(g(x, y))) { | ~^~
[Bug c++/112341] New: error: insufficient contextual information to determine type on co_await result in function template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112341 Bug ID: 112341 Summary: error: insufficient contextual information to determine type on co_await result in function template Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include struct A { int j; }; struct B { bool await_ready(); bool await_suspend(std::coroutine_handle<>); A await_resume(); }; struct C { struct promise_type { std::suspend_always initial_suspend(); std::suspend_always final_suspend() noexcept; void unhandled_exception(); C get_return_object(); void return_void(); }; }; C f(auto) { (co_await B()).j; } void g() { f(0); } : In function 'C f(auto:1)': :17:14: error: insufficient contextual information to determine type 17 | C f(auto) { (co_await B()).j; } | ~^ Writing 'auto&& a = co_await B(); a.j;' or even 'auto(co_await B()).j' accepts.
[Bug c++/111944] Spurious '' is used uninitialized in Boost.Variant2 (-Wuninitialized -Og)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111944 --- Comment #1 from Ed Catmur --- Correction, it does affect sanitizers (-O2 -fsanitize=address) as well as -Og.
[Bug c++/111944] New: Spurious '' is used uninitialized in Boost.Variant2 (-Wuninitialized -Og)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111944 Bug ID: 111944 Summary: Spurious '' is used uninitialized in Boost.Variant2 (-Wuninitialized -Og) Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 12.1, with Boost 1.71 or later, #include int main() { boost::variant2::variant r; r.emplace(); } In member function 'constexpr void boost::variant2::detail::variant_storage_impl, T1, T ...>::emplace_impl(boost::mp11::mp_true, boost::mp11::mp_size_t, A&& ...) [with long unsigned int I = 1; A = {}; T1 = boost::variant2::detail::none; T = {boost::variant2::monostate, int}]', inlined from 'constexpr void boost::variant2::detail::variant_storage_impl, T1, T ...>::emplace(boost::mp11::mp_size_t, A&& ...) [with long unsigned int I = 1; A = {}; T1 = boost::variant2::detail::none; T = {boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:705:27, inlined from 'constexpr void boost::variant2::detail::variant_base_impl::emplace_impl(boost::mp11::mp_true, A&& ...) [with long unsigned int J = 1; U = boost::variant2::monostate; A = {}; T = {boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:902:20, inlined from 'constexpr void boost::variant2::detail::variant_base_impl::emplace(A&& ...) [with long unsigned int I = 0; A = {}; T = {boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:921:33, inlined from 'constexpr U& boost::variant2::variant::emplace(A&& ...) [with U = boost::variant2::monostate; A = {}; E = void; T = {boost::variant2::monostate, int}]' at boost/variant2/variant.hpp:1690:49: boost/variant2/variant.hpp:696:9: warning: '' is used uninitialized [-Wuninitialized] 696 | *this = variant_storage_impl( mp11::mp_size_t(), std::forward(a)... ); | ^ boost/variant2/variant.hpp: In member function 'constexpr U& boost::variant2::variant::emplace(A&& ...) [with U = boost::variant2::monostate; A = {}; E = void; T = {boost::variant2::monostate, int}]': boost/variant2/variant.hpp:696:17: note: '' declared here 696 | *this = variant_storage_impl( mp11::mp_size_t(), std::forward(a)... ); | ^~~ Boost.Variant2 has a suppression at this line for Wmaybe-uninitialized referencing asan, (a) this isn't with sanitizer, and (b) it's Wuninitialized. This only appears to affect -Og, though, so fairly minor.
[Bug c++/111840] New: =delete("can have a reason")?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111840 Bug ID: 111840 Summary: =delete("can have a reason")? Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 6.1, gcc accepts the following (without warnings at any level): int f() = delete("should have a reason"); Much as I'd love to be able to write this, gcc seems to be slightly jumping the gun, since P2573[1][2] hasn't been accepted yet and in fact wasn't even proposed until almost 6 years after 6.1 was released. 1. https://github.com/cplusplus/papers/issues/1229 2. https://wg21.link/p2573r0
[Bug c++/111602] [11/12/13/14 Regression] "Error: symbol is already defined" for variable template dependent on default argument lambda of class dependent on local type used in sfinae and non-sfinae c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111602 --- Comment #2 from Ed Catmur --- (In reply to Andrew Pinski from comment #1) > The local type of f() is not needed. Thanks! I was confused since the local type is required in this similar example: template struct P { static constexpr bool value = true; }; template constexpr bool P::value; template struct E {}; struct F { template::value>> F(T) {} }; template struct C { C(F = []{}) {} }; auto f() { struct T {} t; return t; } template decltype(T()) g() { return T(); } int main() { g>(); }
[Bug c++/111602] New: "Error: symbol is already defined" for variable template dependent on default argument lambda used in sfinae and non-sfinae
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111602 Bug ID: 111602 Summary: "Error: symbol is already defined" for variable template dependent on default argument lambda used in sfinae and non-sfinae Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since gcc 8.1, template constexpr bool V = true; struct F { template> F(T) {} }; template struct C { C(F = []{}) {} }; template decltype(T()) g() { return T(); } auto f() { struct T {} t; return t; }; int main() { g>(); } compiled at -O0 (and -std=c++14 or above) causes assembler error: /tmp/cccVZwwU.s: Assembler messages: /tmp/cccVZwwU.s:106: Error: symbol `_Z1VIZN1CIZ1fvE1TEC4E1FEd_UlvE_E' is already defined The symbol demangles as 'V::C(F)::{default arg#1}::{lambda()#1}>'.
[Bug tree-optimization/111094] Spurious Wuninitialized swapping underlying bytes of object representation in move constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094 Ed Catmur changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #4 from Ed Catmur --- Well, I feel like [basic.types.general] probably allows it. But regardless, yeah, this is an opt-in diagnostic so it's fine if gcc warns on things that are legal but dubious. We'll just have to be a bit smarter in how we write this code. Thanks again.
[Bug middle-end/24639] [meta-bug] bug to track all Wuninitialized issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639 Bug 24639 depends on bug 111094, which changed state. Bug 111094 Summary: Spurious Wuninitialized swapping underlying bytes of object representation in move constructor https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID
[Bug c++/111094] New: Spurious Wuninitialized swapping underlying bytes of object representation in move constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111094 Bug ID: 111094 Summary: Spurious Wuninitialized swapping underlying bytes of object representation in move constructor Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- struct S { short x, y; }; struct A { A() {} A(A&& rhs) { auto p = reinterpret_cast(); auto q = reinterpret_cast(); for (int i = 0; i != sizeof s; ++i) { auto t = p[i]; p[i] = q[i]; q[i] = t; } } bool b = false; S s; }; A f() { A a; A b = static_cast(a); return b; } at -O3 -Wall: In constructor 'A::A(A&&)', inlined from 'A f()' at :18:29: :9:23: warning: '*(__vector(4) unsigned char*)((char*) + offsetof(A, A::s.S::x))' is used uninitialized [-Wuninitialized] 9 | p[i] = q[i]; |~~~^ : In function 'A f()': :17:7: note: 'a' declared here 17 | A a; | ^ I'm reasonably sure that this usage of swapping underlying bytes is OK by [basic.indet]/2.3. (Motivation is e.g. optional with empty-on-move behavior and optimization for trivial types.)
[Bug tree-optimization/111090] Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090 Ed Catmur changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #4 from Ed Catmur --- (In reply to Andrew Pinski from comment #2) > I don't see how it is bogus as you admit it was only partially initialized > even. The act of copying is still an use IIRC. Sorry, my bad. I reduced it past the point of usefulness and got myself confused. Thanks.
[Bug middle-end/24639] [meta-bug] bug to track all Wuninitialized issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639 Bug 24639 depends on bug 111090, which changed state. Bug 111090 Summary: Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID
[Bug c++/111090] Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090 --- Comment #1 from Ed Catmur --- uh, -O -Wall is necessary, obviously. https://godbolt.org/z/eT9dY467P
[Bug c++/111090] New: Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111090 Bug ID: 111090 Summary: Bogus -Wuninitialized for trivial copy of nested struct with partially initialized array Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- struct A { A() { buf[0] = 0; } int buf[2]; }; struct B { A a; }; struct C { C(B const& b) : b(b) {} B b; }; struct D { D(C c) : c(c) {} C c; }; D f() { return D(C(B())); } In constructor 'C::C(const B&)', inlined from 'D f()' at :14:16: :7:21: warning: '.B::a.A::a[1]' is used uninitialized [-Wuninitialized] 7 | C(B const& b) : b(b) {} | ^~~~ : In function 'D f()': :14:22: note: '' declared here 14 | D f() { return D(C(B())); } | ^ This appears to have started in 7.1.
[Bug c++/111016] New: Confusing "used in its own initializer" for non-dependent ad-hoc constraint
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111016 Bug ID: 111016 Summary: Confusing "used in its own initializer" for non-dependent ad-hoc constraint Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include struct S { int i; }; static_assert(requires(S s) { requires std::destructible; }); In file included from :1: include/c++/14.0.0/concepts:148:13: required for the satisfaction of 'destructible' include/c++/14.0.0/concepts:148:38: error: the value of 'std::__detail::__destructible' is not usable in a constant expression 148 | concept destructible = __detail::__destructible<_Tp>; |~~^~~ include/c++/14.0.0/concepts:127:22: note: 'std::__detail::__destructible' used in its own initializer 127 | constexpr bool __destructible = __destructible_impl<_Tp>; | ^~ Obviously this is IFNDR, but it would be nice to emit a diagnostic which gives some better clue to what is going on (e.g. "warning: constraint is non-dependent"). Unfortunately both clang and MSVC accept with no diagnostic, making this look like a gcc bug.
[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 --- Comment #58 from Ed Catmur --- (In reply to Roman Krotov from comment #57) > But I don't see any reasons not to implement the switch right now... Making [[gnu::warn_unused_result]] mean the same as [[nodiscard]] would be a reduction in expressivity. > what about the projects > what don't agree with the distinction of these 2 attributes? Or just want to > be more compatible with clang? They can use [[nodiscard]]. > Or they just may not agree with the choice of a library, that decided to put > wur instead of nodiscard for a specific function. Then they can write their own wrappers using [[nodiscard]].
[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 --- Comment #55 from Ed Catmur --- (In reply to Roman Krotov from comment #54) [[nodiscard]] is in C23, so we can expect that attribute to be adopted where people intend that behavior (warning suppressible by cast to void) as opposed to the nonportable [[gnu::warn_unused_result]] (warning not suppressible by cast to void). So this problem will resolve itself, over time.
[Bug sanitizer/110835] [13/14 Regression] -fsanitize=address causes huge runtime slowdown from std::rethrow_exception not called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835 --- Comment #6 from Ed Catmur --- Thanks, filed https://github.com/llvm/llvm-project/issues/64190 .
[Bug c++/110835] -fsanitize=address causes slowdown from std::rethrow_exception not called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835 --- Comment #1 from Ed Catmur --- Motivation is https://github.com/boostorg/exception/blob/b039b4ea18ef752d0c1684b3f715ce493b778060/include/boost/exception/detail/exception_ptr.hpp#L550 ; the half-reduced code is: #include struct S {}; int main() { auto ep = boost::copy_exception(S()); for (int i = 0; i != 10; ++i) try { boost::rethrow_exception(ep); } catch (...) {} }
[Bug c++/110835] New: -fsanitize=address causes slowdown from std::rethrow_exception not called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110835 Bug ID: 110835 Summary: -fsanitize=address causes slowdown from std::rethrow_exception not called Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include std::exception_ptr p; void f() { try { throw 1; } catch(char) { std::rethrow_exception(p); } } int main() { for (int i = 0; i != 10; ++i) try { f(); } catch (...) { } } Compiled with -fsanitize=address (and at -O0 through -O3), this is roughly 30x slower under gcc 13 than under gcc 12 (4.7s vs 0.15s on my Core i7 3 GHz). Note that the std::rethrow_exception() is not called, but is still essential to exhibit the bug. Also `f` needs to be a separate function (and not `static`). At low optimization levels it can be an iife.
[Bug c++/110809] ICE: in unify, at cp/pt.cc:25226 with floating-point NTTPs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110809 --- Comment #5 from Ed Catmur --- The original code is valid. A reduced valid case would be: ``` template struct S {}; template struct bucket {}; template int find_indices_impl(bucket const &); struct HashTable : bucket, 1>, bucket, 2> {}; auto t = find_indices_impl>(HashTable{}); ```
[Bug c++/110809] New: ICE: in unify, at cp/pt.cc:25226 with floating-point NTTPs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110809 Bug ID: 110809 Summary: ICE: in unify, at cp/pt.cc:25226 with floating-point NTTPs Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include using A = double; template struct S {}; auto x = boost::hana::make_map( boost::hana::make_pair(boost::hana::type_c>, 1), boost::hana::make_pair(boost::hana::type_c>, 2))[ boost::hana::type_c>]; /opt/compiler-explorer/libs/boost_1_82_0/boost/hana/detail/hash_table.hpp:51:62: internal compiler error: in unify, at cp/pt.cc:25226 51 | using type = decltype(detail::find_indices_impl(std::declval())); | ~~~^ 0x246af2e internal_error(char const*, ...) ???:0 0xac8ab6 fancy_abort(char const*, int, char const*) ???:0 0xd01e11 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool, bool) ???:0 0xaf7db9 build_new_function_call(tree_node*, vec**, int) ???:0 0xd2379c finish_call_expr(tree_node*, vec**, bool, bool, int) ???:0 0xcddfef tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xd06d50 instantiate_class_template(tree_node*) ???:0 0xd5954f complete_type_or_maybe_complain(tree_node*, tree_node*, int) ???:0 0xcdf1a7 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xd06d50 instantiate_class_template(tree_node*) ???:0 0xd5954f complete_type_or_maybe_complain(tree_node*, tree_node*, int) ???:0 0xcdf1a7 tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xcde6fc tsubst(tree_node*, tree_node*, int, tree_node*) ???:0 0xcd6618 instantiate_decl(tree_node*, bool, bool) ???:0 0xbb8461 maybe_instantiate_decl(tree_node*) ???:0 0xbb9ebf mark_used(tree_node*, int) ???:0 0xaf673e build_new_method_call(tree_node*, tree_node*, vec**, tree_node*, int, tree_node**, int) ???:0 0xd22eaf finish_call_expr(tree_node*, vec**, bool, bool, int) ???:0 Changing `A` to `int` makes it compile, so this is a problem with floating-point NTTPs.
[Bug c++/110493] 'is not a constant expression' for function-local static std::initializer_list with fsanitize=undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110493 --- Comment #4 from Ed Catmur --- Ah, thanks. So a workaround is something like: void f() { static auto a = {((bool*)&(int const&)0, std::string())}; } That's not too bad, then.
[Bug libstdc++/110493] New: 'is not a constant expression' for function-local static std::initializer_list with fsanitize=undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110493 Bug ID: 110493 Summary: 'is not a constant expression' for function-local static std::initializer_list with fsanitize=undefined Product: gcc Version: 12.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 12.3.0, under -fsanitize=undefined -std=c++20: #include #include void f() { static auto a = {std::string()}; } error: '(((const std::__cxx11::basic_string*)(& )) != 0)' is not a constant expression Clearly this is an instance of bug 71962, but this is in fairly unexceptional code and could make ubsan unusable; it's not obvious that this code should have anything to do with constant evaluation. Since it only appears in a point release I would hope it might be possible to fix in library for this specific case, within ?
[Bug libstdc++/109976] New: error: is not a constant expression in std::equal() with _GLIBCXX_DEBUG
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109976 Bug ID: 109976 Summary: error: is not a constant expression in std::equal() with _GLIBCXX_DEBUG Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #define _GLIBCXX_DEBUG #include #include constexpr bool f(std::string const& l, std::string const& r) { return std::equal(l.data(), l.data() + l.size(), r.data(), r.data() + r.size()); } constexpr bool b = f("aa", "aa"); In file included from c++/14.0.0/debug/stl_iterator.h:32, from c++/14.0.0/bits/stl_iterator.h:3004, from c++/14.0.0/bits/stl_algobase.h:67, from c++/14.0.0/algorithm:60, from :2: :7:21: in 'constexpr' expansion of 'f(std::__cxx11::basic_string(((const char*)"aa"), std::allocator()), std::__cxx11::basic_string(((const char*)"aa"), std::allocator()))' :5:22: in 'constexpr' expansion of 'std::equal((& l)->std::__cxx11::basic_string::data(), ((& l)->std::__cxx11::basic_string::data() + ((sizetype)(& l)->std::__cxx11::basic_string::size())), (& r)->std::__cxx11::basic_string::data(), ((& r)->std::__cxx11::basic_string::data() + ((sizetype)(& r)->std::__cxx11::basic_string::size(' c++/14.0.0/bits/stl_algobase.h:1679:7: in 'constexpr' expansion of '__gnu_debug::__valid_range(__first1, __last1)' c++/14.0.0/debug/helper_functions.h:257:31: in 'constexpr' expansion of '__gnu_debug::__valid_range_aux(__first, __last, (_Integral(), _Integral()))' c++/14.0.0/debug/helper_functions.h:189:31: in 'constexpr' expansion of '__gnu_debug::__valid_range_aux(__first, __last, (std::__iterator_category(__first), std::iterator_traits::iterator_category()))' c++/14.0.0/debug/helper_functions.h:176:19: in 'constexpr' expansion of '__gnu_debug::__valid_range_aux(__first, __last, (std::input_iterator_tag(), std::input_iterator_tag()))' c++/14.0.0/debug/helper_functions.h:136:20: error: '(((const char*)(&.std::__cxx11::basic_string::.std::__cxx11::basic_string_M_local_buf)) == 0)' is not a constant expression 136 | { return __ptr == 0; } | ~~^~~~ This appears to be caused by bug 109975, but I'm filing separately since it may be possible to fix in library. The code is accepted if _GLIBCXX_DEBUG is not defined, since __gnu_debug::__valid_range is not checked.
[Bug c++/109975] New: error: '(((int*)(&.X::a)) != 0)' is not a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109975 Bug ID: 109975 Summary: error: '(((int*)(&.X::a)) != 0)' is not a constant expression Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- struct X { int a[1]; }; constexpr bool b = (X{}.a != 0); :7:27: error: '(((int*)(&.X::a)) != 0)' is not a constant expression 7 | constexpr bool b = (X{}.a != 0); |~~~^ AFAICT this does not fall foul of anything in [expr.const]. Other compilers accept, with a tautological-compare warning in the case of clang. Similar to bug 71962, but this happens without enabling sanitizer.
[Bug c++/109958] [10/11/12/13/14 Regression] ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking the address of bound static member function brought into derived class by using-declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109958 --- Comment #3 from Ed Catmur --- B::f is a static member function so yes, it's valid. A class member access expression naming a static member function is an lvalue designating that function, and it shouldn't make any difference that the function was found via a using declaration.
[Bug c++/109958] New: ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking the address of bound static member function brought into derived class by using-declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109958 Bug ID: 109958 Summary: ICE: in build_ptrmem_type, at cp/decl.cc:11066 taking the address of bound static member function brought into derived class by using-declaration Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- struct B { static int f(); }; struct D : B { using B::f; }; void f(D d) { } : In function 'void f(D)': :3:18: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '::f' [-fpermissive] 3 | void f(D d) { } |~~^ :3:18: internal compiler error: in build_ptrmem_type, at cp/decl.cc:11066 3 | void f(D d) { } | ^ 0x23a0cee internal_error(char const*, ...) ???:0 0xa95fae fancy_abort(char const*, int, char const*) ???:0 0xd31f7f build_x_unary_op(unsigned int, tree_code, cp_expr, tree_node*, int) ???:0 0xc7ab2f c_parse_file() ???:0 0xdb9519 c_common_parse_file() ???:0 This appears to have been broken somewhere between 4.7.4 and 4.8.1.
[Bug preprocessor/109912] New: #pragma GCC diagnostic ignored "-Wall" is ignored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109912 Bug ID: 109912 Summary: #pragma GCC diagnostic ignored "-Wall" is ignored Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #pragma GCC diagnostic warning "-Wall" #pragma GCC diagnostic ignored "-Wall" int i = 0 | 1 & 2; warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses] 3 | int i = 0 | 1 & 2; | ~~^~~ The expected behavior would be for `diagnostic ignored "-Wall"` to suppress all the warnings that were enabled by `diagnostic warning "-Wall"`. If this isn't possible, it would be good to emit a diagnostic that `diagnostic ignored "-Wall"` has no effect. Clang does support this and appears to have always done so.
[Bug libstdc++/109882] New: -fsanitize=thread #include transitively includes sanitizer/common_interface_defs.h
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109882 Bug ID: 109882 Summary: -fsanitize=thread #include transitively includes sanitizer/common_interface_defs.h Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 12.3.0, when compiled under tsan (-fsanitize=thread), #include transitively includes sanitizer/common_interface_defs.h: #include #if defined SANITIZER_COMMON_INTERFACE_DEFS_H #error :( #endif This is problematic for us because sanitizer/common_interface_defs.h has #define __has_feature(x) 0 https://github.com/gcc-mirror/gcc/blame/5d85b5d649fff675ff00adcc99371bccf4ef5944/libsanitizer/include/sanitizer/common_interface_defs.h#L20 which makes our sanitizer detector incorrectly believe that __has_feature is available and that tsan is not in fact present since __has_feature(thread_sanitizer) evaluates to 0. We will fix the order of checks to put `#ifdef __SANITIZE_THREAD__` first but thought we should probably report this to help other users.
[Bug c++/109870] New: Miscomputation of return type of unevaluated lambda in type alias in template context
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109870 Bug ID: 109870 Summary: Miscomputation of return type of unevaluated lambda in type alias in template context Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template struct X {}; template struct M { using R = decltype([] { return 1; }()); template struct S { X p; }; }; M::S s; 9.1 through 14.0.0 trunk reject with: : In instantiation of 'struct M::S': :7:17: required from here :4:36: error: return-statement with a value, in function returning 'void' [-fpermissive] 4 | using R = decltype([] { return 1; }()); |^ It appears the `U` type parameter in `M::S` is overwriting the lambda deduced return type. Possibly related to #92707, #103569
[Bug sanitizer/83780] False positive alignment error with -fsanitize=undefined with virtual base
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83780 --- Comment #4 from Ed Catmur --- Clang has fixed this in https://github.com/llvm/llvm-project/commit/4ddf140c00408ecee9d20f4470e69e0f696d8f8a (12.0.0-rc1).
[Bug c++/109677] New: Access control bypass for function template default argument brace initialization of private default constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109677 Bug ID: 109677 Summary: Access control bypass for function template default argument brace initialization of private default constructor Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- gcc accepts-invalid: struct B { private: B(); }; template int f(T = {}); int i = f(); This is mostly a curiosity, but it came up while trying to understand why a misuse of the passkey pattern was seemingly working.
[Bug c++/109640] Spurious Wdangling-reference for argument to temporary lambda cast to rvalue reference
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109640 --- Comment #2 from Ed Catmur --- Ah, so this is Bug 108165? That's a shame, we use (temporary) lambdas extensively so I think we'd have to disable the warning entirely.
[Bug c++/109640] New: Spurious Wdangling-reference for argument to temporary lambda cast to rvalue reference
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109640 Bug ID: 109640 Summary: Spurious Wdangling-reference for argument to temporary lambda cast to rvalue reference Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- bool b() { int a; int&& i = [](int& r) -> int&& { return static_cast(r); }(a); auto const l = [](int& r) -> int&& { return static_cast(r); }; int&& j = l(a); return == } : In function 'bool b()': :3:11: warning: possibly dangling reference to a temporary [-Wdangling-reference] 3 | int&& i = [](int& r) -> int&& { return static_cast(r); }(a); | ^ :3:68: note: the temporary was destroyed at the end of the full expression 'b()::().b()::(a)' 3 | int&& i = [](int& r) -> int&& { return static_cast(r); }(a); | ~^~~ The heuristic appears to be confused by the lambda itself being a temporary, even though it is captureless.
[Bug c++/109070] New: ICE in class template member function overloads distinguished by non-functionally-equivalent constraints and return type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109070 Bug ID: 109070 Summary: ICE in class template member function overloads distinguished by non-functionally-equivalent constraints and return type Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template concept C = true; template struct A { int f() requires C<42> { return 1; } // #1 unsigned f() requires true { return 2u; } // #2 }; int main() { int (A::*p)() = ::f; unsigned (A::*q)() = ::f; return (A().*p)() + (A().*q)(); } :10:1: error: Two symbols with same comdat_group are not linked by the same_comdat_group list. 10 | } | ^ _ZN1AIiE1fEv/2 (unsigned int A::f() requires true [with T = int]) Type: function definition analyzed Visibility: semantic_interposition public weak comdat comdat_group:_ZN1AIiE1fEv one_only previous sharing asm name: 1 Address is taken. References: Referring: main/0 (addr) Function flags: body Called by: Calls: _ZN1AIiE1fEv/1 (int A::f() requires C<42> [with T = int]) Type: function definition analyzed Visibility: semantic_interposition public weak comdat comdat_group:_ZN1AIiE1fEv one_only next sharing asm name: 2 Address is taken. References: Referring: main/0 (addr) Function flags: body Called by: Calls: :10:1: internal compiler error: symtab_node::verify failed 0x247b73e internal_error(char const*, ...) ???:0 0xed5c22 symtab_node::verify_symtab_nodes() ???:0 0xef042b symbol_table::finalize_compilation_unit() ???:0 This is valid per [temp.over.link]/5, but that seems impossible to implement - I've filed https://github.com/cplusplus/CWG/issues/256.
[Bug c++/79682] [concepts] ambiguous overload with functionally equivalent predicate constraints compiles
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79682 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #2 from Ed Catmur --- I think this was made IFNDR by CWG2603?
[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536 --- Comment #6 from Ed Catmur --- Resubmitted: https://gcc.gnu.org/pipermail/gcc-patches/2023-February/611366.html Hopefully this time I'll remember to save the email for pinging.
[Bug c++/108468] New: ICE in most_specialized_partial_spec/builtin_guide_p in C++20 mode
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108468 Bug ID: 108468 Summary: ICE in most_specialized_partial_spec/builtin_guide_p in C++20 mode Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 11.1, the following ices in -std=c++20 and later: template struct C { template static constexpr int x = 1; }; template template int C::x = 2; int y = C<0>::x; 0x23ae54e internal_error(char const*, ...) ???:0 0xc5b614 deduction_guide_p(tree_node const*) ???:0 0xc5be2c builtin_guide_p(tree_node const*) ???:0 0xc82bdf most_specialized_partial_spec(tree_node*, int) ???:0 0xc83a76 instantiate_template(tree_node*, tree_node*, int) ???:0 0xc8c0d8 finish_template_variable(tree_node*, int) ???:0 0xcce05f finish_id_expression(tree_node*, tree_node*, tree_node*, cp_id_kind*, bool, bool, bool*, bool, bool, bool, bool, char const**, unsigned int) ???:0
[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536 --- Comment #5 from Ed Catmur --- PR: https://github.com/ecatmur/gcc/pull/5
[Bug c++/108390] New: ICE in fold_convert_loc, at fold-const.cc:2504 partial ordering between array types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108390 Bug ID: 108390 Summary: ICE in fold_convert_loc, at fold-const.cc:2504 partial ordering between array types Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template long f(int(*)[t], T(*)[t]); template int f(int(*)[i], T(*)[i]); int n = f(0, 0); :4:18: internal compiler error: in fold_convert_loc, at fold-const.cc:2504 4 | int n = f(0, 0); | ~^~ 0x23975be internal_error(char const*, ...) ???:0 0xa693ae fancy_abort(char const*, int, char const*) ???:0 0xc99848 more_specialized_fn(tree_node*, tree_node*, int) ???:0 0xa97529 build_new_function_call(tree_node*, vec**, int) ???:0 0xcb6fd4 finish_call_expr(tree_node*, vec**, bool, bool, int) ???:0 0xc43be7 c_parse_file() ???:0 0xd7fd79 c_common_parse_file() ???:0 Godbolt says this is bad back to 8.1; before that it was ambiguous.
[Bug c++/107206] New: Bogus -Wuninitialized in std::optional
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107206 Bug ID: 107206 Summary: Bogus -Wuninitialized in std::optional Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 12, at -std=c++17 -O -Wuninitialized: #include struct X { X() = default; X(X const& r) : i(r.i) {} int i; }; struct Y { Y() : x() {} X x; std::optional o; }; struct Z { Y y; explicit Z(Y y) : y(y) {} }; void f(Y const&); void test() { Y const y; Z z(y); z.y.o = 1; auto const w = z; f(w.y); } In copy constructor 'Y::Y(const Y&)', inlined from 'void test()' at :19:10: :7:8: warning: '*(int*)((char*) + offsetof(const Y, Y::o.std::optional::.std::_Optional_base::))' is used uninitialized [-Wuninitialized] 7 | struct Y { |^ : In function 'void test()': :18:13: note: 'y' declared here 18 | Y const y; | ^ Most similar to #80635 and #86465, I think? Although this is -Wuninitialized, not -Wmaybe-uninitialized.
[Bug c++/106712] Incorrect propagation of C++11 attributes to subsequent function declarations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106712 --- Comment #1 from Ed Catmur --- I believe this is happening because start_decl can modify prefix_attributes (by first chaining it onto attributes, then passing the merged chain to grokdeclarator which can then chain onto that merged chain). If the attribute list is empty, prefix_attributes is NULL_TREE and so is not affected. If so, the simplest fix would be for start_decl to copy_list(prefix_attributes) prior to chaining it.
[Bug c++/106712] New: Incorrect propagation of C++11 attributes to subsequent function declarations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106712 Bug ID: 106712 Summary: Incorrect propagation of C++11 attributes to subsequent function declarations Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- In [[first-attribute]] int f [[second-attribute]](), g(); the [[first-attribute]] should apply to both f and g, the [[second-attribute]] to f only: > The attribute-specifier-seq appertains to each of the entities declared by > the declarators of the init-declarator-list. http://eel.is/c++draft/dcl.dcl#dcl.pre-3.sentence-5 > The attribute-specifier-seq affects the type only for the declaration it > appears in, not other declarations involving the same type. http://eel.is/c++draft/dcl.dcl#dcl.spec.general-1.sentence-3 However, gcc instead applies [[second-attribute]] to both functions, but only if [[first-attribute]] is non-empty. This can lead to rejects-valid: [[gnu::cold]] int g() { return 1; } [[gnu::cold]] int f [[gnu::fastcall]](), g(); // error: ambiguating new declaration of 'int g()' Or to miscompilation, e.g.: [[gnu::cold]] int f [[gnu::const]](), g(); int g() { static int i; return ++i; } #include int main() { assert(g() + g() == 3); } // fails Or erroneous warnings (with only standard attributes): [[noreturn]] int f [[nodiscard]](), g(); int main() { g(); }
[Bug c++/106411] New: Wdangling-pointer for a class that cleans up on destruction
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106411 Bug ID: 106411 Summary: Wdangling-pointer for a class that cleans up on destruction Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Reduced testcase: #include void g(auto f1) { auto f2 = std::move(f1); } struct F; struct E { F* f = nullptr; }; struct F { E* e; explicit F(E* a) : e(a) { e->f = this; } ~F() { if (e) e->f = nullptr; } F(F&& rhs) : e(std::exchange(rhs.e, nullptr)) { e->f = this; } }; int main() { E e; F f(); g(std::move(f)); } At -O -Wall in 12.1 and current trunk 13.0.0: In constructor 'F::F(F&&)', inlined from 'void g(auto:1) [with auto:1 = F]' at :3:10, inlined from 'int main()' at :23:6: :17:14: warning: storing the address of local variable 'f2' in '*__old_val.E::f' [-Wdangling-pointer=] 17 | e->f = this; | ~^~ : In function 'int main()': :3:10: note: 'f2' declared here 3 | auto f2 = std::move(f1); | ^~ :3:10: note: '.F::e' declared here It would be helpful if Wdangling-pointer could realize that the stored address will be cleared when the local variable is destroyed. Here `g` is reduced from `boost::asio::detail::executor_function::complete` and `F` is reduced from our own callback type. The above reduced testcase only repros at -O but our unreduced code repros at -O3.
[Bug c++/106074] Spurious Wstringop-overflow for int-to-string with SSE4
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106074 --- Comment #1 from Ed Catmur --- Another example, using Date 3.0.1: #include void f(std::istream s) { std::chrono::system_clock::time_point tp; date::from_stream(s, "%Y", tp); } https://godbolt.org/z/fscqTd947 In file included from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_pair.h:61, from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:64, from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/algorithm:60, from /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:44, from :1: In function 'constexpr std::_Require >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = char]', inlined from 'constexpr void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:182:11, inlined from 'constexpr void std::__reverse(_RandomAccessIterator, _RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1107:18, inlined from 'constexpr void std::reverse(_BIter, _BIter) [with _BIter = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1134:21, inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, int, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {char&, const char&}]' at /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6513:21, inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {int&, char&, const char&}]' at /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6474:9: /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/move.h:205:11: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 205 | __a = _GLIBCXX_MOVE(__b); | ^ /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h: In function 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {int&, char&, const char&}]': /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at offset 19 into destination object 'buf' of size 11 6506 | CharT buf[std::numeric_limits::digits10+2u] = {}; | ^~~ /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at offset [3, 11] into destination object 'buf' of size 11 /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at offset 19 into destination object 'buf' of size 11 In function 'constexpr std::_Require >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = char]', inlined from 'constexpr void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:182:11, inlined from 'constexpr void std::__reverse(_RandomAccessIterator, _RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1107:18, inlined from 'constexpr void std::reverse(_BIter, _BIter) [with _BIter = char*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1134:21, inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, int, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {char&, const char&}]' at /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6513:21, inlined from 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {int&, char&, const char&}]' at /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6474:9: /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/move.h:205:11: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 205 | __a = _GLIBCXX_MOVE(__b); | ^ /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h: In function 'void date::detail::read(std::basic_istream<_CharT, _Traits>&, CharT, Args&& ...) [with CharT = char; Traits = std::char_traits; Args = {int&, char&, const char&}]': /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at offset 20 into destination object 'buf' of size 11 6506 | CharT buf[std::numeric_limits::digits10+2u] = {}; | ^~~ /opt/compiler-explorer/libs/date/v3.0.1/include/date/date.h:6506:15: note: at offset [4, 11] into destination object 'buf' of size 11
[Bug c++/106185] New: Spurious Wstringop-overflow in std::vector::resize
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106185 Bug ID: 106185 Summary: Spurious Wstringop-overflow in std::vector::resize Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Since 12.1.0: At -O3 -std=c++20 -Werror=stringop-overflow: #include void f() { std::vector v; v.resize(26); v.resize(33); v.resize(39); v.resize(47); v.resize(v.size() + 8); } In file included from gcc-12.1.0/include/c++/12.1.0/vector:60, from :1: In function 'constexpr typename __gnu_cxx::__enable_if::__value, void>::__type std::__fill_a1(_Tp*, _Tp*, const _Tp&) [with _Tp = char]', inlined from 'constexpr void std::__fill_a(_FIte, _FIte, const _Tp&) [with _FIte = char*; _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:968:21, inlined from 'constexpr _OutputIterator std::__fill_n_a(_OutputIterator, _Size, const _Tp&, random_access_iterator_tag) [with _OutputIterator = char*; _Size = long unsigned int; _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:1119:20, inlined from 'constexpr _OI std::fill_n(_OI, _Size, const _Tp&) [with _OI = char*; _Size = long unsigned int; _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:1148:29, inlined from 'static constexpr _ForwardIterator std::__uninitialized_default_n_1::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = char*; _Size = long unsigned int]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:663:29, inlined from 'static constexpr _ForwardIterator std::__uninitialized_default_n_1::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = char*; _Size = long unsigned int]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:655:9, inlined from 'constexpr _ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = char*; _Size = long unsigned int]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:701:20, inlined from 'constexpr _ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, allocator<_Tp>&) [with _ForwardIterator = char*; _Size = long unsigned int; _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_uninitialized.h:766:44, inlined from 'constexpr void std::vector<_Tp, _Alloc>::_M_default_append(size_type) [with _Tp = char; _Alloc = std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/vector.tcc:642:35, inlined from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type) [with _Tp = char; _Alloc = std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:1011:21, inlined from 'void f()' at :8:13: gcc-12.1.0/include/c++/12.1.0/bits/stl_algobase.h:942:25: error: 'void* __builtin_memset(void*, int, long unsigned int)' writing 7 bytes into a region of size 4 overflows the destination [-Werror=stringop-overflow=] 942 | __builtin_memset(__first, static_cast(__tmp), __len); | ^~~ In file included from gcc-12.1.0/include/c++/12.1.0/x86_64-linux-gnu/bits/c++allocator.h:33, from gcc-12.1.0/include/c++/12.1.0/bits/allocator.h:46, from gcc-12.1.0/include/c++/12.1.0/vector:61: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = char]', inlined from 'constexpr _Tp* std::allocator< >::allocate(std::size_t) [with _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/allocator.h:183:40, inlined from 'static constexpr _Tp* std::allocator_traits >::allocate(allocator_type&, size_type) [with _Tp = char]' at gcc-12.1.0/include/c++/12.1.0/bits/alloc_traits.h:464:28, inlined from 'constexpr std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = char; _Alloc = std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:378:33, inlined from 'constexpr void std::vector<_Tp, _Alloc>::_M_default_append(size_type) [with _Tp = char; _Alloc = std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/vector.tcc:650:45, inlined from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type) [with _Tp = char; _Alloc = std::allocator]' at gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:1011:21, inlined from 'void f()' at :5:13: gcc-12.1.0/include/c++/12.1.0/bits/new_allocator.h:137:55: note: at offset [48, 52] into destination object of size 52 allocated by 'operator new' 137 | return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp))); | ^ cc1plus: some warnings being treated as errors
[Bug middle-end/103993] -Wismatched-new-delete due to difference in inlining decisions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993 --- Comment #4 from Ed Catmur --- And another example, provoked by throwing new (this only happens at -Og): #include struct D { D(); static void* operator new (std::size_t s) { if (void* p = ::malloc(s)) return p; throw "bad_alloc"; } static void operator delete (void* p) { ::free(p); } }; int main() { new D; }
[Bug c++/106074] New: Spurious Wstringop-overflow for int-to-string with SSE4
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106074 Bug ID: 106074 Summary: Spurious Wstringop-overflow for int-to-string with SSE4 Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Code adapted from https://github.com/capnproto/capnproto/blob/be7a80b4add706ddaeb41689221146b86c3e0f5f/c%2B%2B/src/kj/string.c%2B%2B#L157-L203 : auto f(short i) { struct R { char data[6]; } result; bool negative = i < 0; unsigned u = i; if (negative) u = -u; unsigned char reverse[5]; unsigned char* p = reverse; if (u == 0) *p++ = 0; else for (; u > 0; u /= 10) *p++ = u % 10; char* p2 = result.data; if (negative) *p2++ = '-'; while (p > reverse) { #ifdef ASSUME if (p2 >= ()[1]) __builtin_unreachable(); #endif *p2++ = '0' + *--p; } if (p2 < ()[1]) *p2 = '\0'; return result; } When compiled with -O3 -msse4, from 12.1.0 through 13.0.0 20220619: : In function 'auto f(short int)': :21:11: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 21 | *p2++ = '0' + *--p; | ~~^~~~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 2 | struct R { char data[6]; } result; | ^~~~ :2:30: note: at offset 7 into destination object 'result' of size 6 2 | struct R { char data[6]; } result; | ^~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 2 | struct R { char data[6]; } result; | ^~~~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 :2:30: note: at offset 7 into destination object 'result' of size 6 2 | struct R { char data[6]; } result; | ^~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 2 | struct R { char data[6]; } result; | ^~~~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 :2:30: note: at offset 7 into destination object 'result' of size 6 2 | struct R { char data[6]; } result; | ^~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 2 | struct R { char data[6]; } result; | ^~~~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 :2:30: note: at offset 7 into destination object 'result' of size 6 2 | struct R { char data[6]; } result; | ^~ :2:19: note: at offset 6 into destination object 'f(short int)::R::data' of size 6 2 | struct R { char data[6]; } result; | ^~~~ Adding the assumption at line 19 (-DASSUME) works around this.
[Bug c++/105918] New: Spurious Warray-bounds in std::to_chars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105918 Bug ID: 105918 Summary: Spurious Warray-bounds in std::to_chars Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include template std::to_chars_result toChars(char (& buf)[N], int number) { char temp[N]; std::to_chars_result result = std::to_chars(temp, temp + N, number); if (result.ec != std::errc()) return result; char* it = temp; char* end = result.ptr; std::size_t i = 0u; while (i != N && it != end) buf[i++] = *it++; if (i != N) buf[i] = '\0'; return std::to_chars_result{.ptr = buf + (result.ptr - temp), .ec = std::errc()}; } #include struct ar { struct V { bool value; } value; std::unique_ptr s; }; void f(...); ar g(); ar evaluate(bool value) { ar res{value}; if (res.value.value) return res; return g(); } #define CHECK(P) f(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, evaluate(P), 0, 0, 0, 0, 0, 0, 0, 0, 0 ); int main() { char s3[3]; auto res3 = toChars(s3, 12); CHECK((res3.ec == std::errc())); CHECK((s3[0] == '1')); CHECK((s3[1] == '2')); CHECK((s3[2] == '\0')); char s1[1]; auto res1 = toChars(s1, 12); CHECK((res1.ec != std::errc())); } Compiled at -O3 -Warray-bounds: In file included from include/c++/12.1.0/charconv:42, from :1: In function 'void std::__detail::__to_chars_10_impl(char*, unsigned int, _Tp) [with _Tp = unsigned int]', inlined from 'std::__detail::__integer_to_chars_result_type<_Tp> std::__detail::__to_chars_10(char*, char*, _Tp) [with _Tp = unsigned int]' at include/c++/12.1.0/charconv:225:35, inlined from 'std::__detail::__integer_to_chars_result_type<_Tp> std::__to_chars_i(char*, char*, _Tp, int) [with _Tp = int]' at include/c++/12.1.0/charconv:351:32, inlined from 'std::to_chars_result std::to_chars(char*, char*, int, int)' at include/c++/12.1.0/charconv:370:1, inlined from 'std::to_chars_result toChars(char (&)[N], int) [with int N = 1]' at :7:48: include/c++/12.1.0/bits/charconv.h:95:22: warning: array subscript 1 is outside array bounds of 'char [1]' [-Warray-bounds] 95 | __first[1] = __digits[__num + 1]; | ~~~^~~ : In function 'std::to_chars_result toChars(char (&)[N], int) [with int N = 1]': :6:10: note: at offset 1 into object 'temp' of size 1 6 | char temp[N]; | ^~~~ :6:10: note: at offset 2 into object 'temp' of size 1 Compiler returned: 0
[Bug c/105585] [12/13 Regression] Spurious stringop-overflow warning with
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585 --- Comment #2 from Ed Catmur --- Affected code: https://github.com/abseil/abseil-cpp/issues/1175 The proposed patch to abseil-cpp corresponds to adding an assumption that `b` is true above.
[Bug c/105585] [12/13 Regression] Spurious stringop-overflow warning with
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585 --- Comment #1 from Ed Catmur --- Flags: -O1 -Wstringop-overflow=1 https://godbolt.org/z/8r8roz7Pa
[Bug c/105585] New: [12/13 Regression] Spurious stringop-overflow warning with
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105585 Bug ID: 105585 Summary: [12/13 Regression] Spurious stringop-overflow warning with Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Reduced (from code in abseil-cpp): #include struct S { int i; std::atomic a; }; S* q(); void f(); void g(bool b) { auto p = b ? q() : nullptr; ++p->a; if (p) f(); } In file included from atomic:41, from :1: In member function 'std::__atomic_base<_IntTp>::__int_type std::__atomic_base<_IntTp>::operator++() [with _ITp = int]', inlined from 'void g(bool)' at :10:3: bits/atomic_base.h:385:34: warning: 'unsigned int __atomic_add_fetch_4(volatile void*, unsigned int, int)' writing 4 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 385 | { return __atomic_add_fetch(&_M_i, 1, int(memory_order_seq_cst)); } |~~^
[Bug tree-optimization/105545] [12/13 Regression] Warning for string assignment with _GLIBCXX_ASSERTIONS since r12-3347-g8af8abfbbace49e6
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #3 from Ed Catmur --- I don't think _GLIBCXX_ASSERTIONS is necessary; you just need -Werror=restrict and -O2 (not sure what exactly). https://godbolt.org/z/TvfYzbcf6
[Bug c++/105425] New: ambiguous template instantiation with hana::when
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105425 Bug ID: 105425 Summary: ambiguous template instantiation with hana::when Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- Simplified: template struct when; template constexpr int B = 1; template struct A; template struct A> {}; // fallback template struct A == 1>> {}; A> a; "B<0> == 1" is sufficiently complex (?) to trigger the bug (it doesn't need to be dependent on C) but "B<0>" on its own isn't. This affects hana since it uses the when pattern heavily. Per godbolt 11.3.0 is good, 12.0.1 20220426 is bad.
[Bug libstdc++/105027] New: Missing constraints on std::bit_cast
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105027 Bug ID: 105027 Summary: Missing constraints on std::bit_cast Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- [bit.cast] Constraints (nb. prior to P1719R2 these were specified as SFINAE, but they have been there since the start): (1.1) sizeof(To) == sizeof(From) is true; (1.2) is_trivially_copyable_v is true; and (1.3) is_trivially_copyable_v is true. #include template concept BitCastable = requires(U u) { std::bit_cast(u); }; static_assert(BitCastable); // OK static_assert(BitCastable); // #1: different size struct A { A(A const&); int i; }; static_assert(BitCastable); // #2: not trivially copyable #1 and #2 are erroneously accepted although the corresponding call to std::bit_cast would fail internally; MSVC and clang (with libc++) correctly reject. static_assert(BitCastable); // #3: see below int f(); long l = std::bit_cast(f); // #4 By my reading of [temp.deduct] #3 should be a hard error, since sizeof(int()) is not only invalid; it is not SFINAE. However, compilers that allow it (gcc everywhere, MSVC and clang as SFINAE) should then reject either by SFINAE, or as having the incorrect size, or since function types are not trivially copyable; gcc/libstdc++ does not and also accepts #4, decaying the function reference to a function pointer; clang/libstdc++ rejects within its own __builtin_bit_cast.
[Bug c++/104996] [10/11/12 Regression] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996 --- Comment #5 from Ed Catmur --- Posted https://gcc.gnu.org/pipermail/gcc-patches/2022-March/592154.html
[Bug c++/104996] [10/11/12 Regression] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996 --- Comment #4 from Ed Catmur --- (In reply to Patrick Palka from comment #2) > We started rejecting the commented out static_assert after > r10-3740-g89e0a492af5bec. Thanks, that accords with my analysis - the branch in call.cc:compare_ics that should be refined to take only if the two arrays have same element type was added there.
[Bug c++/104996] Overload resolution over rvalue/const lvalue array reference parameters for an init. list argument incorrectly picks the const lvalue ref. overload
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104996 --- Comment #1 from Ed Catmur --- This should fix it: https://github.com/gcc-mirror/gcc/compare/master...ecatmur:pr-104996 Please test and report back.
[Bug c++/69623] Invalid deduction of non-trailing template parameter pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623 --- Comment #8 from Ed Catmur --- (In reply to jim x from comment #7) > > auto f(auto..., auto a, auto...) { return a; } > > IIUC, this is just disallowed since all arguments would only match the first > function parameter pack. Maybe? But all 4 major compilers currently permit it (with identical behavior), so is it worth breaking existing code by disallowing it?
[Bug c++/69623] Invalid deduction of non-trailing template parameter pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69623 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #6 from Ed Catmur --- There is a fairly well-known idiom for extracting a specific element of an argument pack: auto f(auto..., auto a, auto...) { return a; } template struct any { any(auto) {} }; template auto g(std::index_sequence, auto... a) { return f...>(a...); } template auto h(auto... a) { return g(std::make_index_sequence(), a...); } I believe the intent of http://eel.is/c++draft/temp#param-14.sentence-3 is that this idiom should work; per http://eel.is/c++draft/temp#param-example-7 (as in comment #5) a function template secondary template parameter pack is only disallowed if it is nondeducible. In the original description of this ticket (not comment #5, which I agree is disallowed) T is specifiable and U is deducible, so both are OK. > [...] A template parameter pack of a function template shall not be followed > by another template parameter unless that template parameter can be deduced > from the parameter-type-list ([dcl.fct]) of the function template or has a > default argument ([temp.deduct]). [...] Or is the intent that T must be explicitly specified, i.e. that f can be called as f<>() but not as f(), pace http://eel.is/c++draft/temp#arg.explicit-4.sentence-3 ? > If all of the template arguments can be deduced, they may all be omitted; in > this case, the empty template argument list <> itself may also be omitted.
[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536 --- Comment #4 from Ed Catmur --- Posted: https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591678.html
[Bug c++/77465] [DR909] rejected C-style cast involving casting away constness from result of conversion operator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77465 --- Comment #4 from Ed Catmur --- Branch: https://github.com/gcc-mirror/gcc/compare/master...ecatmur:so-66816741
[Bug c++/70536] g++ doesn't emit DW_AT_name for DW_TAG_GNU_formal_parameter_pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536 --- Comment #3 from Ed Catmur --- Updated: https://github.com/gcc-mirror/gcc/compare/master...ecatmur:pr-70536
[Bug c++/77465] [DR909] rejected C-style cast involving casting away constness from result of conversion operator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77465 --- Comment #3 from Ed Catmur --- Sent patches to mailing list: https://gcc.gnu.org/pipermail/gcc-patches/2021-December/587495.html
[Bug c++/92944] [concepts] redefinition error when using constrained structure template inside namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92944 --- Comment #2 from Ed Catmur --- Sorry, meant to link this: https://quuxplusone.github.io/blog/2021/10/27/dont-reopen-namespace-std/
[Bug c++/92944] [concepts] redefinition error when using constrained structure template inside namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92944 --- Comment #1 from Ed Catmur --- This becomes problematic when N::Q is std::hash; we are encouraged not to reopen namespace std but to specialize std::hash from the root namespace. Example: #include template constexpr bool P = false; template constexpr bool Q = false; template requires P struct std::hash { std::size_t operator()(T) { return 1; } }; template requires Q struct std::hash { std::size_t operator()(U) { return 2; } }; struct S {}; template<> constexpr bool P = true; int i = std::hash()(S()); clang and MSVC correctly accept this.
[Bug c++/102047] ICE in template_parms_to_args passing lambda-quoted constraint to meta-concept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102047 --- Comment #1 from Ed Catmur --- cf. https://bugs.llvm.org/show_bug.cgi?id=51604
[Bug c++/102047] New: ICE in template_parms_to_args passing lambda-quoted constraint to meta-concept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102047 Bug ID: 102047 Summary: ICE in template_parms_to_args passing lambda-quoted constraint to meta-concept Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template concept A = true; template concept M = requires { L.template operator()(); }; template concept C = requires(T t) { { t.x } -> M<[](){}>; }; struct S { double x; }; static_assert(C); g++ (Compiler-Explorer-Build-gcc-8ca7fa84a3af355c3e2bbda2acc61934c16078b2-binutils-2.36.1) 12.0.0 20210823 (experimental) 6:18: internal compiler error: Segmentation fault 6 | { t.x } -> M<[](){}>; | ^ 0x1de2c99 internal_error(char const*, ...) 0x99d20d template_parms_to_args(tree_node*) 0x9e74ea tsubst_lambda_expr(tree_node*, tree_node*, int, tree_node*) 0x9db8d0 tsubst_template_arg(tree_node*, tree_node*, int, tree_node*) 0x7d702a constraints_satisfied_p(tree_node*, tree_node*) 0x9a6a67 do_auto_deduction(tree_node*, tree_node*, tree_node*, int, auto_deduction_context, tree_node*, int) 0x7d6fe2 tsubst_requires_expr(tree_node*, tree_node*, int, tree_node*) 0x7d7088 evaluate_concept_check(tree_node*) 0x7c26f4 maybe_constant_value(tree_node*, tree_node*, bool) 0xa2b65d finish_static_assert(tree_node*, tree_node*, unsigned int, bool, bool) 0x980395 c_parse_file() 0xb05462 c_common_parse_file() Clang also ICEs; MSVC accepts. Possibly related to #99465.
[Bug c++/101988] New: Accepts invalid new-expression of array of deduced class template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101988 Bug ID: 101988 Summary: Accepts invalid new-expression of array of deduced class template Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template struct A { A(T); }; auto p = new A[]{1}; g++ (Compiler-Explorer-Build-gcc-f0fca213bc52644ba896da622b35842a6157bd98-binutils-2.36.1) 12.0.0 20210818 (experimental) accepts (it allocates and constructs a single `A`. gcc 11.2 and below rejects, correctly: error: creating array of 'A<...auto...>' Per [expr.new]/2 the invented declaration should be: A[] x{1}; which is ill-formed. nb. clang ICEs on this (https://bugs.llvm.org/show_bug.cgi?id=51547)
[Bug sanitizer/100878] enabling UBSAN leads to false positive `'this' pointer is null` when casting lambda to function pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100878 --- Comment #1 from Ed Catmur --- Per godbolt, this appears to be fixed on trunk: https://godbolt.org/z/xxz8ecxzK g++ (Compiler-Explorer-Build-gcc-48e8a7a677b8356df946cd12fbb215538828e747-binutils-2.36.1) 12.0.0 20210707 (experimental)
[Bug c++/99994] New: internal compiler error: trying to capture 'f' in instantiation of generic lambda within constraints_satisfied_p
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=4 Bug ID: 4 Summary: internal compiler error: trying to capture 'f' in instantiation of generic lambda within constraints_satisfied_p Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- In godbolt gcc 11.0.1 20210408: int main() { auto f = [](int) { return true; }; return [&](auto i) requires (f(sizeof(i))) { return 99; }(12); } In substitution of 'template main():: [with auto:1 = int]': 3:62: required from here 3:35: internal compiler error: trying to capture 'f' in instantiation of generic lambda 3 | return [&](auto i) requires (f(sizeof(i))) { return 99; }(12); | ~~^~~~ 0x1d00959 internal_error(char const*, ...) 0x800866 add_capture(tree_node*, tree_node*, tree_node*, bool, bool) 0x800bfa add_default_capture(tree_node*, tree_node*, tree_node*) 0x73fdda constraints_satisfied_p(tree_node*, tree_node*) 0x955913 fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool, bool) 0x6e2ace build_op_call(tree_node*, vec**, int) 0x981ab5 finish_call_expr(tree_node*, vec**, bool, bool, int) 0x8e224d c_parse_file() 0xa612e2 c_common_parse_file() Without the default-capture the program is rejected with note: constraints not satisfied [...] error: 'f' is not captured which I think is incorrect since `f` is not odr-used; clang and MSVC accept either way.
[Bug c++/97402] New: Value of dependent partial-concept-id is not usable in a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97402 Bug ID: 97402 Summary: Value of dependent partial-concept-id is not usable in a constant expression Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- #include template void f(T x) { std::same_as auto y = x; } int main() { f(1); } In file included from :1: : In instantiation of 'void f(T) [with T = int]': :5:17: required from here .../gcc-trunk-20201013/include/c++/11.0.0/concepts:57:15: required for the satisfaction of '__same_as<_Tp, _Up>' [with _Tp = int; _Up = T] .../gcc-trunk-20201013/include/c++/11.0.0/concepts:57:32: error: the value of 'std::is_same_v' is not usable in a constant expression 57 | concept __same_as = std::is_same_v<_Tp, _Up>; | ~^~~ In file included from .../gcc-trunk-20201013/include/c++/11.0.0/concepts:44, from :1: .../gcc-trunk-20201013/include/c++/11.0.0/type_traits:3220:25: note: 'std::is_same_v' used in its own initializer 3220 | inline constexpr bool is_same_v = __is_same(_Tp, _Up); | ^ :3:26: error: deduced initializer does not satisfy placeholder constraints 3 | std::same_as auto y = x; | ^ :3:26: note: constraints not satisfied https://godbolt.org/z/qGT5xe Changing std::same_as to std::same_as makes it compile OK. Feels a little like 96410.
[Bug c++/96675] New: tautological-compare warning emitted for NTTP bitwise comparison
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96675 Bug ID: 96675 Summary: tautological-compare warning emitted for NTTP bitwise comparison Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- template constexpr bool f(char d) { return 'a' <= c && c <= 'z' ? (d | 0x20) == c : 'A' <= c && c <= 'Z' ? (d & ~0x20) == c : d == c; } static_assert(f<'p'>('P')); In instantiation of 'constexpr bool f(char) [with char c = 'p']': :7:21: required from here :4:44: warning: bitwise comparison always evaluates to false [-Wtautological-compare] 4 | 'A' <= c && c <= 'Z' ? (d & ~0x20) == c : |^~~~ Per godbolt, this happened somewhere between 10.1.0 and 10.2.0. Motivation is https://github.com/capnproto/capnproto/commit/c38629e5a4b8ce9561b81cb23ea5fc39cbd93eb7
[Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349 --- Comment #12 from Ed Catmur --- (In reply to Richard Biener from comment #11) > Note that for C++ types you can apply memcpy to the placement new is not > needed since object re-use terminates lifetime of the previous object and > starts lifetime of a new one. Under P0593R6 it has the effect of implicitly creating objects on demand. Effectively it is supposed to "curse" the double and "bless" the subsequent uint64_t. Invoking P0593 may be jumping the gun since it's still in LWG, but Richard (Smith) wants it retroactively applied to C++20 IS as a DR, and that could still happen. > Note that while your example performs memcpy dances you are probably > after a solution that elides all generated code? Sure, I assume that memcpy of anything smaller than a page will be elided :) > Note that I do not belive making your examples work as you intend is > possible in an actual implementation without sacrifying all > type-based alias analysis. Ouch. You might be asked to if and when P0593 goes in (again, assuming I've understood it correctly). Would it be appropriate to find out what Ville thinks?
[Bug c++/95349] Using std::launder(p) produces unexpected behavior where (p) produces expected behavior
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349 --- Comment #9 from Ed Catmur --- (In reply to Jonathan Wakely from comment #4) > I don't know the answer, and I don't know why it's useful to try this anyway. If I'm reading P0593 correctly (I may not be), this would be a valid implementation of start_lifetime_as: template inline T* start_lifetime_as(void* p) { std::byte storage[sizeof(T)]; std::memcpy(storage, p, sizeof(T)); auto q = new (p) std::byte[sizeof(T)]; std::memcpy(q, storage, sizeof(T)); auto t = reinterpret_cast(q); return std::launder(t); } But this has the same issue: https://godbolt.org/z/YYtciP
[Bug c++/95344] New: Wparentheses (assignment used as truth value) on parenthesized ternary conditional E2
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95344 Bug ID: 95344 Summary: Wparentheses (assignment used as truth value) on parenthesized ternary conditional E2 Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- void f(int i) { bool b = false; if (i == 99 ? (b = true) : false) ; } warning: suggest parentheses around assignment used as truth value [-Wparentheses] 3 | if (i == 99 ? (b = true) : false) | ~~~^~~ Per Godbolt, issue exists from 9.1 through current trunk (11.0).
[Bug c++/82099] internal compiler error: in type_throw_all_p, at cp/except.c:1186 when using a function pointer for templated predicate
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82099 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #6 from Ed Catmur --- Workaround: force computation of noexcept of predicate before it is required: noexcept(+baz); or simply baz;
[Bug c++/36566] Cannot bind packed field
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566 --- Comment #11 from Ed Catmur --- (In reply to rene.rahn from comment #10) > I know this is quite old now. But can someone explain me why using `#pragma > pack(push, 1)` does work then? `#pragma pack` has sharper edges. It will let you take unaligned pointers/references, but they will break on architectures that enforce alignment or under ubsan, and the compiler won't try to save you. This is for compatibility with other (older) compilers that behave similarly. nb. Since 4.7 `short& pit(oj.s);` gives error: cannot bind packed field 'oj.Squeeze::s' to 'short int&' (comment #1). Since 9.1 `short* ppit();` and `VerticallyChallenged();` give warning: taking address of packed member of 'Squeeze' may result in an unaligned pointer value [-Waddress-of-packed-member] (comment #3). And the typedef `using un_short = short __attribute__((aligned(1)));` (comment #6) gives a way to form references and pointers to these fields and pass them around. (Note that you have to cast the field access at point of use.) So I think this can be RESOLVED FIXED version 9.1.
[Bug c++/92015] New: internal compiler error: in cxx_eval_array_reference, at cp/constexpr.c:2568
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92015 Bug ID: 92015 Summary: internal compiler error: in cxx_eval_array_reference, at cp/constexpr.c:2568 Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ed at catmur dot uk Target Milestone: --- when indexing a char array initialized from a string literal in constexpr context: struct S1 { char c[6] {'h', 'e', 'l', 'l', 'o', 0}; }; struct S2 { char c[6] = "hello"; }; static_assert(S1{}.c[0] == 'h');// OK static_assert(S2{}.c[0] == 'h');// ICE Expected: both static_asserts pass. According to Godbolt, this ICE was introduced between 8.3 and 9.1, and is still present in 10.0.
[Bug c++/80667] [c++1z] ice segfault on partial specialization with non-type template parameter
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80667 --- Comment #3 from Ed Catmur --- Agreed, gcc is OK since 7.2, selecting the latter partial specialization (as with -std=c++14). OK to mark as fixed.
[Bug c++/80871] Template partial ordering considered non-ambiguous with deduced and non-deduced parameter packs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #2 from Ed Catmur --- See also #80438
[Bug c++/80871] Template partial ordering considered non-ambiguous with deduced and non-deduced parameter packs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80871 --- Comment #3 from Ed Catmur --- Sorry. See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80438
[Bug c++/80438] Variadic template class argument deduction failure from variadic constructor deduction guide
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80438 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #2 from Ed Catmur --- Workaround: add an N=1+ deduction guide: // existing template foo(Us...) -> foo; // additional, for g++ template foo(U, Us...) -> foo;
[Bug c++/66476] Erroneous initializer_list lifetime extension from temporary initializer_list
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66476 Ed Catmur changed: What|Removed |Added Status|REOPENED|RESOLVED Resolution|--- |INVALID --- Comment #3 from Ed Catmur --- Ah wait, guaranteed copy elision since C++17 should fix this, right? So g++ is actually correct now, even if it was wrong before.
[Bug c++/66476] Erroneous initializer_list lifetime extension from temporary initializer_list
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66476 Ed Catmur changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|INVALID |--- --- Comment #2 from Ed Catmur --- Yes... but the initializer_list that the array backs is itself temporary; it has lifetime only for the duration of the call to the copy constructor. From https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48562#c6 : > I think that a warning against "({...})" would be useful too >// fine >initializer_list a{1, 2, 3}; >// this is bad >initializer_list b({1, 2, 3}); > Second one is bad because it will destroy the array after initializing 'b', > and won't lengthen the lifetime (because it will use the copy/move > constructor).
[Bug c/66425] (void) cast doesn't suppress __attribute__((warn_unused_result))
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 Ed Catmur changed: What|Removed |Added CC||ed at catmur dot uk --- Comment #34 from Ed Catmur --- Note that a logical negation prior to cast to void is sufficient to suppress the warning: int void_cast_should_not_warn() { (void) !foo(); // ^-- here return 0; }