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

Reply via email to