This bug is similar to http://gcc.gnu.org/PR24255 in that instead of passing the pointer to the variable itself a pointer to a temporary holding the address of the variable is used. However, the test case (which I will attach next) doesn't start failing until the following patch (found with Janis' reghunt scripts): 2007-10-09 Richard Guenther <rguenther@suse.de> PR middle-end/33692 * gimplify.c (canonicalize_component_ref): Honor qualifiers of referenced structure and component. * gcc.dg/pr33692.c: New testcase. The problematic union looks like: union q { unsigned n; unsigned get_n () const { return n; } } __attribute__ ((transparent_union)); If I change the second field to basically anything else, the test case passes. This seems to be a regression with GCC 4.4, 4.5 and mainline, as it compiles fine with my GCC 4.3 based system compiler which predates richi's patch. I'll note this only seems to fail using "g++ -m32 ..." and does not fail when using -m64.
Created attachment 20466 [details] transparent_union test case bergner@begna:~/reghunt/work> /home/bergner/gcc/install/gcc-mainline-r129167/bin/g++ -m32 pr43859.cc bergner@begna:~/reghunt/work> ./a.out 4294716492 Aborted bergner@begna:~/reghunt/work> /home/bergner/gcc/install/gcc-mainline-r129166/bin/g++ -m32 pr43859.cc bergner@begna:~/reghunt/work> ./a.out 1
Looks like the front-end is messing up how transparent_union is done anyways. It is creating a variant which is just bogus. It should be the main variant.
I think you have the attribute in the wrong location.
Interesting, using: union __attribute__ ((transparent_union)) q { unsigned n; unsigned get_n () const { return n; } }; does seem to cure it. However, is the attribute location really incorrect? It seems the gcc docs on variable attributes have several examples where an attribute is located at the end of the declaration. And the attribute syntax documention has this tidbit: An attribute specifier list may appear as part of a struct, union or enum specifier. It may go either immediately after the struct, union or enum keyword, or after the closing brace. The former syntax is preferred. Where attribute specifiers follow the closing brace, they are considered to relate to the structure, union or enumerated type defined, not to any enclosing declaration the type specifier appears in, and the type defined is not complete until after the attribute specifiers. So it looks to me like it should work where I have it, doesn't it?
Sorry, I meant type attribute where I mentioned variable attribute.
The testcase passes in 4.7 and up.