This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 29 Nov 2017 23:32:11 +0100
- Subject: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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