This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

Fix c++ ABI failures



On request from Mark, I regression tested and installed the following
patch of his on the mainline and the 3.1 branch.

The other day I (David) noticed some failures in following the c++ ABI
on both sparc64 and IA-64.  Here is a description of the problem:

Consider the following testcase:

struct A
{
  int x, y;
  A (int a, int b) : x (a), y (b) {}
};

A foo (int x, int y)
{
  A k (x, y);
  return k;
}

According to the ABI, on sparc64 we should return class "A" in
registers because it only has a trivial constructor, no destructors
and it's size is <= 32 bytes.

It also should be returned in registers on ia64 as well.

GCC would unfortunately pass the thing in memory.  This is the point
at which my c++ knowledge ended.  I thus started to contact Mark to
help me fix this :-)

We discovered that the problem was that TREE_ADDRESSABLE was being set
on the trees for class "A".  The culprit was class.c:finish_struct_bits.

The first two tests in finish_struct_bits():

	! TYPE_HAS_TRIVIAL_INIT_REF (t)

	TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)

are OK, that is what the ABI says to do.  However the other tests are,
according to Mark, old remnants from the pre-tree-inliner days.  In
any event, these other tests break the ABI and the ABI takes
precedance over any possible performance issues.

Thus the other tests are removed.

Fully regression tested on sparc-linux-gnu and sparc64-linux-gnu.  And
my original testcase (GDB call dummys on sparc64 in gdb's
gdb.c++/userdef.exp test case) now passes.  My regression test results
may be found at:

	http://gcc.gnu.org/ml/gcc-testresults/2002-04/msg01160.html
	http://gcc.gnu.org/ml/gcc-testresults/2002-04/msg01161.html

Installed on mailine and 3.1 branch.

2002-04-30  Mark Mitchell  <mark@codesourcery.com>

	* class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if
	TYPE_HAS_TRIVIAL_INIT_REF is false or
	TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true.

--- class.c.~1~	Mon Apr 29 18:29:02 2002
+++ class.c	Mon Apr 29 18:29:44 2002
@@ -1853,15 +1853,8 @@ finish_struct_bits (t)
   /* If this type has a copy constructor or a destructor, force its mode to
      be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero.  This
      will cause it to be passed by invisible reference and prevent it from
-     being returned in a register.
-
-     Also do this if the class has BLKmode but can still be returned in
-     registers, since function_cannot_inline_p won't let us inline
-     functions returning such a type.  This affects the HP-PA.  */
-  if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
-      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
-      || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
-	  && CLASSTYPE_NON_AGGREGATE (t)))
+     being returned in a register.  */
+  if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
     {
       tree variants;
       DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;


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