diff options
author | Jason Merrill <jason@redhat.com> | 2014-07-15 15:16:29 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-07-15 15:16:29 -0400 |
commit | 0090cacae6e9f0d3649dff9e428ea92a10d69cfa (patch) | |
tree | 4d907344ad2b91570c02586a01550c3cf0448eb6 | |
parent | e27989c4f4ff56ea84f94135cfc8f574d66459bb (diff) | |
download | gcc-0090cacae6e9f0d3649dff9e428ea92a10d69cfa.tar.gz |
re PR c++/60848 (Crash while experimenting with c++-0x initializer lists)
PR c++/60848
PR c++/61723
* call.c (is_std_init_list): Don't check CLASSTYPE_TEMPLATE_INFO.
* class.c (finish_struct): Reject invalid definition of
std::initializer_list.
From-SVN: r212574
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/call.c | 1 | ||||
-rw-r--r-- | gcc/cp/class.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist85.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist87.C | 35 |
5 files changed, 69 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 697ba793c73..1d5b7d6423c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-07-15 Jason Merrill <jason@redhat.com> + + PR c++/60848 + PR c++/61723 + * call.c (is_std_init_list): Don't check CLASSTYPE_TEMPLATE_INFO. + * class.c (finish_struct): Reject invalid definition of + std::initializer_list. + 2014-07-15 Paolo Carlini <paolo.carlini@oracle.com> * call.c (convert_like_real): Call print_z_candidate and inform only diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6da1218042f..ea8cb5f78c8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9701,7 +9701,6 @@ is_std_init_list (tree type) type = TYPE_MAIN_VARIANT (type); return (CLASS_TYPE_P (type) && CP_TYPE_CONTEXT (type) == std_node - && CLASSTYPE_TEMPLATE_INFO (type) && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0); } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index dbd8d3d3aa5..e4523c7b1f6 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6695,6 +6695,28 @@ finish_struct (tree t, tree attributes) else finish_struct_1 (t); + if (is_std_init_list (t)) + { + /* People keep complaining that the compiler crashes on an invalid + definition of initializer_list, so I guess we should explicitly + reject it. What the compiler internals care about is that it's a + template and has a pointer field followed by an integer field. */ + bool ok = false; + if (processing_template_decl) + { + tree f = next_initializable_field (TYPE_FIELDS (t)); + if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE) + { + f = next_initializable_field (DECL_CHAIN (f)); + if (f && TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE) + ok = true; + } + } + if (!ok) + fatal_error ("definition of std::initializer_list does not match " + "#include <initializer_list>"); + } + input_location = saved_loc; TYPE_BEING_DEFINED (t) = 0; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist85.C b/gcc/testsuite/g++.dg/cpp0x/initlist85.C index 0eb8e26b8cf..fa4fb617b33 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist85.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist85.C @@ -3,12 +3,14 @@ namespace std { - struct initializer_list {}; + struct initializer_list {}; // { dg-message "initializer_list" } } void foo(std::initializer_list &); void f() { - foo({1, 2}); // { dg-error "" } + foo({1, 2}); } + +// { dg-prune-output "compilation terminated" } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist87.C b/gcc/testsuite/g++.dg/cpp0x/initlist87.C new file mode 100644 index 00000000000..fd7586d27d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist87.C @@ -0,0 +1,35 @@ +// PR c++/61723 +// { dg-do compile { target c++11 } } + +namespace std { + template < class > struct initializer_list // { dg-message "initializer_list" } + { +#if BUG1 + int _M_len; +#endif + const int *begin (); + const int *end (); + }; +} + +struct J +{ + J (const int &); + template < typename InputIterator > J (InputIterator, InputIterator); + J (std::initializer_list < int >p1):J (p1.begin (), p1.end ()) { } +}; + +struct L +{ + L ():dim (0) { } + J dim; +}; + +void +fn1 () +{ + L spec; + spec.dim = { }; +} + +// { dg-prune-output "compilation terminated" } |