PR c++/92745 - bogus error when initializing array of vectors.

In r268428 I changed reshape_init_r in such a way that when it sees
a nested { } in a CONSTRUCTOR with missing braces, it just returns
the initializer:
+     else if (COMPOUND_LITERAL_P (stripped_init)
...
+         ++d->cur;
+         gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
+         return init;

But as this test shows, that's incorrect: if TYPE is an array, we need
to proceed to reshape_init_array_1 which will iterate over the array
initializers:
 6006   /* Loop until there are no more initializers.  */
 6007   for (index = 0;
 6008        d->cur != d->end && (!sized_array_p || index <= max_index_cst);
 6009        ++index)
 6010     {
and update d.cur accordingly.  In other words, when reshape_init gets

{{col[0][0], col[1][0], col[2][0], col[3][0]},
 {col[0][1], col[1][1], col[2][1], col[3][1]},
 {col[0][2], col[1][2], col[2][2], col[3][2]},
 {col[0][3], col[1][3], col[2][3], col[3][3]}}

we recurse on the first element:
  {col[0][0], col[1][0], col[2][0], col[3][0]}
and we can't just move d.cur to point to
  {col[0][1], col[1][1], col[2][1], col[3][1]}
and return; we need to iterate, so that d.cur ends up being properly
updated, and after all initializers have been seen, points to d.end.
Currently we skip the loop, wherefore we hit this:

 6502   /* Make sure all the element of the constructor were used. Otherwise,
 6503      issue an error about exceeding initializers.  */
 6504   if (d.cur != d.end)
 6505     {
 6506       if (complain & tf_error)
 6507         error ("too many initializers for %qT", type);
 6508       return error_mark_node;
 6509     }

	* decl.c (reshape_init_r): For a nested compound literal, do
	call reshape_init_{class,array,vector}.

	* g++.dg/cpp0x/initlist118.C: New test.

From-SVN: r279686
This commit is contained in:
Marek Polacek 2019-12-20 23:30:04 +00:00 committed by Marek Polacek
parent 97ba5b86a3
commit 14818f987a
4 changed files with 39 additions and 8 deletions

View File

@ -1,5 +1,9 @@
2019-12-19 Marek Polacek <polacek@redhat.com> 2019-12-19 Marek Polacek <polacek@redhat.com>
PR c++/92745 - bogus error when initializing array of vectors.
* decl.c (reshape_init_r): For a nested compound literal, do
call reshape_init_{class,array,vector}.
PR c++/92974 - bogus location for enum and non-enum in ?: warning. PR c++/92974 - bogus location for enum and non-enum in ?: warning.
* tree.c (build_min_non_dep): Use the location of NON_DEP when * tree.c (build_min_non_dep): Use the location of NON_DEP when
building the expression. building the expression.

View File

@ -6399,14 +6399,13 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
by the front end. Here we have e.g. {.__pfn=0B, .__delta=0}, by the front end. Here we have e.g. {.__pfn=0B, .__delta=0},
which is missing outermost braces. We should warn below, and which is missing outermost braces. We should warn below, and
one of the routines below will wrap it in additional { }. */; one of the routines below will wrap it in additional { }. */;
/* For a nested compound literal, there is no need to reshape since /* For a nested compound literal, proceed to specialized routines,
we called reshape_init in finish_compound_literal, before calling to handle initialization of arrays and similar. */
digest_init. */ else if (COMPOUND_LITERAL_P (stripped_init))
else if (COMPOUND_LITERAL_P (stripped_init) gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));
/* Similarly, a CONSTRUCTOR of the target's type is a /* A CONSTRUCTOR of the target's type is a previously
previously digested initializer. */ digested initializer. */
|| same_type_ignoring_top_level_qualifiers_p (type, else if (same_type_ignoring_top_level_qualifiers_p (type, init_type))
init_type))
{ {
++d->cur; ++d->cur;
gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init)); gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (stripped_init));

View File

@ -1,5 +1,8 @@
2019-12-19 Marek Polacek <polacek@redhat.com> 2019-12-19 Marek Polacek <polacek@redhat.com>
PR c++/92745 - bogus error when initializing array of vectors.
* g++.dg/cpp0x/initlist118.C: New test.
PR c++/92974 - bogus location for enum and non-enum in ?: warning. PR c++/92974 - bogus location for enum and non-enum in ?: warning.
* g++.dg/diagnostic/enum1.C: New test. * g++.dg/diagnostic/enum1.C: New test.
* g++.dg/gomp/loop-2.C: Adjust dg-error. * g++.dg/gomp/loop-2.C: Adjust dg-error.

View File

@ -0,0 +1,25 @@
// PR c++/92745 - bogus error when initializing array of vectors.
// { dg-do compile { target c++11 } }
template <typename a, int b> struct c {
typedef a d[b];
};
template <typename a, int b> struct array {
typename c<a, b>::d e;
a operator[](long);
};
template<class T>
using vec4_t __attribute__((vector_size(4*sizeof(T)))) = float;
array<vec4_t<float>, 4>
transpose(array<vec4_t<float>, 4> col)
{
array<vec4_t<float>, 4>
ret{vec4_t<float>{col[0][0], col[1][0], col[2][0], col[3][0]},
vec4_t<float>{col[0][1], col[1][1], col[2][1], col[3][1]},
vec4_t<float>{col[0][2], col[1][2], col[2][2], col[3][2]},
vec4_t<float>{col[0][3], col[1][3], col[2][3], col[3][3]}};
return ret;
}