[Bug c++/71446] Incorrect overload resolution when using designated initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446 --- Comment #4 from Roman Perepelitsa --- Please take a look at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446#c1. This code compiles. Given that it contains `{.value = 0}`, one would reasonably expect that it creates an instance of a struct with the data member `value` set to zero. However, it doesn't. The literal `{.value = 0}` creates an instance of type `std::initialize_list`. This is very misleading. The code should either not compile or do what was intended (which is also what C++20 requires and what clang does).
[Bug c++/69957] New: Ambiguous overload due to incorrect partial ordering of V<> and V
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69957 Bug ID: 69957 Summary: Ambiguous overload due to incorrect partial ordering of V<> and V Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com Target Milestone: --- === Program #1 === template struct V {}; template void Foo(V, V) {} template void Foo(V<>, V) {} int main() { Foo(V<>(), V<>()); } Expected: compiles. Actual: error: call of overloaded 'Foo(V<>, V<>)' is ambiguous. === Program #2 === (This might be a different bug) template struct V {}; template void Foo(V, V) {} template void Foo(V<>, Us&&...) {} int main() { Foo(V<>(), V<>()); } Expected: error: call of overloaded 'Foo(V<>, V<>)' is ambiguous. Actual: compiles.
[Bug c++/57433] Local classes have an associated namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57433 Roman Perepelitsa changed: What|Removed |Added CC||roman.perepelitsa at gmail dot com --- Comment #1 from Roman Perepelitsa --- Here's another example: template void Bar(T t) { Foo(t); } template void Foo(T) {} void Test() { Bar([]{}); } Clang rejects this code (expected behaviour), gcc accepts it (unexpected behaviour). Gcc erroneously finds Foo() by ADL. A more elaborate example: namespace n1 { template void Foo(T) {} auto F = []{}; auto G = []{ return []{}; }(); } // namespace n1 namespace n2 { void Test() { Foo(n1::F); // gcc and clang accept Foo(n1::G); // gcc accepts, clang rejects } } // namespace n2 F is a lambda defined in namespace scope of n1. When Test() calls Foo(n1::F), n1::Foo() is found via ADL. Nothing surprising here. Now, G is also a lambda from n1 but it's defined locally, in a function. When gcc resolves Foo(n1::G), it finds n1::Foo() by ADL, but clang doesn't. We can use structs instead of lambdas and the effect will be the same. We also can use regular non-template functions: namespace n1 { struct S {}; auto MakeQ = []{ struct Q {}; return Q(); }; using Q = decltype(MakeQ()); void Foo(S) {} void Foo(Q) {} } // namespace n1 namespace n2 { void Test() { Foo(n1::S()); // gcc and clang accept Foo(n1::Q()); // gcc accepts, clang rejects } } // namespace n2
[Bug c++/70544] New: Overload resolution with explicitly specified template arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70544 Bug ID: 70544 Summary: Overload resolution with explicitly specified template arguments Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com Target Milestone: --- When compiling this program: template void F(Args&&...); template int F(Args&&...); int main() { int{F(0)}; } Expected behavior: compile error (call to `F` is ambiguous). Actual behaviour: compiles successfully. Comment from Richard Smith: "I suspect this might be fallout from GCC's workaround for core issue 1395 (after substituting explicitly-specified template arguments, the first 'F' has one pack element deduced and the second 'F' has none, so I suspect the second may look more specialized under GCC's approach to 1395 but not Clang's)." Note that the following program gets rejected by GCC (as expected): template void F(T); template void F(U); int main() { F(0); }
[Bug c++/71382] New: Unary plus doesn't works with pointers to instantiations of function templates
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71382 Bug ID: 71382 Summary: Unary plus doesn't works with pointers to instantiations of function templates Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com Target Milestone: --- This compiles: void F(); void G() { +(&F); } This doesn't: template void F(); void G() { +(&F); } error: wrong type argument to unary plus Expected behaviour: both examples compile.
[Bug c++/71446] New: Incorrect overload resolution when using designated initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446 Bug ID: 71446 Summary: Incorrect overload resolution when using designated initializers Product: gcc Version: 5.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com Target Milestone: --- Actual behaviour: the following program compiles. Expected behaviour: doesn't compile. #include struct S { int value; }; int F(S); char* F(std::initializer_list); char* p = F({.value = 0}); The compiler should either resolve `F({.value = 0})` as `int F(S)` or generate a `sorry, not implemented` error. It shouldn't resolve it as `char* F(std::initializer_list)`.
[Bug c++/71446] Incorrect overload resolution when using designated initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71446 --- Comment #1 from Roman Perepelitsa --- The same bug can lead to incorrect behaviour at run time. #include #include struct S { int value; }; void F(S) { puts("right"); } void F(std::initializer_list) { puts("wrong"); } int main() { F({.value = 0}); } Should print "right" but actually prints "wrong".
[Bug libstdc++/71096] std::get did not work for nested derived classes from std::tuple if one element is empty
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71096 Roman Perepelitsa changed: What|Removed |Added CC||roman.perepelitsa at gmail dot com --- Comment #1 from Roman Perepelitsa --- Slightly simpler example (no user-defined templates): #include struct A {}; struct B : std::tuple {}; int main() { std::tuple t; std::get<0>(t); // compile error } Note that both A and B are empty in the sense of std::is_empty. If you make either of them non-empty by adding a data member, the code will compile. #include struct A { char c; }; // not empty struct B : std::tuple {}; int main() { std::tuple t; std::get<0>(t); // compiles } Likewise, the code compiles when getting the element by type instead of index. #include struct A {}; struct B : std::tuple {}; int main() { std::tuple t; std::get(t); // compiles }
[Bug middle-end/68360] GCC bitfield processing code is very inefficient
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68360 Roman Perepelitsa changed: What|Removed |Added CC||roman.perepelitsa at gmail dot com --- Comment #3 from Roman Perepelitsa --- Here's another example where GCC generates suboptimal code for bitfield initialization on x64: https://godbolt.org/g/WeqAr5. #include struct S { S(uint32_t a, uint32_t b); uint32_t a : 2; uint32_t b : 30; }; S::S(uint32_t a, uint32_t b) : a(a), b(b) {} Here's the code generated for the constructor when compiled with -O2. Clang 3.9: andl$3, %esi leal(%rsi,%rdx,4), %eax movl%eax, (%rdi) retq GCC 7.0: movl%esi, %eax movzbl (%rdi), %esi andl$3, %eax andl$-4, %esi orl %eax, %esi leal0(,%rdx,4), %eax movb%sil, (%rdi) movl(%rdi), %edx andl$3, %edx orl %eax, %edx movl%edx, (%rdi) ret
[Bug c++/60044] New: Template argument of alias template not evaluated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60044 Bug ID: 60044 Summary: Template argument of alias template not evaluated Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com $ cat test.cc #include template using Void = void; template struct Foo { const char* value = "primary template"; }; template struct Foo> { const char* value = "specialization"; }; int main() { puts(Foo().value); } $ g++ -std=c++11 test.cc && ./a.out specialization Expected output: primary template
[Bug c++/62115] [5 Regression] ICE with invalid default argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62115 Roman Perepelitsa changed: What|Removed |Added CC||roman.perepelitsa at gmail dot com --- Comment #4 from Roman Perepelitsa --- r216124 has also fixed another bug, which may result in valid code being rejected and also in incorrect code generation for valid code. #include struct Base { int value; }; struct Derived : Base {}; void Foo(int&&) {} int main() { Derived d; Foo(std::move(d).value); } Before r216124 this program produced the following compile error: test.cc: In function 'int main()': test.cc:10:25: error: cannot bind 'int' lvalue to 'int&&' Foo(std::move(d).value); ^ test.cc:6:6: error: initializing argument 1 of 'void Foo(int&&)' void Foo(int&&) {} If function Foo() was overloaded for const int& and int&, or if it used perfect forwarding, it would result in successful compilation and incorrect runtime behaviour. Would it be possible to backport the fix to gcc-4_9-branch?
[Bug libstdc++/61947] New: Ambiguous calls when constructing std::tuple
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61947 Bug ID: 61947 Summary: Ambiguous calls when constructing std::tuple Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com #include struct ConvertibleToAny { template operator T() const { return T(); } }; int main() { std::tuple t(ConvertibleToAny{}); } Produces: third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4: error: call to constructor of '_Head_base<0UL, (anonymous namespace)::ConvertibleToAny &&, __empty_not_final::value>' is ambiguous _Base(std::forward<_UHead>(__head)) { } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4: note: in instantiation of function template specialization 'std::_Tuple_impl<0, (anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous namespace)::ConvertibleToAny, void>' requested here : _Inherited(std::forward<_UElements>(__elements)...) { } ^ experimental/users/romanp/tuple_bug/tuple-bug.cc:13:34: note: in instantiation of function template specialization 'std::tuple<(anonymous namespace)::ConvertibleToAny &&>::tuple<(anonymous namespace)::ConvertibleToAny, void>' requested here std::tuple t(ConvertibleToAny{}); ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate is the implicit move constructor struct _Head_base<_Idx, _Head, false> ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:128:12: note: candidate constructor (the implicit copy constructor) has been implicitly deleted third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:142:7: note: candidate constructor _Head_base(__uses_alloc0) The call shouldn't be ambiguous. It should pick the following constructor: [tuple.cnstr] template explicit tuple(UTypes&&... u); Requires: sizeof...(Types) == sizeof...(UTypes). is_constructible::value is true for all i. Effects: Initializes the elements in the tuple with the corresponding value in std::forward(u). is_constructible::value is true, so the precondition is satisfied. This bug affects std::bind as it's built on top of std::tuple. #include struct ConvertibleToAny { template operator T() const { return T(); } }; void Sink(int) {} int main() { std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{}); } Error: third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:262:4: error: call to constructor of '_Head_base<0UL, (anonymous namespace)::ConvertibleToAny &&, __empty_not_final::value>' is ambiguous _Base(std::forward<_UHead>(__head)) { } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:405:4: note: in instantiation of function template specialization 'std::_Tuple_impl<0, (anonymous namespace)::ConvertibleToAny &&>::_Tuple_impl<(anonymous namespace)::ConvertibleToAny, void>' requested here : _Inherited(std::forward<_UElements>(__elements)...) { } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/tuple:868:14: note: in instantiation of function template specialization 'std::tuple<(anonymous namespace)::ConvertibleToAny &&>::tuple<(anonymous namespace)::ConvertibleToAny, void>' requested here { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } ^ third_party/crosstool/v17/stable/gcc-x86_64-grtev3-linux-gnu/x86_64-grtev3-linux-gnu/include/c++/4.8.x-google/functional:1354:13: note: in instantiation of function template specialization 'std::forward_as_tuple<(anonymous namespace)::ConvertibleToAny>' requested here std::forward_as_tuple(std::forward<_Args>(__args)...), ^ experimental/users/romanp/tuple_bug/tuple-bug.cc:15:41: note: in instantiation of function template specialization 'std::_Bind))(int)>::operator()<(anonymous namespace)::ConvertibleToAny, void>' requested here std::bind(Sink, std::placeholders::_1)(ConvertibleToAny{});
[Bug c++/62227] New: Templated move not elided
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62227 Bug ID: 62227 Summary: Templated move not elided Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: roman.perepelitsa at gmail dot com #include struct S { S(int) {} S(const S&) = default; // (1) template // (2) S(S&& other) { puts("move"); } }; int main() { S s = 42; (void)s; } This program unexpectedly prints "move". The expected output is empty (move is elided). The program prints nothing (as expected) if any of the following is done: - Line (1) is removed. - Line (2) is removed. - The program is compiled with clang.
[Bug c++/60044] Template argument of alias template not evaluated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60044 Roman Perepelitsa changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #3 from Roman Perepelitsa --- Fixed by r217250.
[Bug c++/63875] Bogus unused-but-set-parameter warning when expanding a variadic template argument pack
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875 Roman Perepelitsa changed: What|Removed |Added CC||roman.perepelitsa at gmail dot com --- Comment #3 from Roman Perepelitsa --- This appears to be fixed in gcc 6.1: the provided snippet compiles cleanly.