Diagnose invalid pointer arithmetic on gdb.Value

Message ID 20160920144601.GA3459@redhat.com
State New, archived
Headers

Commit Message

Jonathan Wakely Sept. 20, 2016, 2:46 p.m. UTC
  Instead of passing invalid arguments to value_binop and getting a
misleading error, raise a TypeError directly in valpy_binop_throw.

gdb/ChangeLog:
2016-09-20  Jonathan Wakely  <jwakely@redhat.com>

	PR python/20622
	* python/py-value.c (valpy_binop_throw): Throw TypeError for pointer
	arithmetic with invalid types instead of passing arguments to
	value_binop.

gdb/testsuite/ChangeLog:
2016-09-20  Jonathan Wakely  <jwakely@redhat.com>

	PR python/20622
	* gdb.python/py-value.exp: Test invalid pointer arithmetic.
commit 17ee03b254118af0108a976125984e7f5ff3858d
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Sep 20 15:39:44 2016 +0100

    gdb: Diagnose invalid pointer arithmetic on gdb.Value
    
    Instead of passing invalid arguments to value_binop and getting a
    misleading error, raise a TypeError directly in valpy_binop_throw.
    
    gdb/ChangeLog:
    2016-09-20  Jonathan Wakely  <jwakely@redhat.com>
    
    	PR python/20622
    	* python/py-value.c (valpy_binop_throw): Throw TypeError for pointer
    	arithmetic with invalid types instead of passing arguments to
    	value_binop.
    
    gdb/testsuite/ChangeLog:
    2016-09-20  Jonathan Wakely  <jwakely@redhat.com>
    
    	PR python/20622
    	* gdb.python/py-value.exp: Test invalid pointer arithmetic.
  

Comments

Pedro Alves Sept. 20, 2016, 3:41 p.m. UTC | #1
On 09/20/2016 03:46 PM, Jonathan Wakely wrote:
> Instead of passing invalid arguments to value_binop and getting a
> misleading error, raise a TypeError directly in valpy_binop_throw.

Did you try changing value_binop instead?  The error string seems
misleading even in C:

(gdb) p ptr
$1 = 0x601040 <buf> ""
(gdb) p ptr + 1
$2 = 0x601041 <buf+1> ""
(gdb) p ptr + 1.0
Argument to arithmetic operation not a number or boolean.
(gdb)

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 21e9247..560f56a 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1064,18 +1064,28 @@  valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
 	rtype = check_typedef (rtype);
 	rtype = STRIP_REFERENCE (rtype);
 
-	handled = 1;
-	if (TYPE_CODE (ltype) == TYPE_CODE_PTR
-	    && is_integral_type (rtype))
-	  res_val = value_ptradd (arg1, value_as_long (arg2));
-	else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
-		 && is_integral_type (ltype))
-	  res_val = value_ptradd (arg2, value_as_long (arg1));
+        handled = 1;
+	if (TYPE_CODE (ltype) == TYPE_CODE_PTR)
+          {
+            if (is_integral_type (rtype))
+              res_val = value_ptradd (arg1, value_as_long (arg2));
+            else
+              PyErr_SetString (PyExc_TypeError, _("pointer arithmetic with "
+                                                  "non-integer argument."));
+          }
+	else if (TYPE_CODE (rtype) == TYPE_CODE_PTR)
+          {
+            if (is_integral_type (ltype))
+              res_val = value_ptradd (arg2, value_as_long (arg1));
+            else
+              PyErr_SetString (PyExc_TypeError, _("pointer arithmetic with "
+                                                  "non-integer argument."));
+          }
 	else
-	  {
-	    handled = 0;
-	    op = BINOP_ADD;
-	  }
+          {
+            handled = 0;
+            op = BINOP_ADD;
+          }
       }
       break;
     case VALPY_SUB:
@@ -1094,9 +1104,14 @@  valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
 	  /* A ptrdiff_t for the target would be preferable here.  */
 	  res_val = value_from_longest (builtin_type_pyint,
 					value_ptrdiff (arg1, arg2));
-	else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
-		 && is_integral_type (rtype))
-	  res_val = value_ptradd (arg1, - value_as_long (arg2));
+	else if (TYPE_CODE (ltype) == TYPE_CODE_PTR)
+          {
+            if (is_integral_type (rtype))
+              res_val = value_ptradd (arg1, - value_as_long (arg2));
+            else
+              PyErr_SetString (PyExc_TypeError, _("pointer arithmetic with "
+                                                  "non-integer argument."));
+          }
 	else
 	  {
 	    handled = 0;
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 57a9ba1..6ad3658 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -144,6 +144,24 @@  proc test_value_numeric_ops {} {
       -re "result = .*$gdb_prompt $"  {fail "catch throw of GDB error"}
       -re "$gdb_prompt $"	      {fail "catch throw of GDB error"}
   }
+
+  gdb_test_multiple "python print ('result = ' + str(a+0.5))" "catch error in python type conversion" {
+      -re "pointer arithmetic with non-integer argument.*$gdb_prompt $"   {pass "catch error in python type conversion"}
+      -re "result = .*$gdb_prompt $"		      {fail "catch error in python type conversion"}
+      -re "$gdb_prompt $"			      {fail "catch error in python type conversion"}
+  }
+
+  gdb_test_multiple "python print ('result = ' + str(0.5+a))" "catch error in python type conversion" {
+      -re "pointer arithmetic with non-integer argument.*$gdb_prompt $"   {pass "catch error in python type conversion"}
+      -re "result = .*$gdb_prompt $"		      {fail "catch error in python type conversion"}
+      -re "$gdb_prompt $"			      {fail "catch error in python type conversion"}
+  }
+
+  gdb_test_multiple "python print ('result = ' + str(a-0.5))" "catch error in python type conversion" {
+      -re "pointer arithmetic with non-integer argument.*$gdb_prompt $"   {pass "catch error in python type conversion"}
+      -re "result = .*$gdb_prompt $"		      {fail "catch error in python type conversion"}
+      -re "$gdb_prompt $"			      {fail "catch error in python type conversion"}
+  }
 }
 
 proc test_value_boolean {} {