Here when we deduced the return type for a lambda to an uninstantiated class template specialization, we built the new RESULT_DECL, and called layout_decl, before we called complete_type_or_else, so the RESULT_DECL wasn't properly laid out.
Tested x86_64-pc-linux-gnu, applying to trunk, 6, 5.
commit f0113b081c53fa70be614f6d1f63953a3919b85f Author: Jason Merrill <ja...@redhat.com> Date: Thu Jul 21 18:20:17 2016 -0400 PR c++/69223 - ICE with deduced template return type. * semantics.c (apply_deduced_return_type): Call complete_type_or_else before building the new RESULT_DECL. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 19daeff..63063b8 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9279,6 +9279,10 @@ apply_deduced_return_type (tree fco, tree return_type) if (TREE_TYPE (result) == return_type) return; + if (!processing_template_decl && !VOID_TYPE_P (return_type) + && !complete_type_or_else (return_type, NULL_TREE)) + return; + /* We already have a DECL_RESULT from start_preparsed_function. Now we need to redo the work it and allocate_struct_function did to reflect the new type. */ @@ -9294,8 +9298,6 @@ apply_deduced_return_type (tree fco, tree return_type) if (!processing_template_decl) { - if (!VOID_TYPE_P (TREE_TYPE (result))) - complete_type_or_else (TREE_TYPE (result), NULL_TREE); bool aggr = aggregate_value_p (result, fco); #ifdef PCC_STATIC_STRUCT_RETURN cfun->returns_pcc_struct = aggr; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C new file mode 100644 index 0000000..68ac29c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce3.C @@ -0,0 +1,15 @@ +// PR c++/69223 +// { dg-do compile { target c++11 } } + +template <class T> struct A +{ + T x[20]; +}; + +int main() +{ + auto l = [](const A<int>& i){ return i; }; + A<int> a; + + l(a); +}