From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 530 invoked by alias); 8 Nov 2011 21:40:45 -0000 Received: (qmail 516 invoked by uid 22791); 8 Nov 2011 21:40:44 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,TW_IV X-Spam-Check-By: sourceware.org Received: from qmta03.westchester.pa.mail.comcast.net (HELO qmta03.westchester.pa.mail.comcast.net) (76.96.62.32) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 08 Nov 2011 21:40:30 +0000 Received: from omta02.westchester.pa.mail.comcast.net ([76.96.62.19]) by qmta03.westchester.pa.mail.comcast.net with comcast id ulWN1h0090QuhwU53lgXTX; Tue, 08 Nov 2011 21:40:31 +0000 Received: from [10.127.248.57] ([65.206.2.68]) by omta02.westchester.pa.mail.comcast.net with comcast id ulgF1h0111U2a2h3NlgJVp; Tue, 08 Nov 2011 21:40:28 +0000 Subject: [RFA] Python: raise exception on field-related gdb.Type methods if it's not struct or union Mime-Version: 1.0 (Apple Message framework v1084) Content-Type: text/plain; charset=us-ascii From: Paul Koning In-Reply-To: Date: Tue, 08 Nov 2011 21:40:00 -0000 Cc: Eli Zaretskii , tromey@redhat.com, gdb-patches@sourceware.org Content-Transfer-Encoding: quoted-printable Message-Id: References: <3A3AF5AE-70E8-43D0-B8CE-DCADFEEF879A@comcast.net> <560557F2-1B8B-4633-8CD6-E63705EEAF0E@comcast.net> <83wrckrcg1.fsf@gnu.org> <37B202A1-DCD5-423E-8E30-55A6F2BE21EF@comcast.net> To: Doug Evans Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-11/txt/msg00210.txt.bz2 On Nov 5, 2011, at 5:04 PM, Doug Evans wrote: > On Sat, Nov 5, 2011 at 7:36 AM, Paul Koning wrot= e: >>> Maybe I'd be happy if gdb.Type (and maybe gdb.Value) were simply more >>> rigorous in throwing exceptions for invalid cases. >>=20 >> I agree. I'll put that together. >=20 > Sounds great if it's possible. >=20 > I don't know enough about the C Python API, but when I tried a simple > hack to have len(scalar_type) throw an exception "not scalar_type" > started throwing exceptions too. :-( See PyObject_IsTrue. I found the answer to that question with a bit of searching. Attached is = a patch that raises an exception (TypeError) for len() and all the field re= ference methods if the type isn't struct or union. Does this need new testcases? paul ChangeLog: 2011-11-08 Paul Koning * python/py-type.c (typy_deref): New function. (typy_nonzero): New function. (typy_length): Raise exception if not struct or union type. (typy_getitem): Ditto. (typy_has_key): Ditto. (typy_make_iter): Ditto. Index: python/py-type.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvs/src/src/gdb/python/py-type.c,v retrieving revision 1.28 diff -u -p -r1.28 py-type.c --- python/py-type.c 4 Nov 2011 11:57:04 -0000 1.28 +++ python/py-type.c 8 Nov 2011 21:36:40 -0000 @@ -350,6 +350,45 @@ typy_strip_typedefs (PyObject *self, PyO return type_to_type_object (check_typedef (type)); } =20 +/* Strip typedefs and pointers/reference from a type. Then check that + it is a struct or union type. If not, raise TypeError. */ +static struct type * +typy_deref (struct type *type) +{ + volatile struct gdb_exception except; + + for (;;) + { + TRY_CATCH (except, RETURN_MASK_ALL) + { + CHECK_TYPEDEF (type); + } + /* Don't use GDB_PY_HANDLE_EXCEPTION here because that returns + a (NULL) pointer of the wrong type. */ + if (except.reason < 0) + { + gdbpy_convert_exception (except); + return NULL; + } + + if (TYPE_CODE (type) !=3D TYPE_CODE_PTR + && TYPE_CODE (type) !=3D TYPE_CODE_REF) + break; + type =3D TYPE_TARGET_TYPE (type); + } + + /* If this is not a struct or union type, raise TypeError exception. */ + if (TYPE_CODE (type) !=3D TYPE_CODE_STRUCT=20 + && TYPE_CODE (type) !=3D TYPE_CODE_UNION) + { + PyErr_SetString (PyExc_TypeError, + "Type is not a structure or union type."); + return NULL; + } +=20=20 + return type; +} + /* Return an array type. */ =20 static PyObject * @@ -1124,9 +1163,22 @@ typy_length (PyObject *self) { struct type *type =3D ((type_object *) self)->type; =20 + type =3D typy_deref (type); + if (type =3D=3D NULL) + return -1; + return TYPE_NFIELDS (type); } =20 +/* Implements boolean evaluation of gdb.Type. Handle this like other + Python objects that don't have a meaningful truth value -- all=20 + values are true. */ +static int +typy_nonzero (PyObject *self) +{ + return 1; +} + /* Return a gdb.Field object for the field named by the argument. */ =20 static PyObject * @@ -1145,20 +1197,10 @@ typy_getitem (PyObject *self, PyObject * using lookup_struct_elt_type, portions of that function are copied here. */ =20 - for (;;) - { - TRY_CATCH (except, RETURN_MASK_ALL) - { - CHECK_TYPEDEF (type); - } - GDB_PY_HANDLE_EXCEPTION (except); - - if (TYPE_CODE (type) !=3D TYPE_CODE_PTR - && TYPE_CODE (type) !=3D TYPE_CODE_REF) - break; - type =3D TYPE_TARGET_TYPE (type); - } - + type =3D typy_deref (type); + if (type =3D=3D NULL) + return NULL; +=20=20 for (i =3D 0; i < TYPE_NFIELDS (type); i++) { char *t_field_name =3D TYPE_FIELD_NAME (type, i); @@ -1216,18 +1258,9 @@ typy_has_key (PyObject *self, PyObject * using lookup_struct_elt_type, portions of that function are copied here. */ =20 - for (;;) - { - TRY_CATCH (except, RETURN_MASK_ALL) - { - CHECK_TYPEDEF (type); - } - GDB_PY_HANDLE_EXCEPTION (except); - if (TYPE_CODE (type) !=3D TYPE_CODE_PTR - && TYPE_CODE (type) !=3D TYPE_CODE_REF) - break; - type =3D TYPE_TARGET_TYPE (type); - } + type =3D typy_deref (type); + if (type =3D=3D NULL) + return NULL; =20 for (i =3D 0; i < TYPE_NFIELDS (type); i++) { @@ -1246,6 +1279,10 @@ typy_make_iter (PyObject *self, enum gdb { typy_iterator_object *typy_iter_obj; =20 + /* Check that "self" is a structure or union type. */ + if (typy_deref (((type_object *) self)->type) =3D=3D NULL) + return NULL; +=20=20 typy_iter_obj =3D PyObject_New (typy_iterator_object, &type_iterator_object_type); if (typy_iter_obj =3D=3D NULL) @@ -1499,6 +1536,32 @@ Return a volatile variant of this type"=20 { NULL } }; =20 +static PyNumberMethods type_object_as_number =3D { + NULL, /* nb_add */ + NULL, /* nb_subtract */ + NULL, /* nb_multiply */ + NULL, /* nb_divide */ + NULL, /* nb_remainder */ + NULL, /* nb_divmod */ + NULL, /* nb_power */ + NULL, /* nb_negative */ + NULL, /* nb_positive */ + NULL, /* nb_absolute */ + typy_nonzero, /* nb_nonzero */ + NULL, /* nb_invert */ + NULL, /* nb_lshift */ + NULL, /* nb_rshift */ + NULL, /* nb_and */ + NULL, /* nb_xor */ + NULL, /* nb_or */ + NULL, /* nb_coerce */ + NULL, /* nb_int */ + NULL, /* nb_long */ + NULL, /* nb_float */ + NULL, /* nb_oct */ + NULL /* nb_hex */ +}; + static PyMappingMethods typy_mapping =3D { typy_length, typy_getitem, @@ -1518,7 +1581,7 @@ static PyTypeObject type_object_type =3D 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ - 0, /*tp_as_number*/ + &type_object_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ &typy_mapping, /*tp_as_mapping*/ 0, /*tp_hash */