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]

[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;
}


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