Message ID | ZCU+huPw218pdDqo@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Fix up ICE in build_min_non_dep_op_overload [PR109319] | expand |
On 3/30/23 03:47, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs, because grok_array_decl during > processing_template_decl handling of a non-dependent subscript > emits a -Wcomma-subscript pedwarn, we decide to pass to the > single index argument the index expressions as if it was wrapped > with () around it, but then when preparing it for later instantiation > we don't actually take that into account and ICE on a mismatch of > number of index arguments (the overload expects a single index, > testcase has two index expressions in this case). > For non-dependent subscript which are builtin subscripts we also > emit the same pedwarn and don't ICE, but emit the same pedwarn > again whenever we instantiate it, which is also IMHO undesirable, > it is enough to warn once during parsing the template. > > The following patch fixes it by turning even the original index expressions > (those which didn't go through make_args_non_dependent) into a single > index using comma expression(s). > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. > 2023-03-30 Jakub Jelinek <jakub@redhat.com> > > PR c++/109319 > * decl2.cc (grok_array_decl): After emitting a pedwarn for > -Wcomma-subscript, if processing_template_decl set orig_index_exp > to compound expr from orig_index_exp_list. > > * g++.dg/cpp23/subscript14.C: New test. > > --- gcc/cp/decl2.cc.jj 2023-03-20 20:29:34.000000000 +0100 > +++ gcc/cp/decl2.cc 2023-03-29 15:17:14.952173134 +0200 > @@ -474,11 +474,23 @@ grok_array_decl (location_t loc, tree ar > &overload, complain); > } > else > - /* If it would be valid albeit deprecated expression in C++20, > - just pedwarn on it and treat it as if wrapped in (). */ > - pedwarn (loc, OPT_Wcomma_subscript, > - "top-level comma expression in array subscript " > - "changed meaning in C++23"); > + { > + /* If it would be valid albeit deprecated expression in > + C++20, just pedwarn on it and treat it as if wrapped > + in (). */ > + pedwarn (loc, OPT_Wcomma_subscript, > + "top-level comma expression in array subscript " > + "changed meaning in C++23"); > + if (processing_template_decl) > + { > + orig_index_exp > + = build_x_compound_expr_from_vec (orig_index_exp_list, > + NULL, complain); > + if (orig_index_exp == error_mark_node) > + expr = error_mark_node; > + release_tree_vector (orig_index_exp_list); > + } > + } > } > } > } > @@ -519,6 +531,15 @@ grok_array_decl (location_t loc, tree ar > return error_mark_node; > } > index_exp = idx; > + if (processing_template_decl) > + { > + orig_index_exp > + = build_x_compound_expr_from_vec (orig_index_exp_list, > + NULL, complain); > + release_tree_vector (orig_index_exp_list); > + if (orig_index_exp == error_mark_node) > + return error_mark_node; > + } > } > > if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) > --- gcc/testsuite/g++.dg/cpp23/subscript14.C.jj 2023-03-29 15:29:46.037076158 +0200 > +++ gcc/testsuite/g++.dg/cpp23/subscript14.C 2023-03-29 15:34:18.645051075 +0200 > @@ -0,0 +1,42 @@ > +// PR c++/109319 > +// { dg-do compile { target c++11 } } > +// { dg-options "" } > + > +struct A { static int &operator[] (int x) { static int a[2]; return a[x]; } }; // { dg-warning "may be a static member function only with" "" { target c++20_down } } > +struct B { int &operator[] (int x) { static int b[2]; return b[x]; } }; > +int c[2]; > + > +template <typename T, typename U, typename V> > +int > +foo () > +{ > + A a; > + ++a[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + B b; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++b[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++c[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + T d; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++d[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + U e; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++e[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + extern V f[2]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++f[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + return 0; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > +} > + > +int f[2]; > + > +int > +main () > +{ > + A a; > + ++a[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + B b; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++b[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + ++c[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } > + foo <A, B, int> (); // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } > + if (a.operator[] (1) != 3 || b.operator[] (1) != 3 || c[1] != 2 || f[1] != 1) > + __builtin_abort (); > +} > > Jakub >
--- gcc/cp/decl2.cc.jj 2023-03-20 20:29:34.000000000 +0100 +++ gcc/cp/decl2.cc 2023-03-29 15:17:14.952173134 +0200 @@ -474,11 +474,23 @@ grok_array_decl (location_t loc, tree ar &overload, complain); } else - /* If it would be valid albeit deprecated expression in C++20, - just pedwarn on it and treat it as if wrapped in (). */ - pedwarn (loc, OPT_Wcomma_subscript, - "top-level comma expression in array subscript " - "changed meaning in C++23"); + { + /* If it would be valid albeit deprecated expression in + C++20, just pedwarn on it and treat it as if wrapped + in (). */ + pedwarn (loc, OPT_Wcomma_subscript, + "top-level comma expression in array subscript " + "changed meaning in C++23"); + if (processing_template_decl) + { + orig_index_exp + = build_x_compound_expr_from_vec (orig_index_exp_list, + NULL, complain); + if (orig_index_exp == error_mark_node) + expr = error_mark_node; + release_tree_vector (orig_index_exp_list); + } + } } } } @@ -519,6 +531,15 @@ grok_array_decl (location_t loc, tree ar return error_mark_node; } index_exp = idx; + if (processing_template_decl) + { + orig_index_exp + = build_x_compound_expr_from_vec (orig_index_exp_list, + NULL, complain); + release_tree_vector (orig_index_exp_list); + if (orig_index_exp == error_mark_node) + return error_mark_node; + } } if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) --- gcc/testsuite/g++.dg/cpp23/subscript14.C.jj 2023-03-29 15:29:46.037076158 +0200 +++ gcc/testsuite/g++.dg/cpp23/subscript14.C 2023-03-29 15:34:18.645051075 +0200 @@ -0,0 +1,42 @@ +// PR c++/109319 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { static int &operator[] (int x) { static int a[2]; return a[x]; } }; // { dg-warning "may be a static member function only with" "" { target c++20_down } } +struct B { int &operator[] (int x) { static int b[2]; return b[x]; } }; +int c[2]; + +template <typename T, typename U, typename V> +int +foo () +{ + A a; + ++a[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + B b; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++b[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++c[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + T d; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++d[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + U e; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++e[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + extern V f[2]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++f[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + return 0; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } +} + +int f[2]; + +int +main () +{ + A a; + ++a[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + B b; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++b[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + ++c[0, 1]; // { dg-warning "top-level comma expression in array subscript changed meaning" "" { target c++23 } } + foo <A, B, int> (); // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++20_only } .-1 } + if (a.operator[] (1) != 3 || b.operator[] (1) != 3 || c[1] != 2 || f[1] != 1) + __builtin_abort (); +}