This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


[ 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:

  "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 :-(.

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]