Re: [PATCH] Classify non-POD struct types more or less correctly on AMD64

Jan Hubicka
2004-01-11T13:29:24Z

> [ This might interest GCC folks. The problem we're facing here is
> that on AMD64, and other targets that return small structures in
> registers, it isn't clear how small C++ classes are returned. Some
> are returned in registers and some are returned in memory. The
> AMD64 ABI explicitly says that non-POD structures and unions are
> returned in memory, but GCC doesn't seem to be ABI-compliant here.
> Is this considered to be a bug? ]
>
> Date: Sat, 10 Jan 2004 23:10:09 -0500
> From: Daniel Jacobowitz <drow@mvista.com>
>
> Looking at that function it looks like it will even return some classes
> with baseclasses in registers. I won't excerpt it here, as it's quite
> large. But it iterates over the baseclasses. If none of them are
> larger than 16 bytes (a given, if the derived class isn't larger than
> 16 bytes) or of a variable size (C++ classes are never variably sized I
> don't think) or of TFmode/TCmode (128-bit long doubles), I believe that
> the aggregate will be returned in registers.
>
> That function just implements the rules for normal C structures. Th
> rules are a bit more complex than you say above, but that bit is
> implemented correctly in GDB. At least that's the intention. The
> decision to not pass certain C++ classes in registers is made
> somewhere else, most notably in cp/class.c:finish_struct_bits(), where
> TYPE_MODE is set to BLKmode, and TREE_ADDRESSABLE is set. Both
> conditions are enough to get the type returned in memory instead of
> registers. However, there are more places where TREE_ADDRESSABLE is
> tweaked.
>
> The 1996 ANSI C++ draft has the following statement about non-POD-ness:

The non-POD clause in x86-64 ABI comes from Mark (GCC C++ maintainer)
and I must admit that I don't fully understand to these issues.
The decisions come from C++ frontend via TREE_ADDRESSABLE flag, as you
already noticed and they should comply what IA-64 ABI is saying (we
simply use that document for x86-64 ABI too). Perhaps it is more
specific about what shall be passed in registers.
>
> "A POD-struct is an aggregate class that has no non-static data members
> of type pointer to member, non-POD-struct, non-POD- union (or array of
> such types) or reference, and has no user-defined copy assignment
> operator and no user-defined destructor. Similarly, a POD-union is an
> aggregate union that has no non-static data members of type pointer to
> member, non-POD-struct, non-POD-union (or array of such types) or
> reference, and has no user-defined copy assignment operator and no
> user-defined destructor. A POD class is a class that is either a
> POD-struct or a POD-union."
>
> So it doesn't say anything about baseclasses. So the code I checked
> in is defenitely wrong :-(.
>
> IOW it doesn't look to me as if GCC implements the non-POD rule. You
> might wish to try returning a simple non-POD derived class and see what
> GCC generates.
>
> Looks very much like it. I can make a class with a user-defined copy
> assignment operator that gets returned in registers by GCC. So GCC
> doesn't correctly implement the ABI :-(.

This seems obviously wrong to me. If you do have testcase, you may want
to fill it in GCC bugzilla. Especially if you can write simple testcase
that fails when copy constructor is not properly used.
I hope that Mark or Jason can take a look into this issue themselves.

Honza
>
> The same problem exist on other targets though. I've seen problems on
> 64-bit SPARC and FreeBSD/i386 too. The FreeBSD/i386 case is
> interesting since the other i386 platforms are OK. This is because
> FreeBSD uses a different ABI, where -freg-struct-return is the
> default. The System V psABI says that all aggregate types are
> returned in memory (-fpcc-struct-return). This is probably the reason
> why GCC has so many bugs related to returning small structs; the
> majority of people hacking on GNU/Linux IA-32 boxen doesn't see the
> problems.
>
> Mark