https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70942
Bug ID: 70942 Summary: [c++14] Incorrect deduction of generic lambda `auto&&` parameter Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: vittorio.romeo at outlook dot com Target Milestone: --- Created attachment 38410 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38410&action=edit Minimal code example g++ 6.1 was recently introduced into Arch Linux's testing repositories, and some of my code that successfully compiled with g++ 5.3.0 does not compile anymore. I've made a minimal example: gcc.godbolt.org link: https://godbolt.org/g/73RTHf // This code compiles with g++ 5.3.0 // This does not compile with g++ 6.1 #include <type_traits> #include <utility> #include <tuple> #define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__) struct sinker { template <typename T> void sink(T&) { } }; template <typename T, typename TF> void caller(T& v, TF&& f) { sinker s; f(s, v); } template <typename T> void interface(T& v) { return caller(v, [](auto& xs, auto&& xv) -> decltype(auto) { xs.sink(FWD(xv)); }); } int main() { int x = 0; interface(x); } This is the reported error: : In instantiation of ‘get_impl(T&)::<lambda(auto:1&, auto:2&&)> [with auto:1 = sinker; auto:2 = int; T = int]’: :25:58: required by substitution of ‘template<class auto:1, class auto:2> get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>::operator decltype (((get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>)0u).operator()(static_cast<auto:1&>(<anonymous>), static_cast<auto:2&&>(<anonymous>))) (*)(auto:1&, auto:2&&)() const [with auto:1 = sinker; auto:2 = int]’ :19:6: required from ‘void chunk_fn_impl(T&, TF&&) [with T = int; TF = get_impl(T&) [with T = int]::<lambda(auto:1&, auto:2&&)>]’ :25:25: required from ‘void get_impl(T&) [with T = int]’ :36:15: required from here :27:13: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’ xs.sink(FWD(md)); ^~ :10:10: note: initializing argument 1 of ‘void sinker::sink(T&) [with T = int]’ void sink(T&) ^~~~ --- Changing: return caller(v, [](auto& xs, auto&& xv) -> decltype(auto) to: return caller(v, [](auto& xs, auto& xv) -> decltype(auto) allows the code to successfully compile. --- I do not understand why this error is happening, as `xv` is being perfectly-forwarded and the `FWD(xv)` call should produce a lvalue reference. Note that the code worked as intended in g++ 5.3.0 and clang++ 3.7. gcc.godbolt.org link: https://godbolt.org/g/73RTHf Try compiling with multiple g++ versions and changing `auto&&` to `auto&`. Is this a g++ 6.1 bug? Or was the code incorrectly compiling with previous versions of g++ and clang++? --- More information: http://stackoverflow.com/questions/37023265