aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-12-15 16:55:31 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-12-15 16:55:31 -0500
commit5058651d6382e0f307f9c96c356cca2d41cbddba (patch)
treecdb27440974c05499b5c3eb2792073f1815c77a2 /gcc
parent794f3386b6ef7070fed482fcbfd113af5121bd7a (diff)
downloadgcc-5058651d6382e0f307f9c96c356cca2d41cbddba.zip
gcc-5058651d6382e0f307f9c96c356cca2d41cbddba.tar.gz
gcc-5058651d6382e0f307f9c96c356cca2d41cbddba.tar.bz2
re PR c++/51458 (Accepts invalid designated initializers)
PR c++/51458 * decl.c (has_designator_problem): New. (reshape_init_r): Check for improper use of designated initializers. From-SVN: r182391
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/desig4.C10
4 files changed, 48 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c9ada9a..5953866 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1239535..919e235 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8786f42..c38491b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..48d629a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/desig4.C
@@ -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" }