[Bug c++/109935] CTAD for an aggregate with a dependent base class doesn't work

2023-05-23 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2023-05-22 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2023-05-22 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2023-04-25 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2021-05-07 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2021-03-09 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2021-02-18 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2021-02-15 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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

2021-02-15 Thread oleksandr.koval.dev at gmail dot com via Gcc-bugs
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