mirror of git://gcc.gnu.org/git/gcc.git
PR c/71560 - union compound literal initializes wrong union field
gcc/ChangeLog: * doc/extend.texi (Compound Literals): Correct and clarify. (Cast to Union): Same. From-SVN: r238651
This commit is contained in:
parent
1610d41097
commit
e040f9bd4b
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-07-22 Martin Sebor <msebor@redhat.com>
|
||||||
|
|
||||||
|
PR c/71560
|
||||||
|
* doc/extend.texi (Compound Literals): Correct and clarify.
|
||||||
|
(Cast to Union): Same.
|
||||||
|
|
||||||
2016-07-22 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
2016-07-22 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
||||||
|
|
||||||
* config/rs6000/rs6000.c (rs6000_option_override_internal): Add
|
* config/rs6000/rs6000.c (rs6000_option_override_internal): Add
|
||||||
|
|
|
||||||
|
|
@ -1868,15 +1868,16 @@ foo (float f, float g)
|
||||||
@cindex compound literals
|
@cindex compound literals
|
||||||
@c The GNU C name for what C99 calls compound literals was "constructor expressions".
|
@c The GNU C name for what C99 calls compound literals was "constructor expressions".
|
||||||
|
|
||||||
ISO C99 supports compound literals. A compound literal looks like
|
A compound literal looks like a cast of a brace-enclosed aggregate
|
||||||
a cast containing an initializer. Its value is an object of the
|
initializer list. Its value is an object of the type specified in
|
||||||
type specified in the cast, containing the elements specified in
|
the cast, containing the elements specified in the initializer.
|
||||||
the initializer; it is an lvalue. As an extension, GCC supports
|
Unlike the result of a cast, a compound literal is an lvalue. ISO
|
||||||
compound literals in C90 mode and in C++, though the semantics are
|
C99 and later support compound literals. As an extension, GCC
|
||||||
somewhat different in C++.
|
supports compound literals also in C90 mode and in C++, although
|
||||||
|
as explained below, the C++ semantics are somewhat different.
|
||||||
|
|
||||||
Usually, the specified type is a structure. Assume that
|
Usually, the specified type of a compound literal is a structure. Assume
|
||||||
@code{struct foo} and @code{structure} are declared as shown:
|
that @code{struct foo} and @code{structure} are declared as shown:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
struct foo @{int a; char b[2];@} structure;
|
struct foo @{int a; char b[2];@} structure;
|
||||||
|
|
@ -1901,7 +1902,7 @@ This is equivalent to writing the following:
|
||||||
|
|
||||||
You can also construct an array, though this is dangerous in C++, as
|
You can also construct an array, though this is dangerous in C++, as
|
||||||
explained below. If all the elements of the compound literal are
|
explained below. If all the elements of the compound literal are
|
||||||
(made up of) simple constant expressions, suitable for use in
|
(made up of) simple constant expressions suitable for use in
|
||||||
initializers of objects of static storage duration, then the compound
|
initializers of objects of static storage duration, then the compound
|
||||||
literal can be coerced to a pointer to its first element and used in
|
literal can be coerced to a pointer to its first element and used in
|
||||||
such an initializer, as shown here:
|
such an initializer, as shown here:
|
||||||
|
|
@ -1910,18 +1911,23 @@ such an initializer, as shown here:
|
||||||
char **foo = (char *[]) @{ "x", "y", "z" @};
|
char **foo = (char *[]) @{ "x", "y", "z" @};
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
Compound literals for scalar types and union types are
|
Compound literals for scalar types and union types are also allowed. In
|
||||||
also allowed, but then the compound literal is equivalent
|
the following example the variable @code{i} is initialized to the value
|
||||||
to a cast.
|
@code{2}, the result of incrementing the unnamed object created by
|
||||||
|
the compound literal.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
int i = ++(int) @{ 1 @};
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
As a GNU extension, GCC allows initialization of objects with static storage
|
As a GNU extension, GCC allows initialization of objects with static storage
|
||||||
duration by compound literals (which is not possible in ISO C99, because
|
duration by compound literals (which is not possible in ISO C99 because
|
||||||
the initializer is not a constant).
|
the initializer is not a constant).
|
||||||
It is handled as if the object is initialized only with the bracket
|
It is handled as if the object were initialized only with the brace-enclosed
|
||||||
enclosed list if the types of the compound literal and the object match.
|
list if the types of the compound literal and the object match.
|
||||||
The initializer list of the compound literal must be constant.
|
The elements of the compound literal must be constant.
|
||||||
If the object being initialized has array type of unknown size, the size is
|
If the object being initialized has array type of unknown size, the size is
|
||||||
determined by compound literal size.
|
determined by the size of the compound literal.
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
static struct foo x = (struct foo) @{1, 'a', 'b'@};
|
static struct foo x = (struct foo) @{1, 'a', 'b'@};
|
||||||
|
|
@ -1939,22 +1945,21 @@ static int z[] = @{1, 0, 0@};
|
||||||
|
|
||||||
In C, a compound literal designates an unnamed object with static or
|
In C, a compound literal designates an unnamed object with static or
|
||||||
automatic storage duration. In C++, a compound literal designates a
|
automatic storage duration. In C++, a compound literal designates a
|
||||||
temporary object, which only lives until the end of its
|
temporary object that only lives until the end of its full-expression.
|
||||||
full-expression. As a result, well-defined C code that takes the
|
As a result, well-defined C code that takes the address of a subobject
|
||||||
address of a subobject of a compound literal can be undefined in C++,
|
of a compound literal can be undefined in C++, so G++ rejects
|
||||||
so the C++ compiler rejects the conversion of a temporary array to a pointer.
|
the conversion of a temporary array to a pointer. For instance, if
|
||||||
For instance, if the array compound literal example above appeared
|
the array compound literal example above appeared inside a function,
|
||||||
inside a function, any subsequent use of @samp{foo} in C++ has
|
any subsequent use of @code{foo} in C++ would have undefined behavior
|
||||||
undefined behavior because the lifetime of the array ends after the
|
because the lifetime of the array ends after the declaration of @code{foo}.
|
||||||
declaration of @samp{foo}.
|
|
||||||
|
|
||||||
As an optimization, the C++ compiler sometimes gives array compound
|
As an optimization, G++ sometimes gives array compound literals longer
|
||||||
literals longer lifetimes: when the array either appears outside a
|
lifetimes: when the array either appears outside a function or has
|
||||||
function or has const-qualified type. If @samp{foo} and its
|
a @code{const}-qualified type. If @code{foo} and its initializer had
|
||||||
initializer had elements of @samp{char *const} type rather than
|
elements of type @code{char *const} rather than code{char *}, or if
|
||||||
@samp{char *}, or if @samp{foo} were a global variable, the array
|
@code{foo} were a global variable, the array would have static storage
|
||||||
would have static storage duration. But it is probably safest just to
|
duration. But it is probably safest just to avoid the use of array
|
||||||
avoid the use of array compound literals in code compiled as C++.
|
compound literals in C++ code.
|
||||||
|
|
||||||
@node Designated Inits
|
@node Designated Inits
|
||||||
@section Designated Initializers
|
@section Designated Initializers
|
||||||
|
|
@ -2145,11 +2150,12 @@ case 1...5:
|
||||||
@cindex cast to a union
|
@cindex cast to a union
|
||||||
@cindex union, casting to a
|
@cindex union, casting to a
|
||||||
|
|
||||||
A cast to union type is similar to other casts, except that the type
|
A cast to union type looks similar to other casts, except that the type
|
||||||
specified is a union type. You can specify the type either with
|
specified is a union type. You can specify the type either with the
|
||||||
@code{union @var{tag}} or with a typedef name. A cast to union is actually
|
@code{union} keyword or with a @code{typedef} name that refers to
|
||||||
a constructor, not a cast, and hence does not yield an lvalue like
|
a union. A cast to a union actually creates a compound literal and
|
||||||
normal casts. (@xref{Compound Literals}.)
|
yields an lvalue, not an rvalue like true casts do.
|
||||||
|
(@xref{Compound Literals}.)
|
||||||
|
|
||||||
The types that may be cast to the union type are those of the members
|
The types that may be cast to the union type are those of the members
|
||||||
of the union. Thus, given the following union and variables:
|
of the union. Thus, given the following union and variables:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue