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: [RFA] Fix calling of static C++ member functions


Peter, I suspect that if you and DanielJ are both happy with this, it is in.

Andrew
--- Begin Message ---
This one fixes
http://sources.redhat.com/ml/bug-gdb/2001-06/msg00059.html
which is still broken in CVS Head GDB.

Actually there are a bunch problems:

- The printing of the bad value happens, because find_overload_match does
  not set *staticp for static member functions.

- The crash happens because in
        domain = TYPE_DOMAIN_TYPE (fns_ptr[0].type);
  in find_overload_match we don't find the domain, as find_method_list
  doesn't handle stub methods correctly and it's too late in
  find_overload_match. Checking for stub methods in find_method_list
  instead gets rid of the crash.

- When trying the provided testcase for dwarf2, more problems arise.
  Until now check_stub_method did not handle static member
  functions correctly, as the this parameter was added unconditionally.
  After fixing this, we also have to adjust typecmp, so that static
  member functions also work with `set overload off'.
  And finally we have to fix find_overload_match, to make it behave properly
  in the `set overload on' case.

The patch below fixes the calling of static member functions for
gcc-2.95.2/gcc-3.x and stabs/dwarf2 debugging, ok to commit ?

2002-03-15  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>

	Fix calling of static member functions.
	* gdbtypes.c (check_stub_method): Handle static member functions.
	* valops.c (typecmp): Handle static member functions correctly.
	(find_overload_match): Ditto, set *staticp for static member
	functions.
	(find_method_list): Check for stub functions here, not in
	find_overload_match.

--- ./gdbtypes.c.orig	Sat Feb  9 12:18:12 2002
+++ ./gdbtypes.c	Sat Mar  2 11:32:33 2002
@@ -1647,9 +1650,16 @@ check_stub_method (struct type *type, in
   argtypes = (struct type **)
     TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
   p = argtypetext;
-  /* FIXME: This is wrong for static member functions.  */
-  argtypes[0] = lookup_pointer_type (type);
-  argcount = 1;
+
+  /* Add THIS pointer for non-static methods.  */
+  f = TYPE_FN_FIELDLIST1 (type, method_id);
+  if (TYPE_FN_FIELD_STATIC_P (f, signature_id))
+    argcount = 0;
+  else
+    {
+      argtypes[0] = lookup_pointer_type (type);
+      argcount = 1;
+    }
 
   if (*p != ')')		/* () means no args, skip while */
     {
@@ -1692,8 +1702,6 @@ check_stub_method (struct type *type, in
 
   xfree (demangled_name);
 
-  f = TYPE_FN_FIELDLIST1 (type, method_id);
-
   TYPE_FN_FIELD_PHYSNAME (f, signature_id) = mangled_name;
 
   /* Now update the old "stub" type into a real type.  */
--- ./valops.c.orig	Mon Feb 18 11:13:54 2002
+++ ./valops.c	Sat Mar  2 11:32:38 2002
@@ -1952,7 +1952,11 @@ typecmp (int staticp, struct type *t1[],
     return 0;
   if (t1[!staticp] == 0)
     return 0;
-  for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
+  /* Skip `this' argument if applicable.  */
+  t2++;
+  if (!staticp)
+    t1++;
+  for (i = 0; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
     {
       struct type *tt1, *tt2;
       if (!t2[i])
@@ -2521,10 +2525,19 @@ find_method_list (struct value **argp, c
       char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
       if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
 	{
-	  *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i);
+	  int len = TYPE_FN_FIELDLIST_LENGTH (type, i);
+	  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+	  int j;
+
+	  *num_fns = len;
 	  *basetype = type;
 	  *boffset = offset;
-	  return TYPE_FN_FIELDLIST1 (type, i);
+	  for (j = 0; j < len; j++)
+	    {
+	      if (TYPE_FN_FIELD_STUB (f, j))
+		check_stub_method (type, i, j);
+	    }
+	  return f;
 	}
     }
 
@@ -2670,6 +2683,7 @@ find_overload_match (struct type **arg_t
   int boffset;
   register int jj;
   register int ix;
+  int static_offset;
 
   char *obj_type_name = NULL;
   char *func_name = NULL;
@@ -2677,9 +2691,6 @@ find_overload_match (struct type **arg_t
   /* Get the list of overloaded methods or functions */
   if (method)
     {
-      int i;
-      int len;
-      struct type *domain;
       obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
       /* Hack: evaluate_subexp_standard often passes in a pointer
          value rather than the object itself, so try again */
@@ -2696,26 +2707,6 @@ find_overload_match (struct type **arg_t
 	       obj_type_name,
 	       (obj_type_name && *obj_type_name) ? "::" : "",
 	       name);
-      domain = TYPE_DOMAIN_TYPE (fns_ptr[0].type);
-      len = TYPE_NFN_FIELDS (domain);
-      /* NOTE: dan/2000-03-10: This stuff is for STABS, which won't
-         give us the info we need directly in the types. We have to
-         use the method stub conversion to get it. Be aware that this
-         is by no means perfect, and if you use STABS, please move to
-         DWARF-2, or something like it, because trying to improve
-         overloading using STABS is really a waste of time. */
-      for (i = 0; i < len; i++)
-	{
-	  int j;
-	  struct fn_field *f = TYPE_FN_FIELDLIST1 (domain, i);
-	  int len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
-	  for (j = 0; j < len2; j++)
-	    {
-	      if (TYPE_FN_FIELD_STUB (f, j) && (!strcmp_iw (TYPE_FN_FIELDLIST_NAME (domain,i),name)))
-		check_stub_method (domain, i, j);
-	    }
-	}
     }
   else
     {
@@ -2742,10 +2733,11 @@ find_overload_match (struct type **arg_t
   /* Consider each candidate in turn */
   for (ix = 0; ix < num_fns; ix++)
     {
+      static_offset = 0;
       if (method)
 	{
-	  /* For static member functions, we won't have a this pointer, but nothing
-	     else seems to handle them right now, so we just pretend ourselves */
+	  if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
+	    static_offset = 1;
 	  nparms=0;
 
 	  if (TYPE_FN_FIELD_ARGS(fns_ptr,ix))
@@ -2768,7 +2760,7 @@ find_overload_match (struct type **arg_t
 			  : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
 
       /* Compare parameter types to supplied argument types */
-      bv = rank_function (parm_types, nparms, arg_types, nargs);
+      bv = rank_function (parm_types, nparms, arg_types + static_offset, nargs - static_offset);
 
       if (!oload_champ_bv)
 	{
@@ -2806,7 +2798,7 @@ find_overload_match (struct type **arg_t
 	    fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
 	  else
 	    fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
-	  for (jj = 0; jj < nargs; jj++)
+	  for (jj = 0; jj < nargs - static_offset; jj++)
 	    fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
 	  fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
 	}
@@ -2830,7 +2822,10 @@ find_overload_match (struct type **arg_t
 #endif
 
   /* Check how bad the best match is */
-  for (ix = 1; ix <= nargs; ix++)
+  static_offset = 0;
+  if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+    static_offset = 1;
+  for (ix = 1; ix <= nargs - static_offset; ix++)
     {
       if (oload_champ_bv->rank[ix] >= 100)
 	oload_incompatible = 1;	/* truly mismatched types */
@@ -2863,6 +2858,8 @@ find_overload_match (struct type **arg_t
 
   if (method)
     {
+      if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+	*staticp = 1;
       if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
 	*valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
       else

-- 
Peter Schauer			pes@regent.e-technik.tu-muenchen.de

--- End Message ---

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