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 <ja...@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