The bug points out a couple of conformance problems in the GCC manual where is discusses compound literals and casts to unions and says that a compound literal is equivalent to a cast. It isn't because a compound literal is an lvalue but a cast yields an rvalue.
The attached patch corrects this error and adds some clarifying text to illustrate the differences. Martin
PR c/71560 - union compound literal initializes wrong union field gcc/ChangeLog: 2016-06-23 Martin Sebor <mse...@redhat.com> PR c/71560 * doc/extend.texi (Compound Literals): Correct and clarify. (Cast to Union): Same. Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 237617) +++ gcc/doc/extend.texi (working copy) @@ -1863,15 +1863,16 @@ foo (float f, float g) @cindex compound literals @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 cast containing an initializer. Its value is an object of the -type specified in the cast, containing the elements specified in -the initializer; it is an lvalue. As an extension, GCC supports -compound literals in C90 mode and in C++, though the semantics are -somewhat different in C++. +A compound literal looks like a cast of a brace-enclosed aggregate +initializer list. Its value is an object of the type specified in +the cast, containing the elements specified in the initializer. +Unlike the result of a cast, a compound literal is an lvalue. ISO +C99 and later support compound literals. As an extension, GCC +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 -@code{struct foo} and @code{structure} are declared as shown: +Usually, the specified type of a compound literal is a structure. Assume +that @code{struct foo} and @code{structure} are declared as shown: @smallexample struct foo @{int a; char b[2];@} structure; @@ -1905,18 +1906,23 @@ such an initializer, as shown here: char **foo = (char *[]) @{ "x", "y", "z" @}; @end smallexample -Compound literals for scalar types and union types are -also allowed, but then the compound literal is equivalent -to a cast. +Compound literals for scalar types and union types are also allowed. In +the following example the variable @var{i} is initialized to the value +@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 -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). -It is handled as if the object is initialized only with the bracket -enclosed list if the types of the compound literal and the object match. -The initializer list of the compound literal must be constant. +It is handled as if the object were initialized only with the brace-enclosed +list if the types of the compound literal and the object match. +The elements of the compound literal must be constant. 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 static struct foo x = (struct foo) @{1, 'a', 'b'@}; @@ -1934,22 +1940,21 @@ static int z[] = @{1, 0, 0@}; In C, a compound literal designates an unnamed object with static or automatic storage duration. In C++, a compound literal designates a -temporary object, which only lives until the end of its -full-expression. As a result, well-defined C code that takes the -address of a subobject of a compound literal can be undefined in C++, -so the C++ compiler rejects the conversion of a temporary array to a pointer. -For instance, if the array compound literal example above appeared -inside a function, any subsequent use of @samp{foo} in C++ has -undefined behavior because the lifetime of the array ends after the -declaration of @samp{foo}. +temporary object that only lives until the end of its full-expression. +As a result, well-defined C code that takes the address of a subobject +of a compound literal can be undefined in C++, so G++ rejects +the conversion of a temporary array to a pointer. For instance, if +the array compound literal example above appeared inside a function, +any subsequent use of @samp{foo} in C++ would have undefined behavior +because the lifetime of the array ends after the declaration of @samp{foo}. -As an optimization, the C++ compiler sometimes gives array compound -literals longer lifetimes: when the array either appears outside a -function or has const-qualified type. If @samp{foo} and its -initializer had elements of @samp{char *const} type rather than -@samp{char *}, or if @samp{foo} were a global variable, the array -would have static storage duration. But it is probably safest just to -avoid the use of array compound literals in code compiled as C++. +As an optimization, G++ sometimes gives array compound literals longer +lifetimes: when the array either appears outside a function or has +a const-qualified type. If @samp{foo} and its initializer had elements +of type @samp{char *const} rather than @samp{char *}, or if @samp{foo} +were a global variable, the array would have static storage duration. +But it is probably safest just to avoid the use of array compound +literals in C++ code compiled. @node Designated Inits @section Designated Initializers @@ -2140,11 +2145,11 @@ case 1...5: @cindex cast to a union @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 -@code{union @var{tag}} or with a typedef name. A cast to union is actually -a constructor, not a cast, and hence does not yield an lvalue like -normal casts. (@xref{Compound Literals}.) +@code{union @var{tag}} or with a typedef name. A cast to union actually +creates a compound literal and 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 of the union. Thus, given the following union and variables: