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]

RE: [PATCH 1/2] Partial fix for PR 14160


> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-owner@sourceware.org] On Behalf Of Tom Tromey
> Sent: Tuesday, July 03, 2012 10:57 PM
> To: gdb-patches@sourceware.org


[...]

> +  if (die->parent->tag != DW_TAG_structure_type
> +      && die->parent->tag != DW_TAG_union_type
> +      && die->parent->tag != DW_TAG_class_type)
> +    return 0;

Should you also check the language?

[...]


The remainder of the patch seems unrelated.

> diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp
> index 1eb82eb..9cb4a39 100644
> --- a/gdb/testsuite/gdb.cp/templates.exp
> +++ b/gdb/testsuite/gdb.cp/templates.exp
> @@ -63,6 +63,14 @@ proc test_ptype_of_templates {} {
>  	    # This also triggers gdb/1113...
>  	    kfail "gdb/1111" "ptype T5<int>"
>  	    # Add here a PASS case when PR gdb/1111 gets fixed.
> +	    # These are really:
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8216
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8218
> +	}
> +	-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const
> T5<int>) ?&\\);${ws}~T5\\(int\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator
> delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8218
> +	    # The destructor has an argument type.
> +	    kfail "gdb/8218" "ptype T5<int>"
>  	}
>      }
> 
> @@ -92,6 +100,14 @@ proc test_ptype_of_templates {} {
>  	    # This also triggers gdb/1113...
>  	    kfail "gdb/1111" "ptype T5<int>"
>  	    # Add here a PASS case when PR gdb/1111 gets fixed.
> +	    # These are really:
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8216
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8218
> +	}
> +	-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const
> T5<int>) ?&\\);${ws}~T5\\(int\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator
> delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
> +	    # http://sourceware.org/bugzilla/show_bug.cgi?id=8218
> +	    # The destructor has an argument type.
> +	    kfail "gdb/8218" "ptype T5<int>"
>  	}
>      }
>  }
> diff --git a/gdb/valarith.c b/gdb/valarith.c
> index 96d5411..d626cff 100644
> --- a/gdb/valarith.c
> +++ b/gdb/valarith.c
> @@ -31,6 +31,7 @@
>  #include <math.h>
>  #include "infcall.h"
>  #include "exceptions.h"
> +#include "cp-abi.h"
> 
>  /* Define whether or not the C operator '/' truncates towards zero for
>     differently signed operands (truncation direction is undefined in C).  */
> @@ -643,6 +644,329 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
> 
>    return 0;			/* For lint -- never reached */
>  }
> +
> +/* Call the appropriate 'operator new' to allocate memory.
> +
> +   GLOBAL_NEW is true if the global ::operator new should be used.
> +
> +   TYPE is the type being allocated.  If it is an array type,
> +   'operator new[]' is used.
> +
> +   ARGV are the arguments to the operator.  The calling convention
> +   here is a little funny in that ARGV[0] must be NULL -- it may be
> +   filled in during overload searching.  ARGV[1] should be the size of
> +   the allocation.
> +
> +   ARGC is the number of arguments in ARGV, including the initial
> +   empty slot.
> +
> +   Returns a newly-allocated object; or throws an exception on error.  */
> +
> +struct value *
> +value_operator_new (int global_new, struct type *type,
> +		    int argc, struct value **argv)
> +{
> +  enum oload_search_type method = BOTH;
> +  struct value *function = NULL;
> +  struct symbol *sym = NULL;
> +  const char *opname = "operator new";
> +  int static_memfunp;
> +
> +  gdb_assert (argv[0] == NULL);
> +
> +  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
> +    {
> +      opname = "operator new[]";
> +      while (TYPE_CODE (type) == TYPE_CODE_ARRAY)
> +	type = check_typedef (TYPE_TARGET_TYPE (type));
> +    }
> +  if (!global_new && TYPE_CODE (type) == TYPE_CODE_STRUCT)
> +    {
> +      volatile struct gdb_exception except;
> +      struct value *arg;
> +
> +      argv[0] = value_zero (type, lval_memory);
> +      arg = argv[0];
> +      TRY_CATCH (except, RETURN_MASK_ERROR)
> +	{
> +	  find_overload_match (argv, argc, opname, METHOD,
> +			       0 /* strict match */, &arg, NULL,
> +			       &function, &sym, &static_memfunp, 1);
> +	}
> +      if (except.reason < 0)
> +	{
> +	  sym = NULL;
> +	  function = NULL;
> +	}
> +    }
> +
> +  if (sym == NULL && function == NULL)
> +    find_overload_match (argv + 1, argc - 1, opname, NON_METHOD,
> +			 0 /* strict match */, NULL, NULL,
> +			 NULL, &sym, NULL, 1);
> +
> +  if (sym != NULL)
> +    function = value_of_variable (sym, 0);
> +
> +  if (function == NULL)
> +    throw_error (NOT_FOUND_ERROR,
> +		 _("could not find appropriate '%s'"), opname);
> +
> +  return call_function_by_hand (function, argc - 1, argv + 1);
> +}
> +
> +/* Call a constructor for a new object.
> +
> +   TYPE is the type whose constructor is to be called.
> +   ARGC and ARGV are the arguments to pass to the constructor.  At
> +   least one argument is required -- the object itself.
> +
> +   Ordinarily TYPE must refer to a type that can have a constructor,
> +   like a class.  However, it can also refer to a scalar type if there
> +   are one or two arguments.  In the one-argument case, nothing is
> +   done.  In the two-argument case, the argument is treated as an
> +   initializer.
> +
> +   This performs an inferior function call and throws an exception on
> +   any error.  */
> +
> +void
> +value_construct (struct type *type, int argc, struct value **argv)
> +{
> +  struct symbol *sym = NULL;
> +  struct value *function = NULL;
> +  int i;
> +  const char *constr_name;
> +
> +  gdb_assert (argc >= 1);
> +
> +  if (TYPE_CODE (type) == TYPE_CODE_PTR
> +      || TYPE_CODE (type) == TYPE_CODE_ENUM
> +      || TYPE_CODE (type) == TYPE_CODE_INT
> +      || TYPE_CODE (type) == TYPE_CODE_FLT
> +      || TYPE_CODE (type) == TYPE_CODE_BOOL
> +      || TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
> +    {
> +      struct value *mem, *val;
> +
> +      if (argc == 1)
> +	return;
> +
> +      if (argc != 2)
> +	error (_("too many arguments to construct for '%s'"),
> +	       TYPE_SAFE_NAME (type));
> +
> +      mem = value_ind (argv[0]);
> +      val = value_cast (value_type (mem), argv[1]);
> +      value_assign (mem, val);
> +      return;
> +    }
> +
> +  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
> +    {
> +      if (argc == 1)
> +	return;
> +      error (_("cannot pass arguments to 'new' of '%s'"),
> +	     TYPE_SAFE_NAME (type));
> +    }
> +
> +  /* Find the constructor name, if we can.  */
> +  constr_name = NULL;
> +  for (i = 0; constr_name == NULL && i < TYPE_NFN_FIELDS (type); ++i)
> +    {
> +      struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
> +      int j;
> +
> +      for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
> +	{
> +	  if (TYPE_FN_FIELD_CONSTRUCTOR (f, j)
> +	      || is_constructor_name (TYPE_FN_FIELD_PHYSNAME (f, j)))
> +	    {
> +	      constr_name = TYPE_FN_FIELDLIST_NAME (type, i);
> +	      break;
> +	    }
> +	}
> +    }
> +
> +  if (constr_name != NULL)
> +    {
> +      struct value *obj = value_ind (argv[0]);
> +
> +      find_overload_match (argv, argc, constr_name, METHOD, 0,
> +			   &obj, NULL, &function, &sym, NULL, 1);
> +    }
> +
> +  if (sym != NULL)
> +    function = value_of_variable (sym, 0);
> +
> +  if (function == NULL)
> +    {
> +      /* No construct is fine for a POD.  */
> +      if (argc == 1)
> +	return;
> +
> +      throw_error (NOT_FOUND_ERROR,
> +		   _("no matching constructor found for '%s'"),
> +		   TYPE_SAFE_NAME (type));
> +    }
> +
> +  call_function_by_hand (function, argc, argv);
> +}
> +
> +/* Call the appropriate 'operator delete' to deallocate memory.
> +
> +   GLOBAL_DEL is true if the global ::operator delete should be
> +   called.
> +
> +   IS_ARRAY is true if operator delete[] should be called.
> +
> +   OBJECT is the object to delete.
> +
> +   Throws an exception on error.  */
> +
> +void
> +value_operator_delete (int global_del, int is_array, struct value *object)
> +{
> +  enum oload_search_type method = BOTH;
> +  struct value *function = NULL;
> +  struct symbol *sym = NULL;
> +  const char *opname = "operator delete";
> +  int static_memfunp;
> +  struct type *type;
> +  struct value *argv[2];
> +  struct gdbarch *arch;
> +
> +  type = check_typedef (value_type (object));
> +  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR);
> +  type = check_typedef (TYPE_TARGET_TYPE (type));
> +  while (TYPE_CODE (type) == TYPE_CODE_ARRAY)
> +    type = check_typedef (TYPE_TARGET_TYPE (type));
> +
> +  if (is_array)
> +    opname = "operator delete[]";
> +
> +  arch = get_type_arch (type);
> +  argv[1] = value_cast (lookup_pointer_type (builtin_type (arch)->builtin_void),
> +			object);
> +
> +  if (!global_del && TYPE_CODE (type) == TYPE_CODE_STRUCT)
> +    {
> +      volatile struct gdb_exception except;
> +      struct value *arg;
> +
> +      argv[0] = value_zero (type, lval_memory);
> +      arg = argv[0];
> +      TRY_CATCH (except, RETURN_MASK_ERROR)
> +	{
> +	  find_overload_match (argv, 2, opname, METHOD,
> +			       0 /* strict match */, &arg, NULL,
> +			       &function, &sym, &static_memfunp, 1);
> +	}
> +      if (except.reason < 0)
> +	{
> +	  sym = NULL;
> +	  function = NULL;
> +	}
> +    }
> +
> +  if (sym == NULL && function == NULL)
> +    find_overload_match (argv + 1, 1, opname, NON_METHOD,
> +			 0 /* strict match */, NULL, NULL,
> +			 NULL, &sym, NULL, 1);
> +
> +  if (sym != NULL)
> +    function = value_of_variable (sym, 0);
> +
> +  if (function == NULL)
> +    throw_error (NOT_FOUND_ERROR,
> +		 _("could not find appropriate '%s'"), opname);
> +
> +  call_function_by_hand (function, 1, argv + 1);
> +}
> +
> +/* Call a destructor for an object.
> +
> +   OBJECT is the object to destroy.
> +
> +   IS_ARRAY is true if this object represents an array.
> +
> +   If IS_ARRAY is true and the base type of OBJECT has a destructor,
> +   then this function will return a new value which is the memory that
> +   was actually allocated by new[].  This will differ from OBJECT by
> +   some padding.  In other cases, this function returns NULL.
> +
> +   This performs an inferior function call and throws an exception on
> +   any error.  */
> +
> +struct value *
> +value_destruct (struct value *object, int is_array)
> +{
> +  const char *destr_name;
> +  struct type *type;
> +  int i;
> +  struct symbol *sym;
> +  struct value *function;
> +
> +  type = check_typedef (value_type (object));
> +  gdb_assert (TYPE_CODE (type) == TYPE_CODE_PTR);
> +  type = check_typedef (TYPE_TARGET_TYPE (type));
> +
> +  while (TYPE_CODE (type) == TYPE_CODE_ARRAY)
> +    type = check_typedef (TYPE_TARGET_TYPE (type));
> +
> +  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
> +    return NULL;
> +
> +  /* Find the destructor name, if we can.  */
> +  destr_name = NULL;
> +  for (i = 0; destr_name == NULL && i < TYPE_NFN_FIELDS (type); ++i)
> +    {
> +      struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
> +      int j;
> +
> +      for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
> +	{
> +	  if (TYPE_FN_FIELDLIST_NAME (type, i)[0] == '~'
> +	      || is_destructor_name (TYPE_FN_FIELD_PHYSNAME (f, j)))
> +	    {
> +	      destr_name = TYPE_FN_FIELDLIST_NAME (type, i);
> +	      break;
> +	    }
> +	}
> +    }
> +
> +  /* No destructor is fine for a POD.  */
> +  if (destr_name == NULL)
> +    return NULL;
> +
> +  sym = lookup_symbol (destr_name, NULL, VAR_DOMAIN, NULL);
> +  if (sym == NULL)
> +    return NULL;
> +
> +  function = value_of_variable (sym, 0);
> +
> +  if (is_array)
> +    {
> +      struct value *new_vec;
> +      struct value *elt_count_v = cp_get_vec_elts (object, &new_vec);
> +      LONGEST iter, elt_count = value_as_long (elt_count_v);
> +      struct value *ptr = value_cast (lookup_pointer_type (type), object);
> +
> +      for (iter = 0; iter < elt_count; ++iter)
> +	{
> +	  struct value *one_elt = ptr;
> +
> +	  call_function_by_hand (function, 1, &one_elt);
> +	  ptr = value_ptradd (ptr, 1);
> +	}
> +
> +      return new_vec;
> +    }
> +
> +  call_function_by_hand (function, 1, &object);
> +  return NULL;
> +}
> +
>  

> 
>  /* Concatenate two values with the following conditions:
> diff --git a/gdb/value.h b/gdb/value.h
> index d8b157f..32f88ed 100644
> --- a/gdb/value.h
> +++ b/gdb/value.h
> @@ -833,6 +833,16 @@ extern struct value *value_x_binop (struct value *arg1, struct value *arg2,
>  extern struct value *value_x_unop (struct value *arg1, enum exp_opcode op,
>  				   enum noside noside);
> 
> +extern struct value *value_operator_new (int global_new, struct type *type,
> +					 int argc, struct value **argv);
> +
> +extern void value_construct (struct type *type, int argc, struct value **argv);
> +
> +extern void value_operator_delete (int global_del, int is_array,
> +				   struct value *object);
> +
> +extern struct value *value_destruct (struct value *object, int is_array);
> +
>  extern struct value *value_fn_field (struct value **arg1p, struct fn_field *f,
>  				     int j, struct type *type, int offset);
> 
> --
> 1.7.7.6

Attachment: smime.p7s
Description: S/MIME cryptographic signature

--------------------------------------------------------------------------------------
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland 
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Douglas Lusk, Peter Gleissner, Hannes Schwaderer
Registergericht: Muenchen HRB 47456 
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

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