From 34fdd6b31e8b715b2dfb1490b7c77b4eddacc8df Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 17 Aug 2013 21:06:49 -0400 Subject: [PATCH] re PR c++/58083 (ICE with lambda as default parameter of a template function) PR c++/58083 * name-lookup.c (push_class_level_binding_1): It's OK to push a lambda type after the enclosing type is complete. From-SVN: r201822 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/name-lookup.c | 6 ++-- .../g++.dg/cpp0x/lambda/lambda-defarg5.C | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7ada1ae4f64..71dcfb8935f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-08-17 Jason Merrill + + PR c++/58083 + * name-lookup.c (push_class_level_binding_1): It's OK to push a + lambda type after the enclosing type is complete. + 2013-08-17 Gabriel Dos Reis * error.c (dump_scope): Add a cxx_pretty_printer parameter. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0fe02469138..cf6c7573ced 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3062,8 +3062,10 @@ push_class_level_binding_1 (tree name, tree x) if (name == error_mark_node) return false; - /* Check for invalid member names. */ - gcc_assert (TYPE_BEING_DEFINED (current_class_type)); + /* Check for invalid member names. But don't worry about a default + argument-scope lambda being pushed after the class is complete. */ + gcc_assert (TYPE_BEING_DEFINED (current_class_type) + || LAMBDA_TYPE_P (TREE_TYPE (decl))); /* Check that we're pushing into the right binding level. */ gcc_assert (current_class_type == class_binding_level->this_entity); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C new file mode 100644 index 00000000000..d85918dd07b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C @@ -0,0 +1,30 @@ +// PR c++/58083 +// { dg-do compile { target c++11 } } + +namespace details { +struct iterator_concept_checker +{ + typedef char yes_type; + typedef char (&no_type)[2]; + + template + static no_type test(...); + + template + static yes_type test( + int* + , void (*)(T) = [](T it) + { + auto copy = T{it}; // copy constructible + copy = it; // copy assignable + copy.~T(); // destroyable + ++it; // incrementable + } + ); +}; +} + +int main() +{ + details::iterator_concept_checker::test(0); +}