OSDN Git Service

PR c++/51458
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Dec 2011 21:55:31 +0000 (21:55 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Dec 2011 21:55:31 +0000 (21:55 +0000)
* decl.c (has_designator_problem): New.
(reshape_init_r): Check for improper use of
designated initializers.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182391 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/desig4.C [new file with mode: 0644]

index c9ada9a..5953866 100644 (file)
@@ -1,3 +1,10 @@
+2011-12-15  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51458
+       * decl.c (has_designator_problem): New.
+       (reshape_init_r): Check for improper use of
+       designated initializers.
+
 2011-12-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/51463
index 1239535..919e235 100644 (file)
@@ -5128,6 +5128,24 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
   return new_init;
 }
 
+/* Subroutine of reshape_init_r.  We're in a context where C99 initializer
+   designators are not valid; either complain or return true to indicate
+   that reshape_init_r should return error_mark_node.  */
+
+static bool
+has_designator_problem (reshape_iter *d, tsubst_flags_t complain)
+{
+  if (d->cur->index)
+    {
+      if (complain & tf_error)
+       error ("C99 designator %qE outside aggregate initializer",
+              d->cur->index);
+      else
+       return true;
+    }
+  return false;
+}
+
 /* Subroutine of reshape_init, which processes a single initializer (part of
    a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
    iterator within the CONSTRUCTOR which points to the initializer to process.
@@ -5143,6 +5161,10 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
   if (error_operand_p (init))
     return error_mark_node;
 
+  if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type)
+      && has_designator_problem (d, complain))
+    return error_mark_node;
+
   if (TREE_CODE (type) == COMPLEX_TYPE)
     {
       /* A complex type can be initialized from one or two initializers,
@@ -5163,6 +5185,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
          VEC(constructor_elt, gc) *v = 0;
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value);
+         if (has_designator_problem (d, complain))
+           return error_mark_node;
          d->cur++;
          init = build_constructor (init_list_type_node, v);
        }
@@ -5242,6 +5266,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
         array types (one value per array element).  */
       if (TREE_CODE (str_init) == STRING_CST)
        {
+         if (has_designator_problem (d, complain))
+           return error_mark_node;
          d->cur++;
          return str_init;
        }
index 8786f42..c38491b 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-15  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51458
+       * g++.dg/ext/desig4.C: New.
+
 2011-12-15  Paul Thomas  <pault@gcc.gnu.org>
 
        * gfortran.dg/class_array_3.f03: Remove explicit indexing of
diff --git a/gcc/testsuite/g++.dg/ext/desig4.C b/gcc/testsuite/g++.dg/ext/desig4.C
new file mode 100644 (file)
index 0000000..48d629a
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/51458
+// { dg-options "" }
+
+char g[] = { [7] = "abcd" };        // { dg-error "designator" }
+int a = { .foo = 6 };               // { dg-error "designator" }
+int b = { [0] = 1 };                // { dg-error "designator" }
+_Complex float c = { .foo = 0,  1 }; // { dg-error "designator" }
+_Complex float d = { [0] = 0,  1 };  // { dg-error "designator" }
+_Complex float e = { 0, .foo = 1 };  // { dg-error "designator" }
+_Complex float f = { 0, [0] = 1 };   // { dg-error "designator" }