This is the mail archive of the gdb-patches@sourceware.org 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]

[RFA] c++/13225


Hi,

This bug exposes two problems with inferior function calling. First (and foremost), the user is attempting to do something like:

(gdb) p my_function
$1 = ... my_function (char *)
(gdb) p my_function(0)
Cannot resolve function my_function to any overloaded instance

This occurs because the parser interprets "0" as an integer, and the evaluator does not allow integer to pointer conversion. I cannot really think of a reason why gdb shouldn't be more permissive of this, as long as the INT will fit into a pointer.

Second, for a function which takes multiple arguments, classify_oload_match would not inspect all arguments. Instead it would return immediately upon finding any INCOMPATIBLE or NONSTANDARD ranking. For incompatible, this is okay -- subsequent arguments' ranks don't matter anymore.

However if we find NONSTANDARD, that doesn't mean that subsequent arguments' rankings should be dismissed, since one of these could be INCOMPATIBLE.

Tested on x86_64 with no regressions.

Keith

ChangeLog
2011-10-11  Keith Seitz  <keiths@redhat.com>

	c++/13225
	* gdbtypes.h (NS_POINTER_CONVERSION_BADNESS): Update comment.
	* gdbtypes.c (rank_one_type): Size permitting, allow int to pointer
	conversion.
	* valops.c (classify_oload_match): Inspect all arguments
	until INCOMPATIBLE is found. Return the worst badness found
	otherwise.

testsuite/ChangeLog:
2011-10-11  Keith Seitz  <keiths@redhat.com>

	c++/13225
	* gdb.cp/converts.cc (foo3_1): New function.
	* gdb.cp/converts.exp: Add test for int to pointer conversion.
	Add test to check if all arguments are checked for incompatible
	conversion BADNESS.

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b1dada5..ca1547a 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2470,6 +2470,11 @@ rank_one_type (struct type *parm, struct type *arg)
 	case TYPE_CODE_FUNC:
 	  return rank_one_type (TYPE_TARGET_TYPE (parm), arg);
 	case TYPE_CODE_INT:
+	  /* The parser may return an integer type for a pointer, especially
+	     if that pointer is 0 (aka NULL).  Allow this if it will fit.  */
+	  if (TYPE_LENGTH (parm) >= TYPE_LENGTH (arg))
+	    return NS_POINTER_CONVERSION_BADNESS;
+	  /* fall through  */
 	case TYPE_CODE_ENUM:
 	case TYPE_CODE_FLAGS:
 	case TYPE_CODE_CHAR:
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 9d9785b..fa6b43c 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1557,7 +1557,8 @@ extern const struct rank BASE_CONVERSION_BADNESS;
 extern const struct rank REFERENCE_CONVERSION_BADNESS;
 
 /* Non-standard conversions allowed by the debugger */
-/* Converting a pointer to an int is usually OK.  */
+/* Converting a pointer to an int is usually OK.  Also allow
+   an int to be converted into a pointer.  */
 extern const struct rank NS_POINTER_CONVERSION_BADNESS;
 
 
diff --git a/gdb/valops.c b/gdb/valops.c
index e88e9dc..b15d12f 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3081,6 +3081,7 @@ classify_oload_match (struct badness_vector *oload_champ_bv,
 		      int static_offset)
 {
   int ix;
+  enum oload_classification worst = STANDARD;
 
   for (ix = 1; ix <= nargs - static_offset; ix++)
     {
@@ -3093,11 +3094,13 @@ classify_oload_match (struct badness_vector *oload_champ_bv,
          NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD.  */
       else if (compare_ranks (oload_champ_bv->rank[ix],
                               NS_POINTER_CONVERSION_BADNESS) <= 0)
-	return NON_STANDARD;	/* Non-standard type conversions
+	worst = NON_STANDARD;	/* Non-standard type conversions
 				   needed.  */
     }
 
-  return STANDARD;		/* Only standard conversions needed.  */
+  /* If no INCOMPATIBLE classification was found, return the worst one
+     that was found (if any).  */
+  return worst;
 }
 
 /* C++: return 1 is NAME is a legitimate name for the destructor of
diff --git a/gdb/testsuite/gdb.cp/converts.cc b/gdb/testsuite/gdb.cp/converts.cc
index 34b6927..772510a 100644
--- a/gdb/testsuite/gdb.cp/converts.cc
+++ b/gdb/testsuite/gdb.cp/converts.cc
@@ -23,6 +23,8 @@ int foo2_2 (char[][1]) {return 22;}
 int foo2_3 (char *[])  {return 23;}
 int foo2_4 (int  *[])  {return 24;}
 
+int foo3_1 (int a, const char **b) { return 31; }
+
 int main()
 {
 
@@ -53,5 +55,8 @@ int main()
   foo2_2 (ba);       // ..array of arrays
   foo2_3 (b);        // ..array of pointers
   foo2_4 ((int**)b); // ..array of wrong pointers
+
+  foo3_1 (0, 0);     // int to pointer
+
   return 0;          // end of main
 }
diff --git a/gdb/testsuite/gdb.cp/converts.exp b/gdb/testsuite/gdb.cp/converts.exp
index 3f3b3c8..a3d375b 100644
--- a/gdb/testsuite/gdb.cp/converts.exp
+++ b/gdb/testsuite/gdb.cp/converts.exp
@@ -49,3 +49,8 @@ gdb_test "p foo2_1 (b)" "= 21"             "pointer pointer to pointer pointer"
 gdb_test "p foo2_2 (b)" "Cannot resolve.*" "pointer pointer to array of arrays"
 gdb_test "p foo2_3 (b)" "= 23"             "pointer pointer to array of pointers"
 gdb_test "p foo2_4 (b)" "Cannot resolve.*" "pointer pointer to array of wrong pointers"
+
+gdb_test "p foo3_1 ((char *) 0, ta)" "Cannot resolve.*" \
+    "check all parameters for badness"
+
+gdb_test "p foo3_1 (0, 0)" "= 31" "int to pointer conversion"

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