From 3a8d62bb49006b4eb17a673c2e7fb5a12cf51036 Mon Sep 17 00:00:00 2001 From: dodji Date: Wed, 14 Dec 2011 21:49:52 +0000 Subject: [PATCH] PR c++/51475 - ICE with invalid initializer-list gcc/cp/ PR c++/51475 * call.c (struct conversion): Update comment. (next_conversion): New static function. (convert_like_real): Use it. gcc/testsuite/ PR c++/51475 * g++.dg/cpp0x/initlist63.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182343 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/call.c | 25 ++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/initlist63.C | 16 ++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist63.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5b818e9f78a..2c20ae28207 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2011-12-14 Dodji Seketeli + PR c++/51475 + * call.c (struct conversion): Update comment. + (next_conversion): New static function. + (convert_like_real): Use it. + PR c++/51476 * pt.c (convert_nontype_argument): Don't call maybe_constant_value for PTRMEM_CST nodes. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 65283685a39..dd716a40e3b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -111,12 +111,15 @@ struct conversion { /* The next conversion in the chain. Since the conversions are arranged from outermost to innermost, the NEXT conversion will actually be performed before this conversion. This variant is - used only when KIND is neither ck_identity nor ck_ambig. */ + used only when KIND is neither ck_identity, ck_ambig nor + ck_list. Please use the next_conversion function instead + of using this field directly. */ conversion *next; /* The expression at the beginning of the conversion chain. This variant is used only if KIND is ck_identity or ck_ambig. */ tree expr; - /* The array of conversions for an initializer_list. */ + /* The array of conversions for an initializer_list, so this + variant is used only when KIN D is ck_list. */ conversion **list; } u; /* The function candidate corresponding to this conversion @@ -193,6 +196,7 @@ static conversion *standard_conversion (tree, tree, tree, bool, int); static conversion *reference_binding (tree, tree, tree, bool, int); static conversion *build_conv (conversion_kind, tree, conversion *); static conversion *build_list_conv (tree, tree, int); +static conversion *next_conversion (conversion *); static bool is_subseq (conversion *, conversion *); static conversion *maybe_handle_ref_bind (conversion **); static void maybe_handle_implicit_object (conversion **); @@ -833,6 +837,21 @@ build_list_conv (tree type, tree ctor, int flags) return t; } +/* Return the next conversion of the conversion chain (if applicable), + or NULL otherwise. Please use this function instead of directly + accessing fields of struct conversion. */ + +static conversion * +next_conversion (conversion *conv) +{ + if (conv == NULL + || conv->kind == ck_identity + || conv->kind == ck_ambig + || conv->kind == ck_list) + return NULL; + return conv->u.next; +} + /* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list, is a valid aggregate initializer for array type ATYPE. */ @@ -5603,7 +5622,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value)) permerror (input_location, "too many braces around initializer for %qT", totype); - for (; t; t = t->u.next) + for (; t ; t = next_conversion (t)) { if (t->kind == ck_user && t->cand->reason) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 81d50c9d0fc..ab5cca091f1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-14 Dodji Seketeli + + PR c++/51475 + * g++.dg/cpp0x/initlist63.C: New test. + 2011-12-14 Georg-Johann Lay PR target/50931 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist63.C b/gcc/testsuite/g++.dg/cpp0x/initlist63.C new file mode 100644 index 00000000000..a72c0ab9922 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist63.C @@ -0,0 +1,16 @@ +// Origin PR c++/51475 +// { dg-options -std=c++11 } + +#include + +struct A +{ + A(int*); +}; + +struct B +{ + const std::initializer_list& x; +}; + +B b = {{1}}; // { dg-error "invalid conversion|cannot convert" } -- 2.11.4.GIT