Bug 43859 - transparent_union mishandled
Summary: transparent_union mishandled
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.7.4
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-04-22 22:23 UTC by Peter Bergner
Modified: 2016-01-21 19:48 UTC (History)
4 users (show)

See Also:
Host: powerpc64-linux
Target: powerpc64-linux
Build: powerpc64-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments
transparent_union test case (260 bytes, text/plain)
2010-04-22 22:26 UTC, Peter Bergner
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Bergner 2010-04-22 22:23:11 UTC
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.
Comment 1 Peter Bergner 2010-04-22 22:26:05 UTC
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
Comment 2 Andrew Pinski 2010-04-22 22:44:57 UTC
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.  
Comment 3 Andrew Pinski 2010-04-22 22:48:52 UTC
I think you have the attribute in the wrong location.
Comment 4 Peter Bergner 2010-04-23 16:15:58 UTC
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?


Comment 5 Peter Bergner 2010-04-23 16:24:38 UTC
Sorry, I meant type attribute where I mentioned variable attribute.
Comment 6 Jason Merrill 2016-01-21 19:48:12 UTC
The testcase passes in 4.7 and up.