[Bug c++/109935] CTAD for an aggregate with a dependent base class doesn't work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109935 --- Comment #5 from Oleksandr Koval --- Right, my understanding is that it should generate hypothetical constructor like: ```cpp template struct C : public B { C(B); }; ``` and it doesn't work with braced-initializer list like in this example: ```cpp template void test(B){} B{1}; // ok test({1}); // error ``` So maybe it should not work by the current rules. I came up with this example while reading https://wg21.link/P2582R1 (CTAD for inherited ctor-s) which makes this possible: ```cpp template struct S1{ S1(T){} }; template struct S2 : S1{ using S1::S1; }; S2{1}; // OK, deduced S2 ``` It's unfortunate that it doesn't work when we remove explicit constructors so I'm trying to understand whether it's not allowed by current language rules or just is not implemented by compilers.
[Bug c++/109935] CTAD for an aggregate with a dependent base class doesn't work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109935 --- Comment #2 from Oleksandr Koval --- According to cppreference, Clang has not implemented CTAD for aggregates at all so no surprise here. I know that gcc/msvc rejects it but I don't understand why.
[Bug c++/109935] New: CTAD for an aggregate with a dependent base class doesn't work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109935 Bug ID: 109935 Summary: CTAD for an aggregate with a dependent base class doesn't work Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- https://godbolt.org/z/s9cM719n3 ```cpp template struct B { T x; }; template struct C : public B { }; void f(){ B{1}; // works as expected C{{1}}; // error } ``` Not 100% sure about it but I see no reason for `C{{1}}` not to work. Extra set of braces is required because B is a dependent base class and brace elision doesn't work for it (https://eel.is/c++draft/over.match.class.deduct#1.5.1).
[Bug c++/109623] New: constexpr restrictions are not relaxed enough
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109623 Bug ID: 109623 Summary: constexpr restrictions are not relaxed enough Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- https://godbolt.org/z/eo8K3Ehqq ```cpp #include struct S{ constexpr S() = default; // error, not implicitly constexpr constexpr S(){}// this works std::unordered_map m; }; ``` My understanding is that in C++23 this should be allowed because the only restriction for constexpr constructors and destructors is the absence of virtual base classes.
[Bug libstdc++/100470] New: std::is_nothrow_move_constructible incorrect behavior for explicitly defaulted members
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100470 Bug ID: 100470 Summary: std::is_nothrow_move_constructible incorrect behavior for explicitly defaulted members Product: gcc Version: 11.1.0 URL: https://godbolt.org/z/hqeh4E3M8 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- Explicit exception specification should be the actual one, hence, S2 should NOT be nothrow-constructible. #include struct S1{ S1(S1&&) noexcept(false); }; struct S2{ S2(S2&&) noexcept(false) = default; }; struct S3{ S3(S3&&) noexcept(false){} }; struct S4{ S4(S4&&) = default; }; static_assert(!std::is_nothrow_move_constructible_v); // OK static_assert(!std::is_nothrow_move_constructible_v); // failed static_assert(!std::is_nothrow_move_constructible_v); // OK static_assert(std::is_nothrow_move_constructible_v); // OK
[Bug c++/99495] New: constexpr virtual destructor is used before its definition
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99495 Bug ID: 99495 Summary: constexpr virtual destructor is used before its definition Product: gcc Version: 11.0 URL: https://godbolt.org/z/GGY6aa Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- I found this while playing with constexpr virtual functions. This code gives "error: 'virtual constexpr Derived2::~Derived2()' used before its definition". Error always refers to the last variable, e.g. if we swap d1 and d2 declarations, it will complain about d1. If x is decalred without constexpr it works fine. struct Base{ constexpr virtual ~Base() = default; virtual int Get() const = 0;// non-constexpr }; struct Derived1 : Base{ constexpr int Get() const override { return 1; } }; struct Derived2 : Base{ constexpr int Get() const override { return 2; } }; constexpr auto GetSum(){ const Derived1 d1; const Derived2 d2; const Base* pb1 = &d1; const Base* pb2 = &d2; return pb1->Get() + pb2->Get(); } constexpr // error int x = GetSum(); // OK if not in constexpr context
[Bug c++/99152] New: Wrong type of implicitly captured by-value unevaluated operand
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99152 Bug ID: 99152 Summary: Wrong type of implicitly captured by-value unevaluated operand Product: gcc Version: 11.0 URL: https://godbolt.org/z/sYsTqa Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- This example was taken directly from the standard(http://eel.is/c++draft/expr.prim.id.unqual#3): void f() { float x, &r = x; auto l = [=] () { static_assert(std::is_same_v); static_assert(std::is_same_v); static_assert(std::is_same_v); // fails, decltype((r)) is float& static_assert(std::is_same_v); }; }
[Bug c++/99107] New: Ignored inconsistent parameter/arguments types in variadic templates
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99107 Bug ID: 99107 Summary: Ignored inconsistent parameter/arguments types in variadic templates Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- template struct Types {}; struct X {}; struct Y {}; struct Z {}; struct W { operator Y(){return Y{};} operator Z(){return Z{};} }; template void ctor(Types, Ts...){} This is an error: ctor(Types{}, X{}, Y{}, W{}); because of mismatch during deduction: first pack is deduced to but second is , conversions are not allowed here. Here we have the same mismatched types but, currently, it's OK: ctor(Types{}, {}, {}, W{}); I've noticed this problem while playing with CTAD for aggregates: template struct F : Types, Ts... {}; // error, as expected F f3 = {Types{}, X{}, W{}}; // should also be an error F f4 = {Types{}, {}, W{}};
[Bug c++/99103] New: Initializer-list constructors in CTAD for vector is still wrong
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99103 Bug ID: 99103 Summary: Initializer-list constructors in CTAD for vector is still wrong Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oleksandr.koval.dev at gmail dot com Target Milestone: --- According to P0702R1, initializer-list constructors for T should be ignored during CTAD if list contains a single element of cv U when U is a specialization or a child of T. It works for simple things like: std::vector v{std::vector{1, 2, 3}}; static_assert(std::is_same_v>); // fine But not for this one: template auto make_vector(const Args&... elems){ return std::vector{elems...}; } auto v2 = make_vector(std::vector{1,2,3}); static_assert(std::is_same_v>); // fails static_assert(std::is_same_v>>); // OK