This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix c++ ABI failures
- From: "David S. Miller" <davem at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Tue, 30 Apr 2002 14:54:25 -0700 (PDT)
- Subject: 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;