aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-07-13 04:31:42 +0000
committerDaniel Jacobowitz <drow@false.org>2006-07-13 04:31:42 +0000
commitfb933624929d0716f25db8d1096557e7f5e72440 (patch)
treee216dad7d0d61e68304e7ab329fe58c5c850799b /gdb/valops.c
parentd49c44d5f19771810279034d93060d13c13f0937 (diff)
downloadgdb-fb933624929d0716f25db8d1096557e7f5e72440.zip
gdb-fb933624929d0716f25db8d1096557e7f5e72440.tar.gz
gdb-fb933624929d0716f25db8d1096557e7f5e72440.tar.bz2
gdb/
* infcall.c (value_arg_coerce): Use value_cast_pointers for references. Avoid value_cast to a reference type. Don't silently convert pointers to references. * valops.c (value_cast_pointers): New, based on value_cast. (value_cast): Use it. Reject reference types. (value_ref): New. (typecmp): Use it. * value.h (value_cast_pointers, value_ref): New prototypes. gdb/testsuite/ * gdb.cp/ref-params.exp: New test. * gdb.cp/ref-params.cc: New source file. * gdb.cp/Makefile.in (EXECUTABLES): Add ref-params.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c130
1 files changed, 86 insertions, 44 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index e86b532..7d1b7d8 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -201,6 +201,70 @@ allocate_space_in_inferior (int len)
return value_as_long (value_allocate_space_in_inferior (len));
}
+/* Cast one pointer or reference type to another. Both TYPE and
+ the type of ARG2 should be pointer types, or else both should be
+ reference types. Returns the new pointer or reference. */
+
+struct value *
+value_cast_pointers (struct type *type, struct value *arg2)
+{
+ struct type *type2 = check_typedef (value_type (arg2));
+ struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
+ struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
+
+ if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
+ && TYPE_CODE (t2) == TYPE_CODE_STRUCT
+ && !value_logical_not (arg2))
+ {
+ struct value *v;
+
+ /* Look in the type of the source to see if it contains the
+ type of the target as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type. */
+ if (TYPE_NAME (t1) != NULL)
+ {
+ struct value *v2;
+
+ if (TYPE_CODE (type2) == TYPE_CODE_REF)
+ v2 = coerce_ref (arg2);
+ else
+ v2 = value_ind (arg2);
+ v = search_struct_field (type_name_no_tag (t1),
+ v2, 0, t2, 1);
+ if (v)
+ {
+ v = value_addr (v);
+ deprecated_set_value_type (v, type);
+ return v;
+ }
+ }
+
+ /* Look in the type of the target to see if it contains the
+ type of the source as a superclass. If so, we'll need to
+ offset the pointer rather than just change its type.
+ FIXME: This fails silently with virtual inheritance. */
+ if (TYPE_NAME (t2) != NULL)
+ {
+ v = search_struct_field (type_name_no_tag (t2),
+ value_zero (t1, not_lval), 0, t1, 1);
+ if (v)
+ {
+ CORE_ADDR addr2 = value_as_address (arg2);
+ addr2 -= (VALUE_ADDRESS (v)
+ + value_offset (v)
+ + value_embedded_offset (v));
+ return value_from_pointer (type, addr2);
+ }
+ }
+ }
+
+ /* No superclass found, just change the pointer type. */
+ deprecated_set_value_type (arg2, type);
+ arg2 = value_change_enclosing_type (arg2, type);
+ set_value_pointed_to_offset (arg2, 0); /* pai: chk_val */
+ return arg2;
+}
+
/* Cast value ARG2 to type TYPE and return as a value.
More general than a C cast: accepts any two types of the same length,
and if ARG2 is an lvalue it can be cast into anything at all. */
@@ -224,6 +288,10 @@ value_cast (struct type *type, struct value *arg2)
arg2 = coerce_ref (arg2);
type2 = check_typedef (value_type (arg2));
+ /* You can't cast to a reference type. See value_cast_pointers
+ instead. */
+ gdb_assert (code1 != TYPE_CODE_REF);
+
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
is treated like a cast to (TYPE [N])OBJECT,
where N is sizeof(OBJECT)/sizeof(TYPE). */
@@ -369,50 +437,8 @@ value_cast (struct type *type, struct value *arg2)
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
- {
- struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
- struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
- if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
- && TYPE_CODE (t2) == TYPE_CODE_STRUCT
- && !value_logical_not (arg2))
- {
- struct value *v;
-
- /* Look in the type of the source to see if it contains the
- type of the target as a superclass. If so, we'll need to
- offset the pointer rather than just change its type. */
- if (TYPE_NAME (t1) != NULL)
- {
- v = search_struct_field (type_name_no_tag (t1),
- value_ind (arg2), 0, t2, 1);
- if (v)
- {
- v = value_addr (v);
- deprecated_set_value_type (v, type);
- return v;
- }
- }
+ return value_cast_pointers (type, arg2);
- /* Look in the type of the target to see if it contains the
- type of the source as a superclass. If so, we'll need to
- offset the pointer rather than just change its type.
- FIXME: This fails silently with virtual inheritance. */
- if (TYPE_NAME (t2) != NULL)
- {
- v = search_struct_field (type_name_no_tag (t2),
- value_zero (t1, not_lval), 0, t1, 1);
- if (v)
- {
- CORE_ADDR addr2 = value_as_address (arg2);
- addr2 -= (VALUE_ADDRESS (v)
- + value_offset (v)
- + value_embedded_offset (v));
- return value_from_pointer (type, addr2);
- }
- }
- }
- /* No superclass found, just fall through to change ptr type. */
- }
deprecated_set_value_type (arg2, type);
arg2 = value_change_enclosing_type (arg2, type);
set_value_pointed_to_offset (arg2, 0); /* pai: chk_val */
@@ -886,6 +912,22 @@ value_addr (struct value *arg1)
return arg2;
}
+/* Return a reference value for the object for which ARG1 is the contents. */
+
+struct value *
+value_ref (struct value *arg1)
+{
+ struct value *arg2;
+
+ struct type *type = check_typedef (value_type (arg1));
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ return arg1;
+
+ arg2 = value_addr (arg1);
+ deprecated_set_value_type (arg2, lookup_reference_type (type));
+ return arg2;
+}
+
/* Given a value of a pointer type, apply the C unary * operator to it. */
struct value *
@@ -1106,7 +1148,7 @@ typecmp (int staticp, int varargs, int nargs,
if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
t2[i] = value_coerce_array (t2[i]);
else
- t2[i] = value_addr (t2[i]);
+ t2[i] = value_ref (t2[i]);
continue;
}