diff mbox series

c: ignore initializers for elements of variable-size types [PR93577]

Message ID alpine.DEB.2.21.2003052349230.2774@digraph.polyomino.org.uk
State New
Headers show
Series c: ignore initializers for elements of variable-size types [PR93577] | expand

Commit Message

Joseph Myers March 5, 2020, 11:49 p.m. UTC
Bug 93577, apparently a regression (although it isn't very clear to me
exactly when it was introduced; tests I made with various past
compilers produced inconclusive results, including e.g. ICEs appearing
with 64-bit-host compilers for some versions but not 32-bit-host
compilers for the same versions) is an C front-end tree-checking ICE
processing initializers for structs using the VLA-in-struct extension.
There is an error for such initializers, but other processing that
still takes place for them results in the ICE.

This patch ensures that processing of initializers for variable-size
types stops earlier to avoid the code that results in the ICE (and
ensures it stops earlier for error_mark_node to avoid ICEs in the
check for variable-size types), adjusts the conditions for the "empty
scalar initializer" diagnostic to avoid consequent excess errors in
the case of a bad type name, and adds tests for a few variations on
what such initializers might look like, as well as tests for cases
identified from ICEs seen with an earlier version of this patch.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Applied to 
mainline.

gcc/c:
2020-03-05  Joseph Myers  <joseph@codesourcery.com>

	PR c/93577
	* c-typeck.c (pop_init_level): Do not diagnose initializers as
	empty when initialized type is error_mark_node.
	(set_designator, process_init_element): Ignore initializers for
	elements of a variable-size type or of error_mark_node.

gcc/testsuite:
2020-03-05  Joseph Myers  <joseph@codesourcery.com>

	PR c/93577
	* gcc.dg/pr93577-1.c, gcc.dg/pr93577-2.c, gcc.dg/pr93577-3.c,
	gcc.dg/pr93577-4.c, gcc.dg/pr93577-5.c, gcc.dg/pr93577-6.c: New
	tests.
	* gcc.dg/vla-init-1.c: Expect fewer errors about VLA initializer.

Comments

Christophe Lyon March 9, 2020, 2:58 p.m. UTC | #1
On Fri, 6 Mar 2020 at 00:50, Joseph Myers <joseph@codesourcery.com> wrote:
>
> Bug 93577, apparently a regression (although it isn't very clear to me
> exactly when it was introduced; tests I made with various past
> compilers produced inconclusive results, including e.g. ICEs appearing
> with 64-bit-host compilers for some versions but not 32-bit-host
> compilers for the same versions) is an C front-end tree-checking ICE
> processing initializers for structs using the VLA-in-struct extension.
> There is an error for such initializers, but other processing that
> still takes place for them results in the ICE.
>
> This patch ensures that processing of initializers for variable-size
> types stops earlier to avoid the code that results in the ICE (and
> ensures it stops earlier for error_mark_node to avoid ICEs in the
> check for variable-size types), adjusts the conditions for the "empty
> scalar initializer" diagnostic to avoid consequent excess errors in
> the case of a bad type name, and adds tests for a few variations on
> what such initializers might look like, as well as tests for cases
> identified from ICEs seen with an earlier version of this patch.
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Applied to
> mainline.
>

Hi Joseph,

I've noticed that your patch introduces regressions on aarch64:
FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
-march=armv8.2-a+sve  (test for errors, line 33)
we now get
/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c:33:44:
error: empty scalar initializer
while we expect dg-error {initializer element is not constant}

FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
-march=armv8.2-a+sve  (test for errors, line 85)
we no longer emit dg-error {empty scalar initializer }

FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
-march=armv8.2-a+sve (test for excess errors)
FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
-march=armv8.2-a+sve  (test for errors, line 85)
we no longer emit dg-error {empty scalar initializer }

Since the compiler did not ICE before your patch, is that new
behaviour expected (and the tests need an update), or is that a
problem with the patch?

Thanks,

Christophe



> gcc/c:
> 2020-03-05  Joseph Myers  <joseph@codesourcery.com>
>
>         PR c/93577
>         * c-typeck.c (pop_init_level): Do not diagnose initializers as
>         empty when initialized type is error_mark_node.
>         (set_designator, process_init_element): Ignore initializers for
>         elements of a variable-size type or of error_mark_node.
>
> gcc/testsuite:
> 2020-03-05  Joseph Myers  <joseph@codesourcery.com>
>
>         PR c/93577
>         * gcc.dg/pr93577-1.c, gcc.dg/pr93577-2.c, gcc.dg/pr93577-3.c,
>         gcc.dg/pr93577-4.c, gcc.dg/pr93577-5.c, gcc.dg/pr93577-6.c: New
>         tests.
>         * gcc.dg/vla-init-1.c: Expect fewer errors about VLA initializer.
>
> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index 308fcffcfb0..d8025de1996 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -8759,7 +8759,7 @@ pop_init_level (location_t loc, int implicit,
>          the element, after verifying there is just one.  */
>        if (vec_safe_is_empty (constructor_elements))
>         {
> -         if (!constructor_erroneous)
> +         if (!constructor_erroneous && constructor_type != error_mark_node)
>             error_init (loc, "empty scalar initializer");
>           ret.value = error_mark_node;
>         }
> @@ -8836,8 +8836,8 @@ set_designator (location_t loc, bool array,
>    enum tree_code subcode;
>
>    /* Don't die if an entire brace-pair level is superfluous
> -     in the containing level.  */
> -  if (constructor_type == NULL_TREE)
> +     in the containing level, or for an erroneous type.  */
> +  if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
>      return true;
>
>    /* If there were errors in this designator list already, bail out
> @@ -8845,6 +8845,12 @@ set_designator (location_t loc, bool array,
>    if (designator_erroneous)
>      return true;
>
> +  /* Likewise for an initializer for a variable-size type.  Those are
> +     diagnosed in digest_init.  */
> +  if (COMPLETE_TYPE_P (constructor_type)
> +      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> +    return true;
> +
>    if (!designator_depth)
>      {
>        gcc_assert (!constructor_range_stack);
> @@ -9955,8 +9961,14 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
>      }
>
>    /* Ignore elements of a brace group if it is entirely superfluous
> -     and has already been diagnosed.  */
> -  if (constructor_type == NULL_TREE)
> +     and has already been diagnosed, or if the type is erroneous.  */
> +  if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
> +    return;
> +
> +  /* Ignore elements of an initializer for a variable-size type.
> +     Those are diagnosed in digest_init.  */
> +  if (COMPLETE_TYPE_P (constructor_type)
> +      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
>      return;
>
>    if (!implicit && warn_designated_init && !was_designated
> diff --git a/gcc/testsuite/gcc.dg/pr93577-1.c b/gcc/testsuite/gcc.dg/pr93577-1.c
> new file mode 100644
> index 00000000000..31023d79d99
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-1.c
> @@ -0,0 +1,16 @@
> +/* Test ICE with variable-size struct initializer: bug 93577.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void
> +f (int c)
> +{
> +  struct s
> +  {
> +    int x[c];
> +    struct
> +    {
> +      int z;
> +    } nest;
> +  } v = { 1, 2 }; /* { dg-error "variable-sized object may not be initialized" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr93577-2.c b/gcc/testsuite/gcc.dg/pr93577-2.c
> new file mode 100644
> index 00000000000..c61589ea670
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-2.c
> @@ -0,0 +1,16 @@
> +/* Test ICE with variable-size struct initializer: bug 93577.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void
> +f (int c)
> +{
> +  struct s
> +  {
> +    int x[c];
> +    struct
> +    {
> +      int a, b;
> +    } nest;
> +  } v = { .nest.b = 1, .nest.a = 2 }; /* { dg-error "variable-sized object may not be initialized" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr93577-3.c b/gcc/testsuite/gcc.dg/pr93577-3.c
> new file mode 100644
> index 00000000000..278146b16bd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-3.c
> @@ -0,0 +1,17 @@
> +/* Test ICE with variable-size struct initializer: bug 93577.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void
> +f (int c)
> +{
> +  struct s
> +  {
> +    int a;
> +    int x[c];
> +    struct
> +    {
> +      int a, b;
> +    } nest;
> +  } v = { .a = 2, .nest.b = 1 }; /* { dg-error "variable-sized object may not be initialized" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr93577-4.c b/gcc/testsuite/gcc.dg/pr93577-4.c
> new file mode 100644
> index 00000000000..0ac117c4d77
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-4.c
> @@ -0,0 +1,17 @@
> +/* Test ICE with variable-size struct initializer: bug 93577.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void
> +f (int c)
> +{
> +  struct s
> +  {
> +    int a;
> +    int x[c];
> +    struct
> +    {
> +      int a, b;
> +    } nest;
> +  } v[2] = { [1].nest.b = 1 }; /* { dg-error "variable-sized object may not be initialized" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr93577-5.c b/gcc/testsuite/gcc.dg/pr93577-5.c
> new file mode 100644
> index 00000000000..68dfc1faaaa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-5.c
> @@ -0,0 +1,11 @@
> +/* Test ICE with designated initializer in compound literal with bad
> +   type name (ICE seen with early version of fix for bug 93577 but not
> +   covered in other tests).  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void *
> +f (void)
> +{
> +  return &(const bad_type) { .a = 0 }; /* { dg-error "unknown type name" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr93577-6.c b/gcc/testsuite/gcc.dg/pr93577-6.c
> new file mode 100644
> index 00000000000..5ec668fd4df
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr93577-6.c
> @@ -0,0 +1,11 @@
> +/* Test ICE with designated initializer in compound literal with bad
> +   type name (ICE seen with early version of fix for bug 93577 but not
> +   covered in other tests).  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +void *
> +f (void)
> +{
> +  return &(const bad_type) { [0] = 0 }; /* { dg-error "unknown type name" } */
> +}
> diff --git a/gcc/testsuite/gcc.dg/vla-init-1.c b/gcc/testsuite/gcc.dg/vla-init-1.c
> index 38e9b011b9c..3125b703451 100644
> --- a/gcc/testsuite/gcc.dg/vla-init-1.c
> +++ b/gcc/testsuite/gcc.dg/vla-init-1.c
> @@ -10,6 +10,4 @@ void
>  foo (void)
>  {
>    int x[a] = { 1 }; /* { dg-error "variable-sized object may not be initialized" "VLA init" } */
> -  /* { dg-warning "excess elements in array initializer" "excess" { target *-*-* } .-1 } */
> -  /* { dg-message "near initialization" "near" { target *-*-* } .-2 } */
>  }
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
Joseph Myers March 10, 2020, 12:51 a.m. UTC | #2
On Mon, 9 Mar 2020, Christophe Lyon wrote:

> Hi Joseph,
> 
> I've noticed that your patch introduces regressions on aarch64:
> FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> -march=armv8.2-a+sve  (test for errors, line 33)
> we now get
> /gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c:33:44:
> error: empty scalar initializer
> while we expect dg-error {initializer element is not constant}
> 
> FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> -march=armv8.2-a+sve  (test for errors, line 85)
> we no longer emit dg-error {empty scalar initializer }
> 
> FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> -march=armv8.2-a+sve (test for excess errors)
> FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> -march=armv8.2-a+sve  (test for errors, line 85)
> we no longer emit dg-error {empty scalar initializer }
> 
> Since the compiler did not ICE before your patch, is that new
> behaviour expected (and the tests need an update), or is that a
> problem with the patch?

Where there has already been an error about the type of an initializer, 
it's expected that some other errors about the value of that initializer 
will disappear.  So I think the cases where a previously expected error 
has disappeared are cases where the tests need an update; they already 
expect an error for the type.

That leaves the case where you report that "empty scalar initializer" has 
appeared.  That seems like a bug.  Maybe some SVE case means 
process_init_element is ignoring something in an initializer for an SVE 
type that did not in fact result in the variable-size error from 
digest_init?  Is the "empty scalar initializer" error coming from the 
compound literal on line 33, as opposed to the variable initialized on 
that line?
Christophe Lyon March 10, 2020, 4:18 p.m. UTC | #3
On Tue, 10 Mar 2020 at 01:52, Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Mon, 9 Mar 2020, Christophe Lyon wrote:
>
> > Hi Joseph,
> >
> > I've noticed that your patch introduces regressions on aarch64:
> > FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > -march=armv8.2-a+sve  (test for errors, line 33)
> > we now get
> > /gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c:33:44:
> > error: empty scalar initializer
> > while we expect dg-error {initializer element is not constant}
> >
> > FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > -march=armv8.2-a+sve  (test for errors, line 85)
> > we no longer emit dg-error {empty scalar initializer }
> >
> > FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > -march=armv8.2-a+sve (test for excess errors)
> > FAIL: gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > -march=armv8.2-a+sve  (test for errors, line 85)
> > we no longer emit dg-error {empty scalar initializer }
> >
> > Since the compiler did not ICE before your patch, is that new
> > behaviour expected (and the tests need an update), or is that a
> > problem with the patch?
>
> Where there has already been an error about the type of an initializer,
> it's expected that some other errors about the value of that initializer
> will disappear.  So I think the cases where a previously expected error
> has disappeared are cases where the tests need an update; they already
> expect an error for the type.
>
OK, makes sense.


> That leaves the case where you report that "empty scalar initializer" has
> appeared.  That seems like a bug.  Maybe some SVE case means
> process_init_element is ignoring something in an initializer for an SVE
> type that did not in fact result in the variable-size error from
> digest_init?  Is the "empty scalar initializer" error coming from the
> compound literal on line 33, as opposed to the variable initialized on
> that line?
>
sizeless-1.c and sizeless-2.c have the same code, but the latter is
compiled with -msve-vector-bits=256 and expects different
warnings/errors.
For line 33:
svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
we now have:
sizeless-1.c:33:44: error: empty scalar initializer
sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
and
sizeless-2.c:33:44: error: initializer element is not constant
sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
so I think the error comes from the compound literal being treated
differently with -msve-vector-bits=256


> --
> Joseph S. Myers
> joseph@codesourcery.com
Joseph Myers March 10, 2020, 11:37 p.m. UTC | #4
On Tue, 10 Mar 2020, Christophe Lyon wrote:

> sizeless-1.c and sizeless-2.c have the same code, but the latter is
> compiled with -msve-vector-bits=256 and expects different
> warnings/errors.
> For line 33:
> svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
> we now have:
> sizeless-1.c:33:44: error: empty scalar initializer
> sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
> and
> sizeless-2.c:33:44: error: initializer element is not constant
> sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
> sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
> so I think the error comes from the compound literal being treated
> differently with -msve-vector-bits=256

I think the sizeless-2.c diagnostics are correct while there's a problem 
in the sizeless-1.c case (the initializer is not empty, so it should not 
be diagnosed as such).

Does the process_init_element code

  /* Ignore elements of an initializer for a variable-size type.
     Those are diagnosed in digest_init.  */
  if (COMPLETE_TYPE_P (constructor_type)
      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
    return;

fire for the sizeless-1.c case?  If so, maybe it needs to be restricted in 
some way to apply only to variable size structs / unions / arrays rather 
than whatever kind of variable-size type the SVE types are.
Li, Pan2 via Gcc-patches March 13, 2020, 12:32 p.m. UTC | #5
On Wed, 11 Mar 2020 at 00:37, Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Tue, 10 Mar 2020, Christophe Lyon wrote:
>
> > sizeless-1.c and sizeless-2.c have the same code, but the latter is
> > compiled with -msve-vector-bits=256 and expects different
> > warnings/errors.
> > For line 33:
> > svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
> > we now have:
> > sizeless-1.c:33:44: error: empty scalar initializer
> > sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
> > and
> > sizeless-2.c:33:44: error: initializer element is not constant
> > sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
> > sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
> > so I think the error comes from the compound literal being treated
> > differently with -msve-vector-bits=256
>
> I think the sizeless-2.c diagnostics are correct while there's a problem
> in the sizeless-1.c case (the initializer is not empty, so it should not
> be diagnosed as such).
>
> Does the process_init_element code
>
>   /* Ignore elements of an initializer for a variable-size type.
>      Those are diagnosed in digest_init.  */
>   if (COMPLETE_TYPE_P (constructor_type)
>       && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
>     return;
>
> fire for the sizeless-1.c case?  If so, maybe it needs to be restricted in
> some way to apply only to variable size structs / unions / arrays rather
> than whatever kind of variable-size type the SVE types are.

It does. Type_size has POLY_INT_CST type.

The attached small patch fixes the problem (tested on arm and aarch64).
OK?

gcc/c/ChangeLog:

2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>

        * c-typeck.c (process_init_element): Handle constructor_type with
        type size represented by POLY_INT_CST.

gcc/testsuite/ChangeLog:

2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>

        * gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Remove
        superfluous dg-error.
        * gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.


diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d8025de..1302486 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9968,7 +9968,8 @@ process_init_element (location_t loc, struct
c_expr value, bool implicit,
   /* Ignore elements of an initializer for a variable-size type.
      Those are diagnosed in digest_init.  */
   if (COMPLETE_TYPE_P (constructor_type)
-      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != POLY_INT_CST)
     return;

   if (!implicit && warn_designated_init && !was_designated
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
index ec892a3..e53b871 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
@@ -83,7 +83,6 @@ statements (int n)
   svint8_t array[2]; /* { dg-error {array elements cannot have SVE
type 'svint8_t'} } */
   svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
have SVE type 'svint8_t'} } */
   svint8_t empty_init_array[] = {}; /* { dg-error {array elements
cannot have SVE type 'svint8_t'} } */
-                                   /* { dg-error {empty scalar
initializer} "" { target *-*-* } .-1 } */
   typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
have SVE type 'svint8_t'} } */

   /* Assignment.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
index 7174393..9986d27 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
@@ -83,7 +83,6 @@ statements (int n)
   svint8_t array[2]; /* { dg-error {array elements cannot have SVE
type 'svint8_t'} } */
   svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
have SVE type 'svint8_t'} } */
   svint8_t empty_init_array[] = {}; /* { dg-error {array elements
cannot have SVE type 'svint8_t'} } */
-                                   /* { dg-error {empty scalar
initializer} "" { target *-*-* } .-1 } */
   typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
have SVE type 'svint8_t'} } */

   /* Assignment.  */

>
> --
> Joseph S. Myers
> joseph@codesourcery.com
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d8025de..1302486 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9968,7 +9968,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
   /* Ignore elements of an initializer for a variable-size type.
      Those are diagnosed in digest_init.  */
   if (COMPLETE_TYPE_P (constructor_type)
-      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != POLY_INT_CST)
     return;
 
   if (!implicit && warn_designated_init && !was_designated
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
index ec892a3..e53b871 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
@@ -83,7 +83,6 @@ statements (int n)
   svint8_t array[2]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
   svint8_t zero_length_array[0]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
   svint8_t empty_init_array[] = {}; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
-  				    /* { dg-error {empty scalar initializer} "" { target *-*-* } .-1 } */
   typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
 
   /* Assignment.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
index 7174393..9986d27 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
@@ -83,7 +83,6 @@ statements (int n)
   svint8_t array[2]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
   svint8_t zero_length_array[0]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
   svint8_t empty_init_array[] = {}; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
-  				    /* { dg-error {empty scalar initializer} "" { target *-*-* } .-1 } */
   typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot have SVE type 'svint8_t'} } */
 
   /* Assignment.  */
gcc/c/ChangeLog:

2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>

	* c-typeck.c (process_init_element): Handle constructor_type with
	type size represented by POLY_INT_CST.

gcc/testsuite/ChangeLog:

2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>

	* gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Remove
	superfluous dg-error.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.
Joseph Myers March 13, 2020, 9:47 p.m. UTC | #6
On Fri, 13 Mar 2020, Christophe Lyon via Gcc-patches wrote:

> The attached small patch fixes the problem (tested on arm and aarch64).
> OK?
> 
> gcc/c/ChangeLog:
> 
> 2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>
> 
>         * c-typeck.c (process_init_element): Handle constructor_type with
>         type size represented by POLY_INT_CST.
> 
> gcc/testsuite/ChangeLog:
> 
> 2020-03-13  Christophe Lyon  <christophe.lyon@linaro.org>
> 
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Remove
>         superfluous dg-error.
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.

OK.
Richard Sandiford March 16, 2020, 6:59 p.m. UTC | #7
Christophe Lyon via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> On Wed, 11 Mar 2020 at 00:37, Joseph Myers <joseph@codesourcery.com> wrote:
>>
>> On Tue, 10 Mar 2020, Christophe Lyon wrote:
>>
>> > sizeless-1.c and sizeless-2.c have the same code, but the latter is
>> > compiled with -msve-vector-bits=256 and expects different
>> > warnings/errors.
>> > For line 33:
>> > svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
>> > we now have:
>> > sizeless-1.c:33:44: error: empty scalar initializer
>> > sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
>> > and
>> > sizeless-2.c:33:44: error: initializer element is not constant
>> > sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
>> > sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
>> > so I think the error comes from the compound literal being treated
>> > differently with -msve-vector-bits=256
>>
>> I think the sizeless-2.c diagnostics are correct while there's a problem
>> in the sizeless-1.c case (the initializer is not empty, so it should not
>> be diagnosed as such).
>>
>> Does the process_init_element code
>>
>>   /* Ignore elements of an initializer for a variable-size type.
>>      Those are diagnosed in digest_init.  */
>>   if (COMPLETE_TYPE_P (constructor_type)
>>       && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
>>     return;
>>
>> fire for the sizeless-1.c case?  If so, maybe it needs to be restricted in
>> some way to apply only to variable size structs / unions / arrays rather
>> than whatever kind of variable-size type the SVE types are.
>
> It does. Type_size has POLY_INT_CST type.
>
> The attached small patch fixes the problem (tested on arm and aarch64).
> OK?

Thanks for doing this.  I'd wondered whether it should be based on
this or on VECTOR_TYPE_P, but FWIW, I agree basing it on this is best.

> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index d8025de..1302486 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -9968,7 +9968,8 @@ process_init_element (location_t loc, struct
> c_expr value, bool implicit,
>    /* Ignore elements of an initializer for a variable-size type.
>       Those are diagnosed in digest_init.  */
>    if (COMPLETE_TYPE_P (constructor_type)
> -      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> +      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST
> +      && TREE_CODE (TYPE_SIZE (constructor_type)) != POLY_INT_CST)

Not worth respinning over, but since it hasn't been applied yet:
a shorter alternative is to replace the != INTEGER_CST test with
!poly_int_tree_p.

> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> index ec892a3..e53b871 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> @@ -83,7 +83,6 @@ statements (int n)
>    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> type 'svint8_t'} } */
>    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> have SVE type 'svint8_t'} } */
>    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> cannot have SVE type 'svint8_t'} } */
> -                                   /* { dg-error {empty scalar
> initializer} "" { target *-*-* } .-1 } */
>    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> have SVE type 'svint8_t'} } */
>
>    /* Assignment.  */
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> index 7174393..9986d27 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> @@ -83,7 +83,6 @@ statements (int n)
>    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> type 'svint8_t'} } */
>    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> have SVE type 'svint8_t'} } */
>    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> cannot have SVE type 'svint8_t'} } */
> -                                   /* { dg-error {empty scalar
> initializer} "" { target *-*-* } .-1 } */
>    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> have SVE type 'svint8_t'} } */
>
>    /* Assignment.  */

Jeff pointed out off-list that using:

   N:  ... /* { dg-error {...} } */
 N+1:      /* { dg-error {...} "" { target *-*-* } .-1 } */

led to two identical test names for line N.  This was causing the
results to fluctuate when using contrib/compare_tests (which I admit
I don't do, so hadn't noticed).  Your patch fixes the cases that
mattered, but for future-proofing reasons, this patch adds proper
test names for the remaining instances.

Tested on aarch64-linux-gnu and committed as obvious.

Richard


2020-03-16  Richard Sandiford  <richard.sandiford@arm.com>

gcc/testsuite/
	* gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Add a test
	name to .-1 dg-error tests.
	* gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.
---
 .../gcc.target/aarch64/sve/acle/general-c/sizeless-1.c          | 2 +-
 .../gcc.target/aarch64/sve/acle/general-c/sizeless-2.c          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
index ec892a3fc83..045963d5c76 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
@@ -31,7 +31,7 @@ union union1 {
 
 svint8_t *global_sve_sc_ptr;
 svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
-  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
+  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
 
 /* Sizeless arguments and return values.  */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
index 71743930098..c7282faba46 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
@@ -31,7 +31,7 @@ union union1 {
 
 svint8_t *global_sve_sc_ptr;
 svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
-  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
+  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
 
 /* Sizeless arguments and return values.  */
Li, Pan2 via Gcc-patches March 17, 2020, 9:50 a.m. UTC | #8
On Mon, 16 Mar 2020 at 19:59, Richard Sandiford
<richard.sandiford@arm.com> wrote:
>
> Christophe Lyon via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> > On Wed, 11 Mar 2020 at 00:37, Joseph Myers <joseph@codesourcery.com> wrote:
> >>
> >> On Tue, 10 Mar 2020, Christophe Lyon wrote:
> >>
> >> > sizeless-1.c and sizeless-2.c have the same code, but the latter is
> >> > compiled with -msve-vector-bits=256 and expects different
> >> > warnings/errors.
> >> > For line 33:
> >> > svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
> >> > we now have:
> >> > sizeless-1.c:33:44: error: empty scalar initializer
> >> > sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
> >> > and
> >> > sizeless-2.c:33:44: error: initializer element is not constant
> >> > sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
> >> > sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
> >> > so I think the error comes from the compound literal being treated
> >> > differently with -msve-vector-bits=256
> >>
> >> I think the sizeless-2.c diagnostics are correct while there's a problem
> >> in the sizeless-1.c case (the initializer is not empty, so it should not
> >> be diagnosed as such).
> >>
> >> Does the process_init_element code
> >>
> >>   /* Ignore elements of an initializer for a variable-size type.
> >>      Those are diagnosed in digest_init.  */
> >>   if (COMPLETE_TYPE_P (constructor_type)
> >>       && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> >>     return;
> >>
> >> fire for the sizeless-1.c case?  If so, maybe it needs to be restricted in
> >> some way to apply only to variable size structs / unions / arrays rather
> >> than whatever kind of variable-size type the SVE types are.
> >
> > It does. Type_size has POLY_INT_CST type.
> >
> > The attached small patch fixes the problem (tested on arm and aarch64).
> > OK?
>
> Thanks for doing this.  I'd wondered whether it should be based on
> this or on VECTOR_TYPE_P, but FWIW, I agree basing it on this is best.
>
> > diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> > index d8025de..1302486 100644
> > --- a/gcc/c/c-typeck.c
> > +++ b/gcc/c/c-typeck.c
> > @@ -9968,7 +9968,8 @@ process_init_element (location_t loc, struct
> > c_expr value, bool implicit,
> >    /* Ignore elements of an initializer for a variable-size type.
> >       Those are diagnosed in digest_init.  */
> >    if (COMPLETE_TYPE_P (constructor_type)
> > -      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> > +      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST
> > +      && TREE_CODE (TYPE_SIZE (constructor_type)) != POLY_INT_CST)
>
> Not worth respinning over, but since it hasn't been applied yet:
> a shorter alternative is to replace the != INTEGER_CST test with
> !poly_int_tree_p.

Thanks for the hint.
Now pushed as r10-7208-gfd857de80705be937d9780dbd394d006151713fe

Christophe

>
> > diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > index ec892a3..e53b871 100644
> > --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > @@ -83,7 +83,6 @@ statements (int n)
> >    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> > type 'svint8_t'} } */
> >    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> > cannot have SVE type 'svint8_t'} } */
> > -                                   /* { dg-error {empty scalar
> > initializer} "" { target *-*-* } .-1 } */
> >    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >
> >    /* Assignment.  */
> > diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > index 7174393..9986d27 100644
> > --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > @@ -83,7 +83,6 @@ statements (int n)
> >    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> > type 'svint8_t'} } */
> >    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> > cannot have SVE type 'svint8_t'} } */
> > -                                   /* { dg-error {empty scalar
> > initializer} "" { target *-*-* } .-1 } */
> >    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >
> >    /* Assignment.  */
>
> Jeff pointed out off-list that using:
>
>    N:  ... /* { dg-error {...} } */
>  N+1:      /* { dg-error {...} "" { target *-*-* } .-1 } */
>
> led to two identical test names for line N.  This was causing the
> results to fluctuate when using contrib/compare_tests (which I admit
> I don't do, so hadn't noticed).  Your patch fixes the cases that
> mattered, but for future-proofing reasons, this patch adds proper
> test names for the remaining instances.
>
> Tested on aarch64-linux-gnu and committed as obvious.
>
> Richard
>
>
> 2020-03-16  Richard Sandiford  <richard.sandiford@arm.com>
>
> gcc/testsuite/
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Add a test
>         name to .-1 dg-error tests.
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.
> ---
>  .../gcc.target/aarch64/sve/acle/general-c/sizeless-1.c          | 2 +-
>  .../gcc.target/aarch64/sve/acle/general-c/sizeless-2.c          | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> index ec892a3fc83..045963d5c76 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> @@ -31,7 +31,7 @@ union union1 {
>
>  svint8_t *global_sve_sc_ptr;
>  svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
> -  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
> +  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
>
>  /* Sizeless arguments and return values.  */
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> index 71743930098..c7282faba46 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> @@ -31,7 +31,7 @@ union union1 {
>
>  svint8_t *global_sve_sc_ptr;
>  svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
> -  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
> +  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
>
>  /* Sizeless arguments and return values.  */
>
Li, Pan2 via Gcc-patches March 17, 2020, 1:27 p.m. UTC | #9
On Mon, 16 Mar 2020 at 19:59, Richard Sandiford
<richard.sandiford@arm.com> wrote:
>
> Christophe Lyon via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> > On Wed, 11 Mar 2020 at 00:37, Joseph Myers <joseph@codesourcery.com> wrote:
> >>
> >> On Tue, 10 Mar 2020, Christophe Lyon wrote:
> >>
> >> > sizeless-1.c and sizeless-2.c have the same code, but the latter is
> >> > compiled with -msve-vector-bits=256 and expects different
> >> > warnings/errors.
> >> > For line 33:
> >> > svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr };
> >> > we now have:
> >> > sizeless-1.c:33:44: error: empty scalar initializer
> >> > sizeless-1.c:33:44: note: (near initialization for '(anonymous)')
> >> > and
> >> > sizeless-2.c:33:44: error: initializer element is not constant
> >> > sizeless-2.c:33:44: note: (near initialization for 'invalid_sve_sc_ptr')
> >> > sizeless-2.c:33:44: error: SVE type 'svint8_t' does not have a fixed size
> >> > so I think the error comes from the compound literal being treated
> >> > differently with -msve-vector-bits=256
> >>
> >> I think the sizeless-2.c diagnostics are correct while there's a problem
> >> in the sizeless-1.c case (the initializer is not empty, so it should not
> >> be diagnosed as such).
> >>
> >> Does the process_init_element code
> >>
> >>   /* Ignore elements of an initializer for a variable-size type.
> >>      Those are diagnosed in digest_init.  */
> >>   if (COMPLETE_TYPE_P (constructor_type)
> >>       && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> >>     return;
> >>
> >> fire for the sizeless-1.c case?  If so, maybe it needs to be restricted in
> >> some way to apply only to variable size structs / unions / arrays rather
> >> than whatever kind of variable-size type the SVE types are.
> >
> > It does. Type_size has POLY_INT_CST type.
> >
> > The attached small patch fixes the problem (tested on arm and aarch64).
> > OK?
>
> Thanks for doing this.  I'd wondered whether it should be based on
> this or on VECTOR_TYPE_P, but FWIW, I agree basing it on this is best.
>
> > diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> > index d8025de..1302486 100644
> > --- a/gcc/c/c-typeck.c
> > +++ b/gcc/c/c-typeck.c
> > @@ -9968,7 +9968,8 @@ process_init_element (location_t loc, struct
> > c_expr value, bool implicit,
> >    /* Ignore elements of an initializer for a variable-size type.
> >       Those are diagnosed in digest_init.  */
> >    if (COMPLETE_TYPE_P (constructor_type)
> > -      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
> > +      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST
> > +      && TREE_CODE (TYPE_SIZE (constructor_type)) != POLY_INT_CST)
>
> Not worth respinning over, but since it hasn't been applied yet:
> a shorter alternative is to replace the != INTEGER_CST test with
> !poly_int_tree_p.
>
> > diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > index ec892a3..e53b871 100644
> > --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> > @@ -83,7 +83,6 @@ statements (int n)
> >    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> > type 'svint8_t'} } */
> >    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> > cannot have SVE type 'svint8_t'} } */
> > -                                   /* { dg-error {empty scalar
> > initializer} "" { target *-*-* } .-1 } */
> >    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >
> >    /* Assignment.  */
> > diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > index 7174393..9986d27 100644
> > --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> > @@ -83,7 +83,6 @@ statements (int n)
> >    svint8_t array[2]; /* { dg-error {array elements cannot have SVE
> > type 'svint8_t'} } */
> >    svint8_t zero_length_array[0]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >    svint8_t empty_init_array[] = {}; /* { dg-error {array elements
> > cannot have SVE type 'svint8_t'} } */
> > -                                   /* { dg-error {empty scalar
> > initializer} "" { target *-*-* } .-1 } */
> >    typedef svint8_t vla_type[n]; /* { dg-error {array elements cannot
> > have SVE type 'svint8_t'} } */
> >
> >    /* Assignment.  */
>
> Jeff pointed out off-list that using:
>
>    N:  ... /* { dg-error {...} } */
>  N+1:      /* { dg-error {...} "" { target *-*-* } .-1 } */
>
> led to two identical test names for line N.  This was causing the
> results to fluctuate when using contrib/compare_tests (which I admit
> I don't do, so hadn't noticed).  Your patch fixes the cases that
> mattered, but for future-proofing reasons, this patch adds proper
> test names for the remaining instances.
>

Thanks.

Just checked, there are many more testcases with duplicate "names"
(266 under gcc.target/aarch64 only) :-(

Sigh...

> Tested on aarch64-linux-gnu and committed as obvious.
>
> Richard
>
>
> 2020-03-16  Richard Sandiford  <richard.sandiford@arm.com>
>
> gcc/testsuite/
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Add a test
>         name to .-1 dg-error tests.
>         * gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise.
> ---
>  .../gcc.target/aarch64/sve/acle/general-c/sizeless-1.c          | 2 +-
>  .../gcc.target/aarch64/sve/acle/general-c/sizeless-2.c          | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> index ec892a3fc83..045963d5c76 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
> @@ -31,7 +31,7 @@ union union1 {
>
>  svint8_t *global_sve_sc_ptr;
>  svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
> -  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
> +  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
>
>  /* Sizeless arguments and return values.  */
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> index 71743930098..c7282faba46 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
> @@ -31,7 +31,7 @@ union union1 {
>
>  svint8_t *global_sve_sc_ptr;
>  svint8_t *invalid_sve_sc_ptr = &(svint8_t) { *global_sve_sc_ptr }; /* { dg-error {initializer element is not constant} } */
> -  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "" { target *-*-* } .-1 } */
> +  /* { dg-error {SVE type 'svint8_t' does not have a fixed size} "2nd line" { target *-*-* } .-1 } */
>
>  /* Sizeless arguments and return values.  */
>
Li, Pan2 via Gcc-patches March 18, 2020, 8:55 p.m. UTC | #10
On Tue, 2020-03-17 at 14:27 +0100, Christophe Lyon wrote:
> 
> > Jeff pointed out off-list that using:
> > 
> >    N:  ... /* { dg-error {...} } */
> >  N+1:      /* { dg-error {...} "" { target *-*-* } .-1 } */
> > 
> > led to two identical test names for line N.  This was causing the
> > results to fluctuate when using contrib/compare_tests (which I admit
> > I don't do, so hadn't noticed).  Your patch fixes the cases that
> > mattered, but for future-proofing reasons, this patch adds proper
> > test names for the remaining instances.
> > 
> 
> Thanks.
> 
> Just checked, there are many more testcases with duplicate "names"
> (266 under gcc.target/aarch64 only) :-(
Yea.  It's a fairly common issue and not immediately obvious unless someone is
using the compare_tests script.

I think when this came up with some of Martin Sebor's work we agreed to fault in
fixes to the existing tests, so I think that would apply here as well.

Jeff
>
diff mbox series

Patch

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 308fcffcfb0..d8025de1996 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -8759,7 +8759,7 @@  pop_init_level (location_t loc, int implicit,
 	 the element, after verifying there is just one.  */
       if (vec_safe_is_empty (constructor_elements))
 	{
-	  if (!constructor_erroneous)
+	  if (!constructor_erroneous && constructor_type != error_mark_node)
 	    error_init (loc, "empty scalar initializer");
 	  ret.value = error_mark_node;
 	}
@@ -8836,8 +8836,8 @@  set_designator (location_t loc, bool array,
   enum tree_code subcode;
 
   /* Don't die if an entire brace-pair level is superfluous
-     in the containing level.  */
-  if (constructor_type == NULL_TREE)
+     in the containing level, or for an erroneous type.  */
+  if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
     return true;
 
   /* If there were errors in this designator list already, bail out
@@ -8845,6 +8845,12 @@  set_designator (location_t loc, bool array,
   if (designator_erroneous)
     return true;
 
+  /* Likewise for an initializer for a variable-size type.  Those are
+     diagnosed in digest_init.  */
+  if (COMPLETE_TYPE_P (constructor_type)
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
+    return true;
+
   if (!designator_depth)
     {
       gcc_assert (!constructor_range_stack);
@@ -9955,8 +9961,14 @@  process_init_element (location_t loc, struct c_expr value, bool implicit,
     }
 
   /* Ignore elements of a brace group if it is entirely superfluous
-     and has already been diagnosed.  */
-  if (constructor_type == NULL_TREE)
+     and has already been diagnosed, or if the type is erroneous.  */
+  if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
+    return;
+
+  /* Ignore elements of an initializer for a variable-size type.
+     Those are diagnosed in digest_init.  */
+  if (COMPLETE_TYPE_P (constructor_type)
+      && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
     return;
 
   if (!implicit && warn_designated_init && !was_designated
diff --git a/gcc/testsuite/gcc.dg/pr93577-1.c b/gcc/testsuite/gcc.dg/pr93577-1.c
new file mode 100644
index 00000000000..31023d79d99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-1.c
@@ -0,0 +1,16 @@ 
+/* Test ICE with variable-size struct initializer: bug 93577.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+f (int c)
+{
+  struct s
+  {
+    int x[c];
+    struct
+    {
+      int z;
+    } nest;
+  } v = { 1, 2 }; /* { dg-error "variable-sized object may not be initialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr93577-2.c b/gcc/testsuite/gcc.dg/pr93577-2.c
new file mode 100644
index 00000000000..c61589ea670
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-2.c
@@ -0,0 +1,16 @@ 
+/* Test ICE with variable-size struct initializer: bug 93577.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+f (int c)
+{
+  struct s
+  {
+    int x[c];
+    struct
+    {
+      int a, b;
+    } nest;
+  } v = { .nest.b = 1, .nest.a = 2 }; /* { dg-error "variable-sized object may not be initialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr93577-3.c b/gcc/testsuite/gcc.dg/pr93577-3.c
new file mode 100644
index 00000000000..278146b16bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-3.c
@@ -0,0 +1,17 @@ 
+/* Test ICE with variable-size struct initializer: bug 93577.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+f (int c)
+{
+  struct s
+  {
+    int a;
+    int x[c];
+    struct
+    {
+      int a, b;
+    } nest;
+  } v = { .a = 2, .nest.b = 1 }; /* { dg-error "variable-sized object may not be initialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr93577-4.c b/gcc/testsuite/gcc.dg/pr93577-4.c
new file mode 100644
index 00000000000..0ac117c4d77
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-4.c
@@ -0,0 +1,17 @@ 
+/* Test ICE with variable-size struct initializer: bug 93577.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+f (int c)
+{
+  struct s
+  {
+    int a;
+    int x[c];
+    struct
+    {
+      int a, b;
+    } nest;
+  } v[2] = { [1].nest.b = 1 }; /* { dg-error "variable-sized object may not be initialized" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr93577-5.c b/gcc/testsuite/gcc.dg/pr93577-5.c
new file mode 100644
index 00000000000..68dfc1faaaa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-5.c
@@ -0,0 +1,11 @@ 
+/* Test ICE with designated initializer in compound literal with bad
+   type name (ICE seen with early version of fix for bug 93577 but not
+   covered in other tests).  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void *
+f (void)
+{
+  return &(const bad_type) { .a = 0 }; /* { dg-error "unknown type name" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr93577-6.c b/gcc/testsuite/gcc.dg/pr93577-6.c
new file mode 100644
index 00000000000..5ec668fd4df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr93577-6.c
@@ -0,0 +1,11 @@ 
+/* Test ICE with designated initializer in compound literal with bad
+   type name (ICE seen with early version of fix for bug 93577 but not
+   covered in other tests).  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void *
+f (void)
+{
+  return &(const bad_type) { [0] = 0 }; /* { dg-error "unknown type name" } */
+}
diff --git a/gcc/testsuite/gcc.dg/vla-init-1.c b/gcc/testsuite/gcc.dg/vla-init-1.c
index 38e9b011b9c..3125b703451 100644
--- a/gcc/testsuite/gcc.dg/vla-init-1.c
+++ b/gcc/testsuite/gcc.dg/vla-init-1.c
@@ -10,6 +10,4 @@  void
 foo (void)
 {
   int x[a] = { 1 }; /* { dg-error "variable-sized object may not be initialized" "VLA init" } */
-  /* { dg-warning "excess elements in array initializer" "excess" { target *-*-* } .-1 } */
-  /* { dg-message "near initialization" "near" { target *-*-* } .-2 } */
 }