*max = ((ULONGEST) 1 << (n - 1)) - 1;
}
+/* Return the largest value representable by pointer type TYPE. */
+
+CORE_ADDR
+get_pointer_type_max (struct type *type)
+{
+ unsigned int n;
+
+ type = check_typedef (type);
+ gdb_assert (type->code () == TYPE_CODE_PTR);
+ gdb_assert (TYPE_LENGTH (type) <= sizeof (CORE_ADDR));
+
+ n = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
+ return ((((CORE_ADDR) 1 << (n - 1)) - 1) << 1) | 1;
+}
+
/* Internal routine called by TYPE_VPTR_FIELDNO to return the value of
cplus_stuff.vptr_fieldno.
extern void get_signed_type_minmax (struct type *, LONGEST *, LONGEST *);
+extern CORE_ADDR get_pointer_type_max (struct type *);
+
/* * Resolve all dynamic values of a type e.g. array bounds to static values.
ADDR specifies the location of the variable the type is bound to.
If TYPE has no dynamic properties return TYPE; otherwise a new type with
int type_arg_pos, SCM type_scm, struct type *type,
struct gdbarch *gdbarch, SCM *except_scmp)
{
- if (is_integral_type (type)
- || type->code () == TYPE_CODE_PTR)
+ if (is_integral_type (type))
{
if (type->is_unsigned ())
{
return value_from_longest (type, gdbscm_scm_to_longest (obj));
}
}
+ else if (type->code () == TYPE_CODE_PTR)
+ {
+ CORE_ADDR max = get_pointer_type_max (type);
+ if (!scm_is_unsigned_integer (obj, 0, max))
+ {
+ *except_scmp
+ = gdbscm_make_out_of_range_error (func_name,
+ obj_arg_pos, obj,
+ _("value out of range for type"));
+ return NULL;
+ }
+ return value_from_pointer (type, gdbscm_scm_to_ulongest (obj));
+ }
else if (type->code () == TYPE_CODE_FLT)
return value_from_host_double (type, scm_to_double (obj));
else
gdb_test "gu (print (value-sub b a))" \
"= 3" "subtract two pointer values"
+ # Test pointer creation.
+
+ gdb_test_no_output "gu (define void-pointer-type (type-pointer (arch-void-type (current-arch))))"
+ gdb_scm_test_silent_cmd "gu (define null-pointer (make-value 0 #:type void-pointer-type))" \
+ "test make-value with pointer type"
+ gdb_test "gu (print null-pointer)" "= 0x0"
+ gdb_test "gu (print (equal? (value-type null-pointer) void-pointer-type))" \
+ "= #t"
+
# Test some invalid operations.
gdb_test_multiple "gu (print (value-add i '()))" "catch error in guile type conversion" {
}
}
+# Helper routine for test_pointer_numeric_range.
+
+proc test_make_pointer_value { size } {
+ set max [get_max_uint $size]
+ set max_hex [string repeat "f" [expr "$size / 4"]]
+
+ gdb_test "gu (print (make-value $max #:type void-pointer-type))" \
+ "= 0x$max_hex" "test make-value void* max"
+ gdb_test "gu (print (make-value 0 #:type void-pointer-type))" \
+ "= 0x0" "test make-value void* 0"
+
+ gdb_test "gu (print (make-value (+ $max 1) #:type void-pointer-type))" \
+ "ERROR.*Out of range.*" "test make-value void* max+1"
+ gdb_test "gu (print (make-value -1 #:type void-pointer-type))" \
+ "ERROR.*Out of range.*" "test make-value void* -1"
+}
+
+proc test_pointer_numeric_range {} {
+ # We can't assume anything about sizeof (void*) on the target.
+ # Keep it simple for now, this will cover everything important for
+ # the major targets.
+ set pointer_size [get_sizeof "void*" 0]
+ if { $pointer_size == 4 } {
+ test_make_pointer_value 32
+ }
+ if { $pointer_size == 8 } {
+ test_make_pointer_value 64
+ }
+}
+
proc test_value_boolean {} {
# Note: Boolean values print as 0,1 because they are printed in the
# current language (in this case C).
test_value_numeric_ops
test_value_numeric_ranges
+test_pointer_numeric_range
test_value_boolean
test_value_compare