Message ID | 537DB4F9.2060605@oracle.com |
---|---|
State | New |
Headers | show |
On 05/22/2014 04:27 AM, Paolo Carlini wrote: > lambda-ice7.C:8:9: error: cannot capture by value ‘a’ of incomplete type > ‘A’ > [=](){a;}; > ^ All the carets in your mail are in the first column; is this one in the right place for you? Let's not print out the expression, we've been moving away from that. Maybe "capture by value of incomplete type 'A'". OK with that change. > 4- Finally, something I noticed while working on add_capture: right above the new check there is: > > type = lambda_capture_field_type (initializer, explicit_init_p); > if (by_reference_p) > { > type = build_reference_type (type); > if (!real_lvalue_p (initializer)) > error ("cannot capture %qE by reference", initializer); > } > > now, interestingly, nothing in the testsuite exercises this error. And, so far, I failed to create a testcase for it. The Standard too doesn't seem to me so clear about that. Ideas?!? void f() { [&x=1]{} } Jason
Hi, On 05/22/2014 08:13 PM, Jason Merrill wrote: > On 05/22/2014 04:27 AM, Paolo Carlini wrote: >> lambda-ice7.C:8:9: error: cannot capture by value ‘a’ of incomplete type >> ‘A’ >> [=](){a;}; >> ^ > > All the carets in your mail are in the first column; is this one in > the right place for you? It would be definitely wrong, but it's just that I did something wrong with the mailer, it shows Ok on my shell, under the a. Look at the column, 9, which is fine. > Let's not print out the expression, we've been moving away from that. > Maybe "capture by value of incomplete type 'A'". Good. I wanted to ask about that. Also, by copy instead of by value, right? Because the Standard always talks about copy (likewise clang). > > OK with that change. > >> 4- Finally, something I noticed while working on add_capture: right >> above the new check there is: >> >> type = lambda_capture_field_type (initializer, explicit_init_p); >> if (by_reference_p) >> { >> type = build_reference_type (type); >> if (!real_lvalue_p (initializer)) >> error ("cannot capture %qE by reference", initializer); >> } >> >> now, interestingly, nothing in the testsuite exercises this error. >> And, so far, I failed to create a testcase for it. The Standard too >> doesn't seem to me so clear about that. Ideas?!? > > void f() > { > [&x=1]{} > } Right, thanks. I'm probably going to add it, at some point. Me, I was looking for something not using C++14 initializers, I think in that case is more difficult!?! Paolo.
On 05/22/2014 02:26 PM, Paolo Carlini wrote: > Good. I wanted to ask about that. Also, by copy instead of by value, > right? Because the Standard always talks about copy (likewise clang). Yes. > Right, thanks. I'm probably going to add it, at some point. Me, I was looking for something not using C++14 initializers, I think in that case is more difficult!?! The error can only occur with a C++14 initializer; a (captured) variable is always an lvalue. Jason
Index: cp/lambda.c =================================================================== --- cp/lambda.c (revision 210682) +++ cp/lambda.c (working copy) @@ -456,6 +456,9 @@ add_capture (tree lambda, tree id, tree orig_init, 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; @@ -492,8 +495,17 @@ add_capture (tree lambda, tree id, tree orig_init, 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 ("cannot capture by value %qE of incomplete " + "type %qT", initializer, type); + cxx_incomplete_type_inform (type); + return error_mark_node; + } + } } /* Add __ to the beginning of the field name so that user code Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 210682) +++ cp/typeck2.c (working copy) @@ -434,6 +434,9 @@ abstract_virtuals_error (abstract_class_use use, t 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)); Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C =================================================================== --- testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C (revision 0) +++ testsuite/g++.dg/cpp0x/lambda/lambda-ice13.C (working copy) @@ -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" } +} Index: testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C =================================================================== --- testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C (revision 210682) +++ testsuite/g++.dg/cpp0x/lambda/lambda-ice7.C (working copy) @@ -5,5 +5,5 @@ struct A; // { dg-message "forward declara void foo(A& a) { - [=](){a;}; // { dg-error "invalid use of incomplete type" } + [=](){a;}; // { dg-error "incomplete type" } }