[Bug c++/114625] requires { T{}; } wrongly returns false when T{} is ill-formed while in concept
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
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
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
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
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
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
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)
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
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
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
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
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
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?
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
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 {}
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