OSDN Git Service

PR c++/51475 - ICE with invalid initializer-list
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Dec 2011 21:49:52 +0000 (21:49 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Dec 2011 21:49:52 +0000 (21:49 +0000)
gcc/cp/

PR c++/51475
* call.c (struct conversion)<u.next>: 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
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist63.C [new file with mode: 0644]

index 5b818e9..2c20ae2 100644 (file)
@@ -1,5 +1,10 @@
 2011-12-14  Dodji Seketeli  <dodji@redhat.com>
 
+       PR c++/51475
+       * call.c (struct conversion)<u.next>: 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.
index 6528368..dd716a4 100644 (file)
@@ -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)
            {
index 81d50c9..ab5cca0 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-14  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/51475
+       * g++.dg/cpp0x/initlist63.C: New test.
+
 2011-12-14  Georg-Johann Lay  <avr@gjlay.de>
 
        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 (file)
index 0000000..a72c0ab
--- /dev/null
@@ -0,0 +1,16 @@
+// Origin PR c++/51475
+// { dg-options -std=c++11 }
+
+#include <initializer_list>
+
+struct A
+{
+    A(int*);
+};
+
+struct B
+{
+    const std::initializer_list<A>& x;
+};
+
+B b = {{1}}; // { dg-error "invalid conversion|cannot convert" }