* [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) @ 2017-11-29 22:35 Jakub Jelinek 2017-11-30 2:42 ` Martin Sebor 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-11-29 22:35 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches Hi! If tsize doesn't fit into uhwi, then it obviously can't match the number of identifiers in the structured binding declaration. While we could use compare_tree_int and avoid that way this conversion to uhwi (though, compare_tree_int does that anyway), for the normal uhwi case we have special cases in cnt_mismatch shared by the other kinds of structured bindings that handle smaller and larger cases separately, so I think it is better to do it this way. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-11-29 Jakub Jelinek <jakub@redhat.com> PR c++/83205 * decl.c (cp_finish_decomp): Handle the case when tsize is not error_mark_node, but doesn't fit into uhwi. * g++.dg/cpp1z/decomp32.C: New test. --- gcc/cp/decl.c.jj 2017-11-28 22:23:34.000000000 +0100 +++ gcc/cp/decl.c 2017-11-29 15:00:24.487658715 +0100 @@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first, "constant expression", type); goto error_out; } + if (!tree_fits_uhwi_p (tsize)) + { + error_at (loc, "%u names provided while %qT decomposes into " + "%E elements", count, type, tsize); + goto error_out; + } eltscnt = tree_to_uhwi (tsize); if (count != eltscnt) goto cnt_mismatch; --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj 2017-11-29 15:08:59.215378903 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C 2017-11-29 15:10:31.576244649 +0100 @@ -0,0 +1,24 @@ +// PR c++/83205 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { int i; }; +struct B { int i; }; +namespace std { + template <typename T> struct tuple_size; + template <> struct tuple_size<A> { + static constexpr int value = -1; + }; +#ifdef __SIZEOF_INT128__ + template <> struct tuple_size<B> { + static constexpr unsigned __int128 value = -1; + }; +#endif +} + +auto [a] = A{}; // { dg-error "1 names provided while 'A' decomposes into -1 elements" } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } +#ifdef __SIZEOF_INT128__ +auto [b] = B{}; // { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } } + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 } +#endif Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) 2017-11-29 22:35 [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jakub Jelinek @ 2017-11-30 2:42 ` Martin Sebor 2017-11-30 9:26 ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek 2017-12-15 19:01 ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill 0 siblings, 2 replies; 12+ messages in thread From: Martin Sebor @ 2017-11-30 2:42 UTC (permalink / raw) To: Jakub Jelinek, Jason Merrill; +Cc: gcc-patches On 11/29/2017 03:32 PM, Jakub Jelinek wrote: > Hi! > > If tsize doesn't fit into uhwi, then it obviously can't match the number of > identifiers in the structured binding declaration. While we could use > compare_tree_int and avoid that way this conversion to uhwi (though, > compare_tree_int does that anyway), for the normal uhwi case we have special > cases in cnt_mismatch shared by the other kinds of structured bindings > that handle smaller and larger cases separately, so I think it is better > to do it this way. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2017-11-29 Jakub Jelinek <jakub@redhat.com> > > PR c++/83205 > * decl.c (cp_finish_decomp): Handle the case when tsize is not > error_mark_node, but doesn't fit into uhwi. > > * g++.dg/cpp1z/decomp32.C: New test. > > --- gcc/cp/decl.c.jj 2017-11-28 22:23:34.000000000 +0100 > +++ gcc/cp/decl.c 2017-11-29 15:00:24.487658715 +0100 > @@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first, > "constant expression", type); > goto error_out; > } > + if (!tree_fits_uhwi_p (tsize)) > + { > + error_at (loc, "%u names provided while %qT decomposes into " When count is 1 as in the test below the error isn't grammatically correct ("1 names"). I see that the same message is already issued elsewhere in the function so this seems like an opportunity to use the right form here and also fix the other one at the same time or in a followup. The error_n function exists to issue the right form for the language, singular or plural. It's not as convenient when the sentence contains two terms that may be singular or plural, but that can also be dealt with. Martin > + "%E elements", count, type, tsize); > + goto error_out; > + } > eltscnt = tree_to_uhwi (tsize); > if (count != eltscnt) > goto cnt_mismatch; > --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj 2017-11-29 15:08:59.215378903 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C 2017-11-29 15:10:31.576244649 +0100 > @@ -0,0 +1,24 @@ > +// PR c++/83205 > +// { dg-do compile { target c++11 } } > +// { dg-options "" } > + > +struct A { int i; }; > +struct B { int i; }; > +namespace std { > + template <typename T> struct tuple_size; > + template <> struct tuple_size<A> { > + static constexpr int value = -1; > + }; > +#ifdef __SIZEOF_INT128__ > + template <> struct tuple_size<B> { > + static constexpr unsigned __int128 value = -1; > + }; > +#endif > +} > + > +auto [a] = A{}; // { dg-error "1 names provided while 'A' decomposes into -1 elements" } > + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } > +#ifdef __SIZEOF_INT128__ > +auto [b] = B{}; // { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } } > + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 } > +#endif > > Jakub > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 2:42 ` Martin Sebor @ 2017-11-30 9:26 ` Jakub Jelinek 2017-11-30 11:59 ` Nathan Sidwell 2017-12-15 19:01 ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill 1 sibling, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-11-30 9:26 UTC (permalink / raw) To: Martin Sebor, Nathan Sidwell, Jason Merrill; +Cc: gcc-patches On Wed, Nov 29, 2017 at 06:19:04PM -0700, Martin Sebor wrote: > > --- gcc/cp/decl.c.jj 2017-11-28 22:23:34.000000000 +0100 > > +++ gcc/cp/decl.c 2017-11-29 15:00:24.487658715 +0100 > > @@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first, > > "constant expression", type); > > goto error_out; > > } > > + if (!tree_fits_uhwi_p (tsize)) > > + { > > + error_at (loc, "%u names provided while %qT decomposes into " > > When count is 1 as in the test below the error isn't grammatically > correct ("1 names"). I see that the same message is already issued > elsewhere in the function so this seems like an opportunity to use > the right form here and also fix the other one at the same time or > in a followup. The error_n function exists to issue the right form > for the language, singular or plural. It's not as convenient when > the sentence contains two terms that may be singular or plural, > but that can also be dealt with. Here is an incremental patch to deal with that on top of the previously posted patch, ok for trunk if it passes testing? Note, not using inform_n in this !tree_fits_uhwi_p case, because gettext doesn't recommend that for negative values and the other values printed there (the very large ones) are printed using hexadecimal where also I think human plural forms are rarely useful. 2017-11-30 Jakub Jelinek <jakub@redhat.com> * decl.c (cp_finish_decomp): Split up count != eltscnt and !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n to handle plural forms properly. * g++.dg/cpp1z/decomp3.C: Adjust for structured binding count mismatch diagnostics split into error and warning with plural forms. * g++.dg/cpp1z/decomp10.C: Likewise. * g++.dg/cpp1z/decomp32.C: Likewise. --- gcc/cp/decl.c.jj 2017-11-30 09:44:19.000000000 +0100 +++ gcc/cp/decl.c 2017-11-30 09:57:44.539504854 +0100 @@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first, { cnt_mismatch: if (count > eltscnt) - error_at (loc, "%u names provided while %qT decomposes into " - "%wu elements", count, type, eltscnt); + error_n (loc, count, + "%u name provided for structured binding", + "%u names provided for structured binding", count); else - error_at (loc, "only %u names provided while %qT decomposes into " - "%wu elements", count, type, eltscnt); + error_n (loc, count, + "only %u name provided for structured binding", + "only %u names provided for structured binding", count); + inform_n (loc, eltscnt != (unsigned long) eltscnt + ? (eltscnt % 1000000) + 1000000 : eltscnt, + "while %qT decomposes into %wu element", + "while %qT decomposes into %wu elements", + type, eltscnt); goto error_out; } eltype = TREE_TYPE (type); @@ -7520,8 +7527,11 @@ cp_finish_decomp (tree decl, tree first, } if (!tree_fits_uhwi_p (tsize)) { - error_at (loc, "%u names provided while %qT decomposes into " - "%E elements", count, type, tsize); + error_n (loc, count, + "%u name provided for structured binding", + "%u names provided for structured binding", count); + inform (loc, "while %qT decomposes into %E elements", + type, tsize); goto error_out; } eltscnt = tree_to_uhwi (tsize); --- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj 2017-09-15 18:11:04.000000000 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp3.C 2017-11-30 10:09:42.756619330 +0100 @@ -51,16 +51,21 @@ int arr[4]; void test3 (A &b, B c) { - auto [ d, e, f ] = arr; // { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto [ l, m ] = b; // { dg-error "only 2 names provided while 'A' decomposes into 3 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto & [ n, o, p, q ] = b; // { dg-error "4 names provided while 'A' decomposes into 3 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } + auto [ d, e, f ] = arr; // { dg-error "only 3 names provided" } + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided" } + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto [ l, m ] = b; // { dg-error "only 2 names provided" } + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto & [ n, o, p, q ] = b; // { dg-error "4 names provided" } + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } auto [] { c }; // { dg-error "empty structured binding declaration" } // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto [ r, s ] = c; // { dg-error "2 names provided while 'B' decomposes into 1 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } + auto [ r, s ] = c; // { dg-error "2 names provided" } + // { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } } --- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj 2017-09-15 18:11:04.000000000 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp10.C 2017-11-30 10:03:08.356491129 +0100 @@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; } // { dg-e struct A2 { int i,j; } a2; template<> struct std::tuple_size<A2> { enum { value = 5 }; }; -void f2() { auto [ x ] = a2; } // { dg-error "decomposes into 5" } +void f2() { auto [ x ] = a2; } // { dg-error "only 1 name provided" } + // { dg-message "decomposes into 5" "" { target *-*-* } .-1 } struct A3 { int i,j; } a3; template<> struct std::tuple_size<A3> { enum { value = 1 }; }; --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj 2017-11-30 09:44:19.000000000 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C 2017-11-30 10:09:53.126490397 +0100 @@ -16,9 +16,17 @@ namespace std { #endif } -auto [a] = A{}; // { dg-error "1 names provided while 'A' decomposes into -1 elements" } - // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } +auto [a] = A{}; // { dg-error "1 name provided" } + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } #ifdef __SIZEOF_INT128__ -auto [b] = B{}; // { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } } - // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 } +auto [b] = B{}; // { dg-error "1 name provided" } + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } +auto [c, d] = B{}; // { dg-error "2 names provided" } + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } #endif +auto [e, f, g] = A{}; // { dg-error "3 names provided" } + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 9:26 ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek @ 2017-11-30 11:59 ` Nathan Sidwell 2017-11-30 12:09 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Nathan Sidwell @ 2017-11-30 11:59 UTC (permalink / raw) To: Jakub Jelinek, Martin Sebor, Jason Merrill; +Cc: gcc-patches On 11/30/2017 04:18 AM, Jakub Jelinek wrote: > Here is an incremental patch to deal with that on top of the previously > posted patch, ok for trunk if it passes testing? Note, not using inform_n > in this !tree_fits_uhwi_p case, because gettext doesn't recommend that for > negative values and the other values printed there (the very large ones) are > printed using hexadecimal where also I think human plural forms are rarely > useful. > > 2017-11-30 Jakub Jelinek <jakub@redhat.com> > > * decl.c (cp_finish_decomp): Split up count != eltscnt and > !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n > to handle plural forms properly. > > * g++.dg/cpp1z/decomp3.C: Adjust for structured binding count > mismatch diagnostics split into error and warning with plural > forms. > * g++.dg/cpp1z/decomp10.C: Likewise. > * g++.dg/cpp1z/decomp32.C: Likewise. Ok. > --- gcc/cp/decl.c.jj 2017-11-30 09:44:19.000000000 +0100 > +++ gcc/cp/decl.c 2017-11-30 09:57:44.539504854 +0100 > @@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first, > + inform_n (loc, eltscnt != (unsigned long) eltscnt > + ? (eltscnt % 1000000) + 1000000 : eltscnt, Is such elaboration with the modulo operator necessary? wouldn;t an arbitrary non-unity constant do. (It took me a while to figure out what this was trying to do. At least a comment?) nathan -- Nathan Sidwell ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 11:59 ` Nathan Sidwell @ 2017-11-30 12:09 ` Jakub Jelinek 2017-11-30 13:01 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-11-30 12:09 UTC (permalink / raw) To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches On Thu, Nov 30, 2017 at 06:55:08AM -0500, Nathan Sidwell wrote: > > --- gcc/cp/decl.c.jj 2017-11-30 09:44:19.000000000 +0100 > > +++ gcc/cp/decl.c 2017-11-30 09:57:44.539504854 +0100 > > @@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first, > > > + inform_n (loc, eltscnt != (unsigned long) eltscnt > > + ? (eltscnt % 1000000) + 1000000 : eltscnt, > > Is such elaboration with the modulo operator necessary? wouldn;t an > arbitrary non-unity constant do. (It took me a while to figure out what > this was trying to do. At least a comment?) For english it isn't needed of course. I just followed: https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html "About larger integer types, such as âuintmax_tâ or âunsigned long longâ: they can be handled by reducing the value to a range that fits in an âunsigned longâ. Simply casting the value to âunsigned longâ would not do the right thing, since it would treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you can exploit the fact that all mentioned plural form formulas eventually become periodic, with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large value to another one in the range [1000000, 1999999] that ends in the same 6 decimal digits, you can assume that it will lead to the same plural form selection. This code does this: #include <inttypes.h> uintmax_t nbytes = ...; printf (ngettext ("The file has %"PRIuMAX" byte.", "The file has %"PRIuMAX" bytes.", (nbytes > ULONG_MAX ? (nbytes % 1000000) + 1000000 : nbytes)), nbytes);" I can surely add a comment about that. Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html patch. Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 12:09 ` Jakub Jelinek @ 2017-11-30 13:01 ` Jakub Jelinek 2017-11-30 13:47 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-11-30 13:01 UTC (permalink / raw) To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote: > I just followed: > https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html > > "About larger integer types, such as âuintmax_tâ or âunsigned long longâ: they can be > handled by reducing the value to a range that fits in an âunsigned longâ. Simply > casting the value to âunsigned longâ would not do the right thing, since it would > treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you > can exploit the fact that all mentioned plural form formulas eventually become periodic, > with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large > value to another one in the range [1000000, 1999999] that ends in the same 6 decimal > digits, you can assume that it will lead to the same plural form selection. This code > does this: > > #include <inttypes.h> > uintmax_t nbytes = ...; > printf (ngettext ("The file has %"PRIuMAX" byte.", > "The file has %"PRIuMAX" bytes.", > (nbytes > ULONG_MAX > ? (nbytes % 1000000) + 1000000 > : nbytes)), > nbytes);" > > I can surely add a comment about that. > > Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html > patch. Though, looking at our *_n diagnostic routines, the n argument is actually int there, not unsigned long for some reason. So, either we should fix that (seems ngettext has unsigned long), or the above would need to be (unsigned HOST_WIDE_INT) (int) eltscnt != eltscnt || (int) eltscnt < 0 Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 13:01 ` Jakub Jelinek @ 2017-11-30 13:47 ` Jakub Jelinek 2017-11-30 15:51 ` Pedro Alves 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-11-30 13:47 UTC (permalink / raw) To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches On Thu, Nov 30, 2017 at 01:33:48PM +0100, Jakub Jelinek wrote: > On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote: > > I just followed: > > https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html > > > > "About larger integer types, such as âuintmax_tâ or âunsigned long longâ: they can be > > handled by reducing the value to a range that fits in an âunsigned longâ. Simply > > casting the value to âunsigned longâ would not do the right thing, since it would > > treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you > > can exploit the fact that all mentioned plural form formulas eventually become periodic, > > with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large > > value to another one in the range [1000000, 1999999] that ends in the same 6 decimal > > digits, you can assume that it will lead to the same plural form selection. This code > > does this: > > > > #include <inttypes.h> > > uintmax_t nbytes = ...; > > printf (ngettext ("The file has %"PRIuMAX" byte.", > > "The file has %"PRIuMAX" bytes.", > > (nbytes > ULONG_MAX > > ? (nbytes % 1000000) + 1000000 > > : nbytes)), > > nbytes);" > > > > I can surely add a comment about that. > > > > Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html > > patch. > > Though, looking at our *_n diagnostic routines, the n argument is actually > int there, not unsigned long for some reason. So, either we should fix > that (seems ngettext has unsigned long), or the above would need to be > (unsigned HOST_WIDE_INT) (int) eltscnt != eltscnt || (int) eltscnt < 0 Of course better eltscnt > INT_MAX Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics 2017-11-30 13:47 ` Jakub Jelinek @ 2017-11-30 15:51 ` Pedro Alves 0 siblings, 0 replies; 12+ messages in thread From: Pedro Alves @ 2017-11-30 15:51 UTC (permalink / raw) To: Jakub Jelinek, Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches On 11/30/2017 01:10 PM, Jakub Jelinek wrote: > On Thu, Nov 30, 2017 at 01:33:48PM +0100, Jakub Jelinek wrote: >> On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote: >>> I just followed: >>> https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html >>> >>> "About larger integer types, such as âuintmax_tâ or âunsigned long longâ: they can be >>> handled by reducing the value to a range that fits in an âunsigned longâ. Simply >>> casting the value to âunsigned longâ would not do the right thing, since it would >>> treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you >>> can exploit the fact that all mentioned plural form formulas eventually become periodic, >>> with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large >>> value to another one in the range [1000000, 1999999] that ends in the same 6 decimal >>> digits, you can assume that it will lead to the same plural form selection. This code >>> does this: >>> >>> #include <inttypes.h> >>> uintmax_t nbytes = ...; >>> printf (ngettext ("The file has %"PRIuMAX" byte.", >>> "The file has %"PRIuMAX" bytes.", >>> (nbytes > ULONG_MAX >>> ? (nbytes % 1000000) + 1000000 >>> : nbytes)), >>> nbytes);" >>> >>> I can surely add a comment about that. How about wrapping it in a function to make it self-describing? Something around: /* Comment/url here. */ unsigned long plural_form_for (unsigned HOST_WIDE_INT val) { return (val > ULONG_MAX ? (val % 1000000) + 1000000 : val); } and then: inform_n (loc, plural_form_for (eltscnt), "while %qT decomposes into %wu element", "while %qT decomposes into %wu elements", type, eltscnt); Pedro Alves ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) 2017-11-30 2:42 ` Martin Sebor 2017-11-30 9:26 ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek @ 2017-12-15 19:01 ` Jason Merrill 2017-12-15 19:09 ` Jakub Jelinek 1 sibling, 1 reply; 12+ messages in thread From: Jason Merrill @ 2017-12-15 19:01 UTC (permalink / raw) To: Martin Sebor, Jakub Jelinek; +Cc: gcc-patches On 11/29/2017 08:19 PM, Martin Sebor wrote: > On 11/29/2017 03:32 PM, Jakub Jelinek wrote: >> +     if (!tree_fits_uhwi_p (tsize)) >> +   { >> +     error_at (loc, "%u names provided while %qT decomposes into " > > When count is 1 as in the test below the error isn't grammatically > correct ("1 names"). I see that the same message is already issued > elsewhere in the function so this seems like an opportunity to use > the right form here and also fix the other one at the same time or > in a followup. The error_n function exists to issue the right form > for the language, singular or plural. It's not as convenient when > the sentence contains two terms that may be singular or plural, > but that can also be dealt with. Agreed. Jason ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) 2017-12-15 19:01 ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill @ 2017-12-15 19:09 ` Jakub Jelinek 2017-12-15 19:46 ` Jakub Jelinek 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-12-15 19:09 UTC (permalink / raw) To: Jason Merrill; +Cc: Martin Sebor, gcc-patches On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote: > On 11/29/2017 08:19 PM, Martin Sebor wrote: > > On 11/29/2017 03:32 PM, Jakub Jelinek wrote: > > > +     if (!tree_fits_uhwi_p (tsize)) > > > +   { > > > +     error_at (loc, "%u names provided while %qT decomposes into " > > > > When count is 1 as in the test below the error isn't grammatically > > correct ("1 names"). I see that the same message is already issued > > elsewhere in the function so this seems like an opportunity to use > > the right form here and also fix the other one at the same time or > > in a followup. The error_n function exists to issue the right form > > for the language, singular or plural. It's not as convenient when > > the sentence contains two terms that may be singular or plural, > > but that can also be dealt with. > > Agreed. Yeah, I've implemented it as an incremental patch. So http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html for the ICE and http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html on top of it. The latter is what Nathan approved already, the former needs review. Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) 2017-12-15 19:09 ` Jakub Jelinek @ 2017-12-15 19:46 ` Jakub Jelinek 2017-12-15 21:16 ` Jason Merrill 0 siblings, 1 reply; 12+ messages in thread From: Jakub Jelinek @ 2017-12-15 19:46 UTC (permalink / raw) To: Jason Merrill; +Cc: Martin Sebor, gcc-patches On Fri, Dec 15, 2017 at 08:09:20PM +0100, Jakub Jelinek wrote: > On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote: > > On 11/29/2017 08:19 PM, Martin Sebor wrote: > > > On 11/29/2017 03:32 PM, Jakub Jelinek wrote: > > > > +     if (!tree_fits_uhwi_p (tsize)) > > > > +   { > > > > +     error_at (loc, "%u names provided while %qT decomposes into " > > > > > > When count is 1 as in the test below the error isn't grammatically > > > correct ("1 names"). I see that the same message is already issued > > > elsewhere in the function so this seems like an opportunity to use > > > the right form here and also fix the other one at the same time or > > > in a followup. The error_n function exists to issue the right form > > > for the language, singular or plural. It's not as convenient when > > > the sentence contains two terms that may be singular or plural, > > > but that can also be dealt with. > > > > Agreed. > > Yeah, I've implemented it as an incremental patch. > So > http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html > for the ICE and > http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html > on top of it. The latter is what Nathan approved already, the former > needs review. If it helps any, here are the 2 patches combined, re-tested on x86_64-linux with check-c++-all. 2017-12-15 Jakub Jelinek <jakub@redhat.com> PR c++/83205 * decl.c (cp_finish_decomp): Handle the case when tsize is not error_mark_node, but doesn't fit into uhwi. Split up count != eltscnt and !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n to handle plural forms properly. * g++.dg/cpp1z/decomp3.C: Adjust for structured binding count mismatch diagnostics split into error and warning with plural forms. * g++.dg/cpp1z/decomp10.C: Likewise. * g++.dg/cpp1z/decomp32.C: New test. --- gcc/cp/decl.c.jj 2017-12-15 20:40:00.601221086 +0100 +++ gcc/cp/decl.c 2017-12-15 20:42:25.917445216 +0100 @@ -7427,11 +7427,20 @@ cp_finish_decomp (tree decl, tree first, { cnt_mismatch: if (count > eltscnt) - error_at (loc, "%u names provided while %qT decomposes into " - "%wu elements", count, type, eltscnt); + error_n (loc, count, + "%u name provided for structured binding", + "%u names provided for structured binding", count); else - error_at (loc, "only %u names provided while %qT decomposes into " - "%wu elements", count, type, eltscnt); + error_n (loc, count, + "only %u name provided for structured binding", + "only %u names provided for structured binding", count); + /* Some languages have special plural rules even for large values, + but it is periodic with period of 10, 100, 1000 etc. */ + inform_n (loc, eltscnt > INT_MAX + ? (eltscnt % 1000000) + 1000000 : eltscnt, + "while %qT decomposes into %wu element", + "while %qT decomposes into %wu elements", + type, eltscnt); goto error_out; } eltype = TREE_TYPE (type); @@ -7500,6 +7509,15 @@ cp_finish_decomp (tree decl, tree first, "constant expression", type); goto error_out; } + if (!tree_fits_uhwi_p (tsize)) + { + error_n (loc, count, + "%u name provided for structured binding", + "%u names provided for structured binding", count); + inform (loc, "while %qT decomposes into %E elements", + type, tsize); + goto error_out; + } eltscnt = tree_to_uhwi (tsize); if (count != eltscnt) goto cnt_mismatch; --- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj 2017-11-30 11:18:00.078805693 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp3.C 2017-12-15 20:42:25.917445216 +0100 @@ -51,16 +51,21 @@ int arr[4]; void test3 (A &b, B c) { - auto [ d, e, f ] = arr; // { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto [ l, m ] = b; // { dg-error "only 2 names provided while 'A' decomposes into 3 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto & [ n, o, p, q ] = b; // { dg-error "4 names provided while 'A' decomposes into 3 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } + auto [ d, e, f ] = arr; // { dg-error "only 3 names provided" } + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided" } + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto [ l, m ] = b; // { dg-error "only 2 names provided" } + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } + auto & [ n, o, p, q ] = b; // { dg-error "4 names provided" } + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } auto [] { c }; // { dg-error "empty structured binding declaration" } // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } - auto [ r, s ] = c; // { dg-error "2 names provided while 'B' decomposes into 1 elements" } - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } + auto [ r, s ] = c; // { dg-error "2 names provided" } + // { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } } --- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj 2017-11-30 11:18:00.102805393 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp10.C 2017-12-15 20:42:25.918445204 +0100 @@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; } // { dg-e struct A2 { int i,j; } a2; template<> struct std::tuple_size<A2> { enum { value = 5 }; }; -void f2() { auto [ x ] = a2; } // { dg-error "decomposes into 5" } +void f2() { auto [ x ] = a2; } // { dg-error "only 1 name provided" } + // { dg-message "decomposes into 5" "" { target *-*-* } .-1 } struct A3 { int i,j; } a3; template<> struct std::tuple_size<A3> { enum { value = 1 }; }; --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj 2017-12-15 20:42:58.977041204 +0100 +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C 2017-12-15 20:42:25.918445204 +0100 @@ -0,0 +1,32 @@ +// PR c++/83205 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct A { int i; }; +struct B { int i; }; +namespace std { + template <typename T> struct tuple_size; + template <> struct tuple_size<A> { + static constexpr int value = -1; + }; +#ifdef __SIZEOF_INT128__ + template <> struct tuple_size<B> { + static constexpr unsigned __int128 value = -1; + }; +#endif +} + +auto [a] = A{}; // { dg-error "1 name provided" } + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } +#ifdef __SIZEOF_INT128__ +auto [b] = B{}; // { dg-error "1 name provided" "" { target int128 } } + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } +auto [c, d] = B{}; // { dg-error "2 names provided" "" { target int128 } } + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } +#endif +auto [e, f, g] = A{}; // { dg-error "3 names provided" } + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) 2017-12-15 19:46 ` Jakub Jelinek @ 2017-12-15 21:16 ` Jason Merrill 0 siblings, 0 replies; 12+ messages in thread From: Jason Merrill @ 2017-12-15 21:16 UTC (permalink / raw) To: Jakub Jelinek; +Cc: Martin Sebor, gcc-patches List OK. On Fri, Dec 15, 2017 at 2:46 PM, Jakub Jelinek <jakub@redhat.com> wrote: > On Fri, Dec 15, 2017 at 08:09:20PM +0100, Jakub Jelinek wrote: >> On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote: >> > On 11/29/2017 08:19 PM, Martin Sebor wrote: >> > > On 11/29/2017 03:32 PM, Jakub Jelinek wrote: >> > > > + if (!tree_fits_uhwi_p (tsize)) >> > > > + { >> > > > + error_at (loc, "%u names provided while %qT decomposes into " >> > > >> > > When count is 1 as in the test below the error isn't grammatically >> > > correct ("1 names"). I see that the same message is already issued >> > > elsewhere in the function so this seems like an opportunity to use >> > > the right form here and also fix the other one at the same time or >> > > in a followup. The error_n function exists to issue the right form >> > > for the language, singular or plural. It's not as convenient when >> > > the sentence contains two terms that may be singular or plural, >> > > but that can also be dealt with. >> > >> > Agreed. >> >> Yeah, I've implemented it as an incremental patch. >> So >> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html >> for the ICE and >> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html >> on top of it. The latter is what Nathan approved already, the former >> needs review. > > If it helps any, here are the 2 patches combined, re-tested on x86_64-linux > with check-c++-all. > > 2017-12-15 Jakub Jelinek <jakub@redhat.com> > > PR c++/83205 > * decl.c (cp_finish_decomp): Handle the case when tsize is not > error_mark_node, but doesn't fit into uhwi. Split up count != eltscnt > and !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n > to handle plural forms properly. > > * g++.dg/cpp1z/decomp3.C: Adjust for structured binding count > mismatch diagnostics split into error and warning with plural > forms. > * g++.dg/cpp1z/decomp10.C: Likewise. > * g++.dg/cpp1z/decomp32.C: New test. > > --- gcc/cp/decl.c.jj 2017-12-15 20:40:00.601221086 +0100 > +++ gcc/cp/decl.c 2017-12-15 20:42:25.917445216 +0100 > @@ -7427,11 +7427,20 @@ cp_finish_decomp (tree decl, tree first, > { > cnt_mismatch: > if (count > eltscnt) > - error_at (loc, "%u names provided while %qT decomposes into " > - "%wu elements", count, type, eltscnt); > + error_n (loc, count, > + "%u name provided for structured binding", > + "%u names provided for structured binding", count); > else > - error_at (loc, "only %u names provided while %qT decomposes into " > - "%wu elements", count, type, eltscnt); > + error_n (loc, count, > + "only %u name provided for structured binding", > + "only %u names provided for structured binding", count); > + /* Some languages have special plural rules even for large values, > + but it is periodic with period of 10, 100, 1000 etc. */ > + inform_n (loc, eltscnt > INT_MAX > + ? (eltscnt % 1000000) + 1000000 : eltscnt, > + "while %qT decomposes into %wu element", > + "while %qT decomposes into %wu elements", > + type, eltscnt); > goto error_out; > } > eltype = TREE_TYPE (type); > @@ -7500,6 +7509,15 @@ cp_finish_decomp (tree decl, tree first, > "constant expression", type); > goto error_out; > } > + if (!tree_fits_uhwi_p (tsize)) > + { > + error_n (loc, count, > + "%u name provided for structured binding", > + "%u names provided for structured binding", count); > + inform (loc, "while %qT decomposes into %E elements", > + type, tsize); > + goto error_out; > + } > eltscnt = tree_to_uhwi (tsize); > if (count != eltscnt) > goto cnt_mismatch; > --- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj 2017-11-30 11:18:00.078805693 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp3.C 2017-12-15 20:42:25.917445216 +0100 > @@ -51,16 +51,21 @@ int arr[4]; > void > test3 (A &b, B c) > { > - auto [ d, e, f ] = arr; // { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" } > - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > - auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" } > - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > - auto [ l, m ] = b; // { dg-error "only 2 names provided while 'A' decomposes into 3 elements" } > - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > - auto & [ n, o, p, q ] = b; // { dg-error "4 names provided while 'A' decomposes into 3 elements" } > - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > + auto [ d, e, f ] = arr; // { dg-error "only 3 names provided" } > + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } > + auto & [ g, h, i, j, k ] = arr; // { dg-error "5 names provided" } > + // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } > + auto [ l, m ] = b; // { dg-error "only 2 names provided" } > + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } > + auto & [ n, o, p, q ] = b; // { dg-error "4 names provided" } > + // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } > auto [] { c }; // { dg-error "empty structured binding declaration" } > // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > - auto [ r, s ] = c; // { dg-error "2 names provided while 'B' decomposes into 1 elements" } > - // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 } > + auto [ r, s ] = c; // { dg-error "2 names provided" } > + // { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 } > } > --- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj 2017-11-30 11:18:00.102805393 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp10.C 2017-12-15 20:42:25.918445204 +0100 > @@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; } // { dg-e > > struct A2 { int i,j; } a2; > template<> struct std::tuple_size<A2> { enum { value = 5 }; }; > -void f2() { auto [ x ] = a2; } // { dg-error "decomposes into 5" } > +void f2() { auto [ x ] = a2; } // { dg-error "only 1 name provided" } > + // { dg-message "decomposes into 5" "" { target *-*-* } .-1 } > > struct A3 { int i,j; } a3; > template<> struct std::tuple_size<A3> { enum { value = 1 }; }; > --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj 2017-12-15 20:42:58.977041204 +0100 > +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C 2017-12-15 20:42:25.918445204 +0100 > @@ -0,0 +1,32 @@ > +// PR c++/83205 > +// { dg-do compile { target c++11 } } > +// { dg-options "" } > + > +struct A { int i; }; > +struct B { int i; }; > +namespace std { > + template <typename T> struct tuple_size; > + template <> struct tuple_size<A> { > + static constexpr int value = -1; > + }; > +#ifdef __SIZEOF_INT128__ > + template <> struct tuple_size<B> { > + static constexpr unsigned __int128 value = -1; > + }; > +#endif > +} > + > +auto [a] = A{}; // { dg-error "1 name provided" } > + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } > +#ifdef __SIZEOF_INT128__ > +auto [b] = B{}; // { dg-error "1 name provided" "" { target int128 } } > + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } > + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } > +auto [c, d] = B{}; // { dg-error "2 names provided" "" { target int128 } } > + // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 } > + // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 } > +#endif > +auto [e, f, g] = A{}; // { dg-error "3 names provided" } > + // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 } > + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } > > > Jakub ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-12-15 21:16 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-11-29 22:35 [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jakub Jelinek 2017-11-30 2:42 ` Martin Sebor 2017-11-30 9:26 ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek 2017-11-30 11:59 ` Nathan Sidwell 2017-11-30 12:09 ` Jakub Jelinek 2017-11-30 13:01 ` Jakub Jelinek 2017-11-30 13:47 ` Jakub Jelinek 2017-11-30 15:51 ` Pedro Alves 2017-12-15 19:01 ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill 2017-12-15 19:09 ` Jakub Jelinek 2017-12-15 19:46 ` Jakub Jelinek 2017-12-15 21:16 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).