Message ID | 015b4c9b-5405-7391-42d2-941106b41931@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] PR 85227 ("[7/8/ Regression] ICE with structured binding of a forward declared variable") | expand |
On Fri, Apr 6, 2018 at 5:01 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > here, for an incomplete type we ICE pretty soon in find_decomp_class_base. > Comparing to other cases too, I convinced myself that trying to complete the > type is Ok. Also, it seems that in these functions we want to talk about > structured binding and use an appropriate location, thus no > complete_type_or_maybe_complain. Tested x86_64-linux. What if, in a template, we defer trying to do bindings to an incomplete type, so extern struct A a; template<int> void f() { auto [x] = a; } struct A { int i; }; int main() { f<0>(); } works? Probably with a pedwarn, as in xref_basetypes or cp_parser_dot_deref_incomplete. Jason
Hi, On 06/04/2018 19:04, Jason Merrill wrote: > On Fri, Apr 6, 2018 at 5:01 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote: >> here, for an incomplete type we ICE pretty soon in find_decomp_class_base. >> Comparing to other cases too, I convinced myself that trying to complete the >> type is Ok. Also, it seems that in these functions we want to talk about >> structured binding and use an appropriate location, thus no >> complete_type_or_maybe_complain. Tested x86_64-linux. > What if, in a template, we defer trying to do bindings to an incomplete type, so > > extern struct A a; > > template<int> > void f() > { > auto [x] = a; > } > > struct A { int i; }; > > int main() > { > f<0>(); > } > > works? Probably with a pedwarn, as in xref_basetypes or > cp_parser_dot_deref_incomplete. Ok... I tested the very simple patch below, wasnt sure between pedwarn (loc, 0, ...) and pedwarn (loc, OPT_Wpedantic, ...) but probably we want to former in order not to be too permissive (for comparison, clang rejects with an hard error both tests). What do you think? Thanks! Paolo. ///////////////////// Index: cp/decl.c =================================================================== --- cp/decl.c (revision 259184) +++ cp/decl.c (working copy) @@ -7756,6 +7756,9 @@ cp_finish_decomp (tree decl, tree first, unsigned error_at (loc, "cannot decompose lambda closure type %qT", type); goto error_out; } + else if (processing_template_decl && !COMPLETE_TYPE_P (type)) + pedwarn (loc, 0, "structured binding refers to incomplete class type %qT", + type); else { tree btype = find_decomp_class_base (loc, type, NULL_TREE); Index: testsuite/g++.dg/cpp1z/decomp43.C =================================================================== --- testsuite/g++.dg/cpp1z/decomp43.C (nonexistent) +++ testsuite/g++.dg/cpp1z/decomp43.C (working copy) @@ -0,0 +1,10 @@ +// PR c++/85227 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +extern struct A a; + +template<int> void foo() +{ + auto[i] = a; // { dg-warning "incomplete" } +} // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } Index: testsuite/g++.dg/cpp1z/decomp44.C =================================================================== --- testsuite/g++.dg/cpp1z/decomp44.C (nonexistent) +++ testsuite/g++.dg/cpp1z/decomp44.C (working copy) @@ -0,0 +1,18 @@ +// PR c++/85227 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +extern struct A a; + +template<int> +void f() +{ + auto [x] = a; // { dg-warning "incomplete" } +} // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } + +struct A { int i; }; + +int main() +{ + f<0>(); +}
OK. On Fri, Apr 6, 2018 at 3:05 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > Hi, > > On 06/04/2018 19:04, Jason Merrill wrote: >> >> On Fri, Apr 6, 2018 at 5:01 AM, Paolo Carlini <paolo.carlini@oracle.com> >> wrote: >>> >>> here, for an incomplete type we ICE pretty soon in >>> find_decomp_class_base. >>> Comparing to other cases too, I convinced myself that trying to complete >>> the >>> type is Ok. Also, it seems that in these functions we want to talk about >>> structured binding and use an appropriate location, thus no >>> complete_type_or_maybe_complain. Tested x86_64-linux. >> >> What if, in a template, we defer trying to do bindings to an incomplete >> type, so >> >> extern struct A a; >> >> template<int> >> void f() >> { >> auto [x] = a; >> } >> >> struct A { int i; }; >> >> int main() >> { >> f<0>(); >> } >> >> works? Probably with a pedwarn, as in xref_basetypes or >> cp_parser_dot_deref_incomplete. > > Ok... I tested the very simple patch below, wasnt sure between pedwarn (loc, > 0, ...) and pedwarn (loc, OPT_Wpedantic, ...) but probably we want to former > in order not to be too permissive (for comparison, clang rejects with an > hard error both tests). What do you think? > > Thanks! > Paolo. > > /////////////////////
Index: cp/decl.c =================================================================== --- cp/decl.c (revision 259156) +++ cp/decl.c (working copy) @@ -7310,6 +7310,13 @@ cp_finish_decl (tree decl, tree init, bool init_co static tree find_decomp_class_base (location_t loc, tree type, tree ret) { + if (!COMPLETE_TYPE_P (complete_type (type))) + { + error_at (loc, "structured binding refers to incomplete class type %qT", + type); + return error_mark_node; + } + bool member_seen = false; for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (TREE_CODE (field) != FIELD_DECL Index: testsuite/g++.dg/cpp1z/decomp42.C =================================================================== --- testsuite/g++.dg/cpp1z/decomp42.C (nonexistent) +++ testsuite/g++.dg/cpp1z/decomp42.C (working copy) @@ -0,0 +1,10 @@ +// PR c++/85227 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +extern struct A a; + +template<int> void foo() +{ + auto[i] = a; // { dg-error "incomplete" } +} // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }