This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC PATCH] Fix PR c++/12007
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Tue, 27 Jan 2004 14:01:00 -0500 (EST)
- Subject: [RFC PATCH] Fix PR c++/12007
The enclosed patch fixes a problem with thunks that is probably specific
to the PA HP-UX port. The ASM_DECLARE_FUNCTION_NAME macro for this port
outputs .EXPORT/.PARAM directives which include information about the
expected register location for arguments passed in registers. This
information is used by the linker and it will provide a stub to relocate
arguments if necessary. If the information isn't output, the linker
assumes everything is ok and arguments don't get relocated.
Normally, float arguments are passed in floating point registers.
However, in indirect calls, the general registers are used. In the
testcase provided below, we need to output an appropriate .EXPORT/.PARAM
directive to cause the linker to provide a stub to relocate the float
value from a general argument register to the appropriate float
argument register.
The simplest fix appears to be change cp/method.c so that the argument
list of the function is always cloned in the thunk. I punted on
trying to compute the RTL for the arguments. It's not available
from the function at the time the thunk is output, so it would need
to be calculated directly from the tree if it was needed. Fortunately,
we don't need this information for ASM_DECLARE_FUNCTION_NAME. However,
I had to change dbxout.c to prevent it from generating an ICE when it
encounters the parameters of a thunk with no RTL.
The enclosed patch has been tested on hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11.
I don't believe this has ever worked, so the PR is not a regression.
Ok for main?
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2004-01-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR c++/12007
* dbxout.c (dbxout_parms): Check that DECL_RTL and DECL_INCOMING_RTL
are set for parameters before outputing debugging information.
* cp/method.c (make_thunk): Clone function argument tree.
(use_thunk): Don't clone function argument tree.
Index: dbxout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dbxout.c,v
retrieving revision 1.172
diff -u -3 -p -r1.172 dbxout.c
--- dbxout.c 16 Jan 2004 01:44:06 -0000 1.172
+++ dbxout.c 26 Jan 2004 18:37:38 -0000
@@ -2708,7 +2708,10 @@ dbxout_parms (tree parms)
emit_pending_bincls_if_required ();
for (; parms; parms = TREE_CHAIN (parms))
- if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
+ if (DECL_NAME (parms)
+ && TREE_TYPE (parms) != error_mark_node
+ && DECL_RTL_SET_P (parms)
+ && DECL_INCOMING_RTL (parms))
{
dbxout_prepare_symbol (parms);
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.275
diff -u -3 -p -r1.275 method.c
--- cp/method.c 2 Jan 2004 15:57:16 -0000 1.275
+++ cp/method.c 26 Jan 2004 18:37:38 -0000
@@ -102,7 +102,7 @@ make_thunk (tree function, bool this_adj
tree fixed_offset, tree virtual_offset)
{
HOST_WIDE_INT d;
- tree thunk;
+ tree a, t, thunk;
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025);
/* We can have this thunks to covariant thunks, but not vice versa. */
@@ -181,7 +181,21 @@ make_thunk (tree function, bool this_adj
DECL_DECLARED_INLINE_P (thunk) = 0;
/* Nor has it been deferred. */
DECL_DEFERRED_FN (thunk) = 0;
-
+
+ /* Set up cloned argument trees for the thunk. */
+ t = NULL_TREE;
+ for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
+ {
+ tree x = copy_node (a);
+ TREE_CHAIN (x) = t;
+ DECL_CONTEXT (x) = thunk;
+ SET_DECL_RTL (x, NULL_RTX);
+ t = x;
+ }
+ a = nreverse (t);
+ DECL_ARGUMENTS (thunk) = a;
+ DECL_RESULT (thunk) = NULL_TREE;
+
/* Add it to the list of thunks associated with FUNCTION. */
TREE_CHAIN (thunk) = DECL_THUNKS (function);
DECL_THUNKS (function) = thunk;
@@ -450,33 +464,19 @@ use_thunk (tree thunk_fndecl, bool emit_
just makes a call to the real function. Unfortunately, this
doesn't work for varargs. */
- tree a, t;
+ tree a = DECL_ARGUMENTS (thunk_fndecl);
+ tree t = a;
if (varargs_function_p (function))
error ("generic thunk code fails for method `%#D' which uses `...'",
function);
- /* Set up cloned argument trees for the thunk. */
- t = NULL_TREE;
- for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
- {
- tree x = copy_node (a);
- TREE_CHAIN (x) = t;
- DECL_CONTEXT (x) = thunk_fndecl;
- SET_DECL_RTL (x, NULL_RTX);
- t = x;
- }
- a = nreverse (t);
- DECL_ARGUMENTS (thunk_fndecl) = a;
- DECL_RESULT (thunk_fndecl) = NULL_TREE;
-
start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
/* We don't bother with a body block for thunks. */
/* There's no need to check accessibility inside the thunk body. */
push_deferring_access_checks (dk_no_check);
- t = a;
if (this_adjusting)
t = thunk_adjust (t, /*this_adjusting=*/1,
fixed_offset, virtual_offset);
Test case for installation in g++.dg/other/vthunk1.C:
// PR c++/12007 Multiple inheritance float pass by value fails
// { dg-do run }
extern "C" void abort (void);
class gvImpl
{
public:
virtual void PutVal(float value){}
};
class foo { public: virtual void Bar(){} };
class myGv: public foo, public gvImpl
{
void PutVal(float value){ if (value != 3.14159f) abort (); }
};
myGv x;
gvImpl* object = &x;
int main()
{
object->PutVal(3.14159f);
return 0;
}