c-decl.c (grokdeclarator): Give zero-length arrays size zero.
* c-decl.c (grokdeclarator): Give zero-length arrays size zero. Remove dead code. * c-typeck.c (push_init_level): Move checks for flexible array members and zero length arrays ... (pop_init_level): ... here. Silently discard empty initializations. Remove dead code. * varasm.c (output_constructor): Update for sizeof change to zero-length arrays. * extend.texi (Zero Length): Clarify semantics. * gcc.dg/940510-1.c: Update expected error wording. * gcc.dg/array-2.c, gcc.dg/array-3.c, gcc.dg/array-4.c: New. From-SVN: r38678
This commit is contained in:
parent
04d430b8d0
commit
584ef5fea5
@ -1,3 +1,16 @@
|
||||
2000-01-03 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* c-decl.c (grokdeclarator): Give zero-length arrays size zero.
|
||||
Remove dead code.
|
||||
* c-typeck.c (push_init_level): Move checks for flexible array
|
||||
members and zero length arrays ...
|
||||
(pop_init_level): ... here. Silently discard empty initializations.
|
||||
Remove dead code.
|
||||
* varasm.c (output_constructor): Update for sizeof change to
|
||||
zero-length arrays.
|
||||
|
||||
* extend.texi (Zero Length): Clarify semantics.
|
||||
|
||||
2001-01-03 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* configure.in (tm.h): Include isns-codes.h last.
|
||||
|
15
gcc/c-decl.c
15
gcc/c-decl.c
@ -4518,14 +4518,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
||||
if (type_quals)
|
||||
type = c_build_qualified_type (type, type_quals);
|
||||
|
||||
#if 0
|
||||
/* Don't clear these; leave them set so that the array type
|
||||
or the variable is itself const or volatile. */
|
||||
type_quals = TYPE_UNQUALIFIED;
|
||||
#endif
|
||||
|
||||
if (size_varies)
|
||||
C_TYPE_VARIABLE_SIZE (type) = 1;
|
||||
|
||||
/* The GCC extension for zero-length arrays differs from
|
||||
ISO flexible array members in that sizeof yields zero. */
|
||||
if (size && integer_zerop (size))
|
||||
{
|
||||
layout_type (type);
|
||||
TYPE_SIZE (type) = bitsize_zero_node;
|
||||
TYPE_SIZE_UNIT (type) = size_zero_node;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (declarator) == CALL_EXPR)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Build expressions with type checking for C compiler.
|
||||
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -5289,20 +5289,9 @@ push_init_level (implicit)
|
||||
{
|
||||
constructor_max_index
|
||||
= TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
|
||||
|
||||
if (constructor_max_index == NULL_TREE)
|
||||
{
|
||||
/* This is a zero-length array or flexible array member. */
|
||||
if (pedantic)
|
||||
pedwarn_init ("ISO C does not support initialization of flexible array members");
|
||||
if (constructor_depth != 2)
|
||||
error_init ("initialization of zero-length array inside a nested structure");
|
||||
}
|
||||
|
||||
constructor_index
|
||||
= convert (bitsizetype,
|
||||
TYPE_MIN_VALUE
|
||||
(TYPE_DOMAIN (constructor_type)));
|
||||
TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
|
||||
}
|
||||
else
|
||||
constructor_index = bitsize_zero_node;
|
||||
@ -5346,6 +5335,24 @@ pop_init_level (implicit)
|
||||
if (constructor_type != 0)
|
||||
size = int_size_in_bytes (constructor_type);
|
||||
|
||||
/* Error for initializing a flexible array member, or a zero-length
|
||||
array member in an inappropriate context. */
|
||||
if (constructor_type
|
||||
&& TREE_CODE (constructor_type) == ARRAY_TYPE
|
||||
&& TYPE_DOMAIN (constructor_type)
|
||||
&& ! TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
|
||||
{
|
||||
if (! TYPE_SIZE (constructor_type))
|
||||
error_init ("initialization of a flexible array member");
|
||||
/* Silently discard empty initializations of zero-length arrays. */
|
||||
else if (integer_zerop (constructor_unfilled_index))
|
||||
constructor_type = 0;
|
||||
/* Otherwise we must be initializing a member of a top-level
|
||||
structure. */
|
||||
else if (constructor_depth != 2)
|
||||
error_init ("initialization of zero-length array inside a nested structure");
|
||||
}
|
||||
|
||||
/* Warn when some struct elements are implicitly initialized to zero. */
|
||||
if (extra_warnings
|
||||
&& constructor_type
|
||||
@ -5360,17 +5367,7 @@ pop_init_level (implicit)
|
||||
/* Now output all pending elements. */
|
||||
output_pending_init_elements (1);
|
||||
|
||||
#if 0 /* c-parse.in warns about {}. */
|
||||
/* In ANSI, each brace level must have at least one element. */
|
||||
if (! implicit && pedantic
|
||||
&& (TREE_CODE (constructor_type) == ARRAY_TYPE
|
||||
? integer_zerop (constructor_unfilled_index)
|
||||
: constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
|
||||
pedwarn_init ("empty braces in initializer");
|
||||
#endif
|
||||
|
||||
/* Pad out the end of the structure. */
|
||||
|
||||
if (p->replacement_value)
|
||||
/* If this closes a superfluous brace pair,
|
||||
just pass out the element between them. */
|
||||
|
@ -869,8 +869,8 @@ extension for floating-point constants of type @code{float}.
|
||||
@cindex zero-length arrays
|
||||
@cindex length-zero arrays
|
||||
|
||||
Zero-length arrays are allowed in GNU C. They are very useful as the last
|
||||
element of a structure which is really a header for a variable-length
|
||||
Zero-length arrays are allowed in GNU C. They are very useful as the
|
||||
last element of a structure which is really a header for a variable-length
|
||||
object:
|
||||
|
||||
@example
|
||||
@ -879,32 +879,54 @@ struct line @{
|
||||
char contents[0];
|
||||
@};
|
||||
|
||||
@{
|
||||
struct line *thisline = (struct line *)
|
||||
malloc (sizeof (struct line) + this_length);
|
||||
thisline->length = this_length;
|
||||
@}
|
||||
struct line *thisline = (struct line *)
|
||||
malloc (sizeof (struct line) + this_length);
|
||||
thisline->length = this_length;
|
||||
@end example
|
||||
|
||||
In ISO C89, you would have to give @code{contents} a length of 1, which
|
||||
means either you waste space or complicate the argument to @code{malloc}.
|
||||
|
||||
In ISO C99, you would use a @dfn{flexible array member}, which uses a
|
||||
slightly different syntax: leave out the @code{0} and write
|
||||
@code{contents[]}.
|
||||
In ISO C99, you would use a @dfn{flexible array member}, which is
|
||||
slightly different in syntax and semantics:
|
||||
|
||||
GCC allows static initialization of the zero-length array if
|
||||
the structure is not nested inside another structure. I.e.
|
||||
@itemize @bullet
|
||||
@item
|
||||
Flexible array members are written as @code{contents[]} without
|
||||
the @code{0}.
|
||||
|
||||
@item
|
||||
Flexible array members have incomplete type, and so the @code{sizeof}
|
||||
operator may not be applied. As a quirk of the original implementation
|
||||
of zero-length arrays, @code{sizeof} evaluates to zero.
|
||||
|
||||
@item
|
||||
Flexible array members may only appear as the last member of a
|
||||
@code{struct} that is otherwise non-empty. GCC currently allows
|
||||
zero-length arrays anywhere. You may encounter problems, however,
|
||||
defining structures containing only a zero-length array. Such usage
|
||||
is deprecated, and we recommend using zero-length arrays only in
|
||||
places in which flexible array members would be allowed.
|
||||
|
||||
@item
|
||||
GCC allows static initialization of the zero-length array if the structure
|
||||
is not nested inside another structure. In addition, for backward
|
||||
compatibility with an earlier versions of gcc, we allow a degenerate empty
|
||||
initialization when nested inside another structure. I.e.
|
||||
|
||||
@example
|
||||
struct bar @{ struct line a; @};
|
||||
|
||||
/* Legal. */
|
||||
struct line x = @{ 4, @{ 'g', 'o', 'o', 'd' @} @};
|
||||
|
||||
/* Illegal. */
|
||||
struct bar @{
|
||||
struct line a;
|
||||
@} y = @{ @{ 3, @{ 'b', 'a', 'd' @} @} @};
|
||||
struct bar y = @{ @{ 3, @{ 'b', 'a', 'd' @} @} @};
|
||||
|
||||
/* Legal. */
|
||||
struct bar z = @{ @{ 0, @{ @} @} @};
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@node Variable Length
|
||||
@section Arrays of Variable Length
|
||||
|
@ -1,3 +1,8 @@
|
||||
2001-01-03 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.dg/940510-1.c: Update expected error wording.
|
||||
* gcc.dg/array-2.c, gcc.dg/array-3.c, gcc.dg/array-4.c: New.
|
||||
|
||||
2001-01-03 Jeffrey Oldham <oldham@codesourcery.com>
|
||||
|
||||
* lib/target-supports.exp (check_alias_available): Modified to
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=c89 -pedantic" } */
|
||||
struct { int a[]; } x = { 0 }; /* { dg-error "(does not support)|(near initialization)" } */
|
||||
struct { int a[]; } x = { 0 }; /* { dg-error "(flexible array member)|(near initialization)" } */
|
||||
|
10
gcc/testsuite/gcc.dg/array-2.c
Normal file
10
gcc/testsuite/gcc.dg/array-2.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
/* Verify that we can't do things to get ourselves in trouble
|
||||
with GCC's zero-length array extension. */
|
||||
|
||||
struct f { int w; int x[0]; };
|
||||
struct g { struct f f; };
|
||||
struct g g1 = { { 0, { } } };
|
||||
struct g g2 = { { 0, { 1 } } }; /* { dg-error "(nested structure)|(near initialization)" "nested" } */
|
11
gcc/testsuite/gcc.dg/array-3.c
Normal file
11
gcc/testsuite/gcc.dg/array-3.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
/* ISO C99 flexible array members don't have a size. GCC's zero-length
|
||||
array extension does. */
|
||||
|
||||
struct f { int w; int x[0]; } f;
|
||||
struct g { int w; int x[]; } g;
|
||||
|
||||
char test_gcc[sizeof (f.x) ? -1 : 1];
|
||||
char test_iso[sizeof (g.x) ? -1 : 1]; /* { dg-error "incomplete type" "iso" } */
|
19
gcc/testsuite/gcc.dg/array-4.c
Normal file
19
gcc/testsuite/gcc.dg/array-4.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
/* Verify that GCC's extension to initialize a zero-length array
|
||||
member works properly. */
|
||||
|
||||
extern void abort(void);
|
||||
extern void exit(int);
|
||||
|
||||
struct f { int w; int x[0]; } f = { 4, { 0, 1, 2, 3 } };
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < f.w; ++i)
|
||||
if (f.x[i] != i)
|
||||
abort ();
|
||||
exit(0);
|
||||
}
|
15
gcc/varasm.c
15
gcc/varasm.c
@ -1,6 +1,6 @@
|
||||
/* Output variables, constants and external declarations, for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -4607,16 +4607,19 @@ output_constructor (exp, size)
|
||||
/* Determine size this element should occupy. */
|
||||
if (field)
|
||||
{
|
||||
if (DECL_SIZE_UNIT (field))
|
||||
if (DECL_SIZE_UNIT (field)
|
||||
&& ! integer_zerop (DECL_SIZE_UNIT (field)))
|
||||
fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
|
||||
else
|
||||
else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
|
||||
{
|
||||
/* If DECL_SIZE is not set, then this must be an array
|
||||
of unspecified length. The initialized value must
|
||||
be a CONSTRUCTOR, and we take the length from the
|
||||
/* If DECL_SIZE is not set or is zero, then this must be
|
||||
an array of unspecified length. The initialized value
|
||||
must be a CONSTRUCTOR, and we take the length from the
|
||||
last initialized element. */
|
||||
fieldsize = array_size_for_constructor (val);
|
||||
}
|
||||
else
|
||||
fieldsize = 0;
|
||||
}
|
||||
else
|
||||
fieldsize = int_size_in_bytes (TREE_TYPE (type));
|
||||
|
Loading…
Reference in New Issue
Block a user