$ cat bug.cc int main() { auto f = [](const auto &g, auto x) { return g(g, x); }; f(f, 0); } $ gcc -std=c++14 bug.cc bug.cc: In instantiation of ‘main()::<lambda(const auto:1&, auto:2)> [with auto:1 = main()::<lambda(const auto:1&, auto:2)>; auto:2 = int]’: bug.cc:3:9: required from here bug.cc:2:48: error: use of ‘main()::<lambda(const auto:1&, auto:2)> [with auto:1 = main()::<lambda(const auto:1&, auto:2)>; auto:2 = int]’ before deduction of ‘auto’ 2 | auto f = [](const auto &g, auto x) { return g(g, x); }; | ~^~~~~~ This error message is technically correct, but the `auto' it refers to is very misleading here: it's the implicit `auto' return type of the lambda expression, rather than either `auto' argument type. The message can become clearer if changed to "use of ... before deduction of _return type_". GCC version: 9.3.1
Created attachment 48534 [details] `gcc -v' and bug.ii stuff
All 4 compilers (GCC, ICC, clang and MSVC) I have access to reject this code.
(In reply to Andrew Pinski from comment #2) > All 4 compilers (GCC, ICC, clang and MSVC) I have access to reject this code. Could you post their error messages for comparison?
Literally all of the same error message even: clang: <source>:2:47: error: function 'operator()<(lambda at <source>:2:12), int>' with deduced return type cannot be used before it is defined auto f = [](const auto &g, auto x) { return g(g, x); }; ^ <source>:3:4: note: in instantiation of function template specialization 'main()::(anonymous class)::operator()<(lambda at <source>:2:12), int>' requested here f(f, 0); ^ <source>:2:12: note: 'operator()<(lambda at <source>:2:12), int>' declared here auto f = [](const auto &g, auto x) { return g(g, x); }; ^ ICC: <source>(2): error: cannot deduce the return type of function "lambda [](const auto &, auto)->auto [with <auto-1>=lambda [](const auto &, auto)->auto, <auto-2>=int]" (declared at line 2); it has not been defined auto f = [](const auto &g, auto x) { return g(g, x); }; ^ detected during instantiation of function "lambda [](const auto &, auto)->auto [with <auto-1>=lambda [](const auto &, auto)->auto, <auto-2>=int]" at line 3 compilation aborted for <source> (code 2) MSVC: <source>(2): error C3779: 'main::<lambda_1>::operator ()': a function that returns 'auto' cannot be used before it is defined <source>(2): note: see declaration of 'main::<lambda_1>::operator ()' <source>(3): note: see reference to function template instantiation 'auto main::<lambda_1>::operator ()<main::<lambda_1>,int>(const _T1 &,_T2) const' being compiled with [ _T1=main::<lambda_1>, _T2=int ]