diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2021e2df26e..a594e9393f3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-05-22 Paolo Carlini + + PR c++/61088 + * lambda.c (add_capture): Enforce that capture by value requires + complete type. + * typeck2.c (cxx_incomplete_type_inform): Early return if + TYPE_MAIN_DECL is null. + 2014-05-21 Jonathan Wakely PR c/61271 diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index bb6014b23d0..e72682c9487 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -453,6 +453,9 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, initializer = build_x_compound_expr_from_list (initializer, ELK_INIT, tf_warning_or_error); type = TREE_TYPE (initializer); + if (type == error_mark_node) + return error_mark_node; + if (array_of_runtime_bound_p (type)) { vla = true; @@ -489,8 +492,16 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, error ("cannot capture %qE by reference", initializer); } else - /* Capture by copy requires a complete type. */ - type = complete_type (type); + { + /* Capture by copy requires a complete type. */ + type = complete_type (type); + if (!dependent_type_p (type) && !COMPLETE_TYPE_P (type)) + { + error ("capture by copy of incomplete type %qT", type); + cxx_incomplete_type_inform (type); + return error_mark_node; + } + } } /* Add __ to the beginning of the field name so that user code diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index e98942d7d2a..18bc25f766d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -434,6 +434,9 @@ abstract_virtuals_error (abstract_class_use use, tree type) void cxx_incomplete_type_inform (const_tree type) { + if (!TYPE_MAIN_DECL (type)) + return; + location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)); tree ptype = strip_top_quals (CONST_CAST_TREE (type)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4e86b8dd633..a799992e502 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-05-22 Paolo Carlini + + PR c++/61088 + * g++.dg/cpp0x/lambda/lambda-ice13.C: New. + * g++.dg/cpp0x/lambda/lambda-ice7.C: Adjust. + 2014-05-22 Xinliang David Li * g++.dg/ipa/devirt-15.C: Fix expected message. diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C new file mode 100644 index 00000000000..4c611ad8ee1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C @@ -0,0 +1,14 @@ +// PR c++/61088 +// { dg-do compile { target c++11 } } + +void f() +{ + typedef void (*X) (); + X x[] = { [x](){} }; // { dg-error "incomplete type" } +} + +void g() +{ + typedef void (X) (); + X x[] = { [x](){} }; // { dg-error "array of functions|not declared" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C index 1d7dfcc933e..6f8272aeb60 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C @@ -5,5 +5,5 @@ struct A; // { dg-message "forward declaration" } void foo(A& a) { - [=](){a;}; // { dg-error "invalid use of incomplete type" } + [=](){a;}; // { dg-error "incomplete type" } }