[Bug c++/114625] requires { T{}; } wrongly returns false when T{} is ill-formed while in concept

2024-04-15 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114625

--- Comment #5 from Ted Lyngmo  ---
@Andrew, the title change seems wrong. It wrongly returns true when T{} is
ill-formed.

[Bug c++/114625] requires { T{}; } wrongly accepted when T{} is ill-formed while in concept

2024-04-07 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114625

Ted Lyngmo  changed:

   What|Removed |Added

Summary|requires { T{}; } wrongly   |requires { T{}; } wrongly
   |accepted when T{} is|accepted when T{} is
   |ill-formed  |ill-formed while in concept
 CC||ted at lyncon dot se

--- Comment #1 from Ted Lyngmo  ---
The assertion correctly fails with this though:
```
static_assert(requires { d{}; });
```

[Bug c++/114625] New: requires { T{}; } wrongly accepted when T{} is ill-formed

2024-04-07 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114625

Bug ID: 114625
   Summary: requires { T{}; } wrongly accepted when T{} is
ill-formed
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

This program compiles but I'd expect both `static_assert`s to refuse it since
`d x{};` is invalid.
```
#include 

template
concept default_initializable =
std::constructible_from &&
requires { T{}; } &&
requires { ::new T; };

struct b { explicit b(auto...) {} };
struct d : b {};

int main() {
static_assert(default_initializable);
static_assert(std::default_initializable);
//d x{}; // ERROR
}
```

[Bug c++/114504] New: Non-structural type accepted as non-type template parameter type

2024-03-27 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114504

Bug ID: 114504
   Summary: Non-structural type accepted as non-type template
parameter type
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

gcc accepts `NonStructuralType` as a non-type template parameter type below:
```
struct StructuralType1 {
constexpr StructuralType1(int A) : a(A) {}
int a;
};

struct NonStructuralType {
constexpr NonStructuralType(int A) : a(A) {}
private:
int a;
};

template 
concept is_structural = requires { [] {}; };

static_assert(is_structural,
  "BUG! StructuralType1 is not structural");

static_assert(!is_structural,
  "BUG! NontStructuralType is structural");

int main() {}
```
I was expecting `[]{}` to fail in the concept. The program compiles with
clang++, icx and MSVC.

[Bug c++/112349] New: ranges::max makes unecessary copies

2023-11-02 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112349

Bug ID: 112349
   Summary: ranges::max makes unecessary copies
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

From:
https://stackoverflow.com/questions/77409266/why-does-gcc-copy-object-for-each-comparison-in-stdrangesmax

OP's sample program shows a copy being made for each comparison:
```
#include 
#include 
#include 
#include 

struct A {
A() = default;
A(const A&) { std::cout << "Copy\n"; }
A(A&&) noexcept { std::cout << "Move\n"; }

A& operator=(const A&) {
std::cout << "Copy assigned\n";
return *this;
}
A& operator=(A&&) noexcept {
std::cout << "Move assigned\n";
return *this;
}

int x = 10;
};

int main() {
std::vector vec(10);
std::cout << "Init\n";
std::cout << std::ranges::max(vec, [](const auto& a, const auto& b) {
 std::cout << "cmp" << std::endl;
 return a.x < b.x;
 }).x;
}
```
I _think_ the proper solution is to not copy `__first` into `__tmp` in
`operator()`:
```
template, _Proj>>
   _Comp = ranges::less>
  requires indirectly_copyable_storable,
range_value_t<_Range>*>
  constexpr range_value_t<_Range>
  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
  {
auto __first = ranges::begin(__r);
auto __last = ranges::end(__r);
__glibcxx_assert(__first != __last);
auto __result = *__first;
while (++__first != __last)
  {
auto __tmp = *__first;   // <- COPY
if (std::__invoke(__comp,
  std::__invoke(__proj, __result),
  std::__invoke(__proj, __tmp)))
  __result = std::move(__tmp);
  }
return __result;
  }
```
By changing it to
```c++
auto& __tmp = *__first;
```
...or just supplying `*__first` to `std::__invoke` it doesn't do copies in OP's
example but it may have other consequences. Worth looking in to anyway.

[Bug c++/93595] [c++20] function call, substitution failure of template paramter with a lambda default in template context

2023-07-11 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93595

--- Comment #8 from Ted Lyngmo  ---
:-) Ok I tried understanding the Status by reading
https://gcc.gnu.org/bugzilla/page.cgi?id=fields.html#bug_status but it doesn't
mention NEW. But ok, as long as it's actually a confirmed bug, I'm good.

[Bug c++/93595] [c++20] function call, substitution failure of template paramter with a lambda default in template context

2023-07-11 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93595

--- Comment #6 from Ted Lyngmo  ---
@Andrew Pinski: Shouldn't the status be "CONFIRMED" rather than "NEW"?

[Bug c++/110604] New: template argument deduction failed with decltype(lambda)

2023-07-09 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110604

Bug ID: 110604
   Summary: template argument deduction failed with
decltype(lambda)
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

Compiling this in C++20 mode on trunk (https://godbolt.org/z/dW5cf3WrK):
```
template
struct foo {
template
void bar() {}
};

int main() {
[[maybe_unused]] auto v = foo();

v.bar<>();
v.bar();
}
```
Results in the following error:
```
: In function 'int main()':
:10:12: error: no matching function for call to 'foo::bar<>()'
   10 | v.bar<>();
  | ~~~^~
:4:10: note: candidate: 'template void foo<
 >::bar() [with  = void]'
4 | void bar() {}
  |  ^~~
:4:10: note:   template argument deduction/substitution failed:
:11:10: error: no matching function for call to 'foo::bar()'
   11 | v.bar();
  | ~^~
:4:10: note: candidate: 'template void foo<
 >::bar() [with  = void]'
4 | void bar() {}
  |  ^~~
:4:10: note:   template argument deduction/substitution failed:
```
Possibly a duplicate of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102721,
but I'm not 100% sure.

[Bug c++/108303] New: lookup failes with requires clause on non-template friend function of a class template

2023-01-05 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108303

Bug ID: 108303
   Summary: lookup failes with requires clause on non-template
friend function of a class template
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

This works up to 12.2 (inclusive) on godbolt but fails on trunk:
```
template 
struct base {
friend void foo(const Derived& d)
requires requires { bar(d); } // removing this makes it work
{
bar(d);
}
};

namespace adl {
struct S : base {
friend void bar(const S&) {}
};
}  // namespace adl

void test(adl::S const& s) {
foo(s);  // error: 'foo' was not declared in this scope
}
```

[Bug c++/106110] Expected ambiguity but it resolves fine

2022-06-27 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106110

--- Comment #1 from Ted Lyngmo  ---
Sorry, the helper variable template should be:
```
template 
static constexpr bool is_foo_call_ambiguous_v =
is_foo_call_ambiguous::value;
```
It gives the same result: https://godbolt.org/z/bKbn8Gre7

[Bug c++/106110] New: Expected ambiguity but it resolves fine

2022-06-27 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106110

Bug ID: 106110
   Summary: Expected ambiguity but it resolves fine
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

I made a type trait to test if a call to a function using certain arguments
would be ambiguous or not, but in the below example, where I expected that
calling the function `foo` with a `std::tuple` would result in
ambiguity, it is not detected as such.
```
#include 
#include 

template 
void foo(const std::tuple&) { std::cout << "T\n"; }

template 
void foo(const std::tuple&) { std::cout << "Ts...\n"; }

template 
struct is_foo_call_ambiguous {
static std::true_type test(...);

template 
static auto test(AArgs&&...)
-> decltype(foo(std::declval()...), std::false_type{});

static constexpr bool value =
decltype(test(std::declval()...))::value;
};

template 
static constexpr bool is_foo_call_ambiguous_v =
is_foo_call_ambiguous::value;

int main() {
// expected `true` here, but it reports `false`:
std::cout << is_foo_call_ambiguous_v> << '\n';

// `false` as expected:
std::cout << is_foo_call_ambiguous_v> << '\n';
}
```
As can be seen here, clang++ reports it to be ambiguous:
https://godbolt.org/z/YTevWvbzz

If I understand it correctly, the added tiebreaker
(https://cplusplus.github.io/CWG/issues/1395.html) for variadic templates
should not apply here.

[Bug c++/105637] [12 Regression] Wrong overload selected in base class

2022-06-03 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105637

--- Comment #5 from Ted Lyngmo  ---
Excellent and thanks!

[Bug c++/105637] New: [11 Regression] Wrong overload selected in base class

2022-05-17 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105637

Bug ID: 105637
   Summary: [11 Regression] Wrong overload selected in base class
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

This compiles fine in 11.3 but selects the non-const `BaseClass` overload in
12.1:
```
struct BaseClass {
// Commenting out this non-const function out will fix the compilation:
int baseDevice() { return 1; }
int baseDevice() const { return 2; }
};

template 
struct DerivedClass : BaseClass {};

template 
struct TopClass : DerivedClass {
public:
virtual int failsToCompile() const {
// This should choose to call the const function, but it tries to call
// the non-const version.
return BaseClass::baseDevice();   // error!
//return this->baseDevice();  // works
//return DerivedClass::baseDevice(); // works
}
};

int main() {
TopClass x; 
}
```

[Bug c++/104565] New: One too many `this`es in parsing?

2022-02-16 Thread ted at lyncon dot se via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104565

Bug ID: 104565
   Summary: One too many `this`es in parsing?
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ted at lyncon dot se
  Target Milestone: ---

Regression between g++ 9.4 and 10.1:
```
struct apa {
constexpr auto n() const { return 3; }
};

template 
constexpr auto f() {
apa foo;
int{foo.n()};  // no matching function for call to 'apa::n(apa*)'
}

int main() {}
```

[Bug c++/86581] constexpr variable allows uninitialized member of anonymous struct inside union

2019-08-14 Thread ted at lyncon dot se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86581

Ted Lyngmo  changed:

   What|Removed |Added

 CC||ted at lyncon dot se

--- Comment #2 from Ted Lyngmo  ---
Does this bug cover this case? This compiles with g++ but clang++ gives "error:
constexpr union constructor does not initialize any member".

template 
union test {
constexpr test() noexcept {}
T member;
};

int main() {
test a;
}

[Bug c++/81486] Class template argument deduction fails with (), succeeds with {}

2018-11-02 Thread ted at lyncon dot se
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81486

Ted Lyngmo  changed:

   What|Removed |Added

 CC||ted at lyncon dot se

--- Comment #3 from Ted Lyngmo  ---
A comparison between g++ 8.2 and clang++ 6.0.1

g++ -fsanitize=undefined -std=c++17 -Wall -Wextra -Wshadow -Weffc++ -pedantic
-pedantic-errors -Wc++14-compat -Wc++17-compat -c test.cpp
clang++ -fsanitize=undefined -std=c++17 -Wall -Wextra -Wshadow -Weffc++
-pedantic -pedantic-errors -Wc++14-compat -Wc++17-compat -c test.cpp

#include 

std::less lt_g;
std::greater gt_g;
// ok in g++ 8.2
// clang++ 6.0.1:
//  error: declaration of variable 'lt' with deduced type 'std::less' requires
an initializer
//  error: declaration of variable 'gt' with deduced type 'std::greater'
requires an initializer

auto lt_c = std::less();
auto gt_c = std::greater();
// ok in clang++ 6.0.1
// g++ 8.2:
//  error: cannot deduce template arguments for ‘less’ from ()
//  error: cannot deduce template arguments for ‘greater’ from ()

auto lt_b = std::less{};
auto gt_b = std::greater{};
// ok in both