Revert the entire VLA series.
This reverts the following patch series, as they cause some regresssions. commit37c1ab67a3
type: add c99 variable length array support gdb/ * dwarf2loc.c (dwarf2_locexpr_baton_eval): New function. (dwarf2_evaluate_property): New function. * dwarf2loc.h (dwarf2_evaluate_property): New function prototype. * dwarf2read.c (attr_to_dynamic_prop): New function. (read_subrange_type): Use attr_to_dynamic_prop to read high bound attribute. * gdbtypes.c: Include dwarf2loc.h. (is_dynamic_type): New function. (resolve_dynamic_type): New function. (resolve_dynamic_bounds): New function. (get_type_length): New function. (check_typedef): Use get_type_length to compute type length. * gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro. (TYPE_LOW_BOUND_KIND): New macro. (is_dynamic_type): New function prototype. * value.c (value_from_contents_and_address): Call resolve_dynamic_type to resolve dynamic properties of the type. Update comment. * valops.c (get_value_at, value_at, value_at_lazy): Update comment. commit26cb189f8b
vla: enable sizeof operator to work with variable length arrays gdb/ * eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type passed to sizeof is dynamic evaluate the argument to compute the length. commit04b19544ef
vla: enable sizeof operator for indirection gdb/ * eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect value and retrieve the dynamic type size. commitbcd629a44f
vla: update type from newly created value gdb/ * ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value. (ada_template_to_fixed_record_type_1): Likewise. (ada_to_fixed_type_1): Likewise. * cp-valprint.c (cp_print_value_fields_rtti): Likewise. (cp_print_value): Likewise. * d-valprint.c (dynamic_array_type): Likewise. * eval.c (evaluate_subexp_with_coercion): Likewise. * findvar.c (address_of_variable): Likewise. * jv-valprint.c (java_value_print): Likewise. * valops.c (value_ind): Likewise. * value.c (coerce_ref): Likewise. commitb86138fb04
vla: print "variable length" for unresolved dynamic bounds gdb/ * c-typeprint.c (c_type_print_varspec_suffix): Added check for not yet resolved high bound. If unresolved, print "variable length" string to the console instead of random length. commite1969afbd4
vla: support for DW_AT_count gdb/ * dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic property and store it as the high bound and flag the range accordingly. * gdbtypes.c (resolve_dynamic_bounds): If range is flagged as RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound. * gdbtypes.h (enum range_flags): New enum. (struct range_bounds): Add flags member. commit92b09522dc
vla: resolve dynamic bounds if value contents is a constant byte-sequence gdb/ * findvar.c (default_read_var_value): Resolve dynamic bounds if location points to a constant blob. commit3bce82377f
vla: evaluate operand of sizeof if its type is a vla gdb/ * eval.c (evaluate_subexp_for_sizeof): Add enum noside argument. (evaluate_subexp_standard): Pass noside argument. (evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case if noside equals EVAL_NORMAL. If the subscript yields a vla type re-evaluate subscript operation with EVAL_NORMAL to enable sideffects. * gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated. * gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case. gdb/testsuite * gdb.base/vla-sideeffect.c: New file. * gdb.base/vla-sideeffect.exp: New file. commit504f34326e
test: cover subranges with present DW_AT_count attribute gdb/testsuite/ * gdb.dwarf2/count.exp: New file. commit1a237e0ee5
test: multi-dimensional c99 vla. gdb/testsuite/ * gdb.base/vla-multi.c: New file. * gdb.base/vla-multi.exp: New file. commit024e13b46f
test: evaluate pointers to C99 vla correctly. gdb/testsuite/ * gdb.base/vla-ptr.c: New file. * gdb.base/vla-ptr.exp: New file. commitc8655f75e2
test: basic c99 vla tests for C primitives gdb/testsuite/ * gdb.base/vla-datatypes.c: New file. * gdb.base/vla-datatypes.exp: New file. commit58a84dcf29
test: add mi vla test gdb/testsuite/ * gdb.mi/mi-vla-c99.exp: New file. * gdb.mi/vla.c: New file.
This commit is contained in:
parent
245a5f0b74
commit
6b662e19e4
27 changed files with 193 additions and 1316 deletions
|
@ -1,3 +1,67 @@
|
|||
2014-04-11 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
Revert the following changes due to regressions:
|
||||
|
||||
* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
|
||||
(dwarf2_evaluate_property): New function.
|
||||
* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
|
||||
* dwarf2read.c (attr_to_dynamic_prop): New function.
|
||||
(read_subrange_type): Use attr_to_dynamic_prop to read high bound
|
||||
attribute.
|
||||
* gdbtypes.c: Include dwarf2loc.h.
|
||||
(is_dynamic_type): New function.
|
||||
(resolve_dynamic_type): New function.
|
||||
(resolve_dynamic_bounds): New function.
|
||||
(get_type_length): New function.
|
||||
(check_typedef): Use get_type_length to compute type length.
|
||||
* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
|
||||
(TYPE_LOW_BOUND_KIND): New macro.
|
||||
(is_dynamic_type): New function prototype.
|
||||
* value.c (value_from_contents_and_address): Call resolve_dynamic_type
|
||||
to resolve dynamic properties of the type. Update comment.
|
||||
* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
|
||||
|
||||
* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
|
||||
passed to sizeof is dynamic evaluate the argument to compute the length.
|
||||
|
||||
* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
|
||||
value and retrieve the dynamic type size.
|
||||
|
||||
* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
|
||||
(ada_template_to_fixed_record_type_1): Likewise.
|
||||
(ada_to_fixed_type_1): Likewise.
|
||||
* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
|
||||
(cp_print_value): Likewise.
|
||||
* d-valprint.c (dynamic_array_type): Likewise.
|
||||
* eval.c (evaluate_subexp_with_coercion): Likewise.
|
||||
* findvar.c (address_of_variable): Likewise.
|
||||
* jv-valprint.c (java_value_print): Likewise.
|
||||
* valops.c (value_ind): Likewise.
|
||||
* value.c (coerce_ref): Likewise.
|
||||
|
||||
* c-typeprint.c (c_type_print_varspec_suffix): Added
|
||||
check for not yet resolved high bound. If unresolved, print
|
||||
"variable length" string to the console instead of random
|
||||
length.
|
||||
|
||||
* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
|
||||
property and store it as the high bound and flag the range accordingly.
|
||||
* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
|
||||
RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
|
||||
* gdbtypes.h (enum range_flags): New enum.
|
||||
(struct range_bounds): Add flags member.
|
||||
|
||||
* findvar.c (default_read_var_value): Resolve dynamic bounds if location
|
||||
points to a constant blob.
|
||||
|
||||
* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
|
||||
(evaluate_subexp_standard): Pass noside argument.
|
||||
(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
|
||||
if noside equals EVAL_NORMAL. If the subscript yields a vla type
|
||||
re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
|
||||
* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
|
||||
* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.
|
||||
|
||||
2014-04-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
PR c++/16675
|
||||
|
|
|
@ -2406,7 +2406,6 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
|
|||
else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
|
||||
{
|
||||
v = value_at (type, value_address (obj));
|
||||
type = value_type (v);
|
||||
bytes = (unsigned char *) alloca (len);
|
||||
read_memory (value_address (v) + offset, bytes, len);
|
||||
}
|
||||
|
@ -7889,7 +7888,6 @@ ada_template_to_fixed_record_type_1 (struct type *type,
|
|||
size first before creating the value. */
|
||||
check_size (rtype);
|
||||
dval = value_from_contents_and_address (rtype, valaddr, address);
|
||||
rtype = value_type (dval);
|
||||
}
|
||||
else
|
||||
dval = dval0;
|
||||
|
@ -7992,10 +7990,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
|
|||
off = TYPE_FIELD_BITPOS (rtype, variant_field);
|
||||
|
||||
if (dval0 == NULL)
|
||||
{
|
||||
dval = value_from_contents_and_address (rtype, valaddr, address);
|
||||
rtype = value_type (dval);
|
||||
}
|
||||
dval = value_from_contents_and_address (rtype, valaddr, address);
|
||||
else
|
||||
dval = dval0;
|
||||
|
||||
|
@ -8136,10 +8131,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
|
|||
return type;
|
||||
|
||||
if (dval0 == NULL)
|
||||
{
|
||||
dval = value_from_contents_and_address (type, valaddr, address);
|
||||
type = value_type (dval);
|
||||
}
|
||||
dval = value_from_contents_and_address (type, valaddr, address);
|
||||
else
|
||||
dval = dval0;
|
||||
|
||||
|
@ -8437,7 +8429,6 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
|
|||
value_from_contents_and_address (fixed_record_type,
|
||||
valaddr,
|
||||
address);
|
||||
fixed_record_type = value_type (obj);
|
||||
if (real_type != NULL)
|
||||
return to_fixed_record_type
|
||||
(real_type, NULL,
|
||||
|
|
|
@ -689,11 +689,7 @@ c_type_print_varspec_suffix (struct type *type,
|
|||
|
||||
fprintf_filtered (stream, (is_vector ?
|
||||
" __attribute__ ((vector_size(" : "["));
|
||||
/* Bounds are not yet resolved, print a bounds placeholder instead. */
|
||||
if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
|
||||
|| TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
|
||||
fprintf_filtered (stream, "variable length");
|
||||
else if (get_array_bounds (type, &low_bound, &high_bound))
|
||||
if (get_array_bounds (type, &low_bound, &high_bound))
|
||||
fprintf_filtered (stream, "%s",
|
||||
plongest (high_bound - low_bound + 1));
|
||||
fprintf_filtered (stream, (is_vector ? ")))" : "]"));
|
||||
|
|
|
@ -443,7 +443,6 @@ cp_print_value_fields_rtti (struct type *type,
|
|||
/* Ugh, we have to convert back to a value here. */
|
||||
value = value_from_contents_and_address (type, valaddr + offset,
|
||||
address + offset);
|
||||
type = value_type (value);
|
||||
/* We don't actually care about most of the result here -- just
|
||||
the type. We already have the correct offset, due to how
|
||||
val_print was initially called. */
|
||||
|
@ -546,7 +545,6 @@ cp_print_value (struct type *type, struct type *real_type,
|
|||
base_val = value_from_contents_and_address (baseclass,
|
||||
buf,
|
||||
address + boffset);
|
||||
baseclass = value_type (base_val);
|
||||
thisoffset = 0;
|
||||
boffset = 0;
|
||||
thistype = baseclass;
|
||||
|
|
|
@ -59,7 +59,6 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
|
|||
|
||||
true_type = lookup_array_range_type (true_type, 0, length - 1);
|
||||
ival = value_at (true_type, addr);
|
||||
true_type = value_type (ival);
|
||||
|
||||
d_val_print (true_type,
|
||||
value_contents_for_printing (ival),
|
||||
|
|
119
gdb/dwarf2loc.c
119
gdb/dwarf2loc.c
|
@ -2432,125 +2432,6 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
|
|||
return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
|
||||
}
|
||||
|
||||
/* Evaluates a dwarf expression and stores the result in VAL, expecting
|
||||
that the dwarf expression only produces a single CORE_ADDR. ADDR is a
|
||||
context (location of a variable) and might be needed to evaluate the
|
||||
location expression.
|
||||
Returns 1 on success, 0 otherwise. */
|
||||
|
||||
static int
|
||||
dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
|
||||
CORE_ADDR addr, CORE_ADDR *valp)
|
||||
{
|
||||
struct dwarf_expr_context *ctx;
|
||||
struct dwarf_expr_baton baton;
|
||||
struct objfile *objfile;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
if (dlbaton == NULL || dlbaton->size == 0)
|
||||
return 0;
|
||||
|
||||
ctx = new_dwarf_expr_context ();
|
||||
cleanup = make_cleanup_free_dwarf_expr_context (ctx);
|
||||
|
||||
baton.frame = get_selected_frame (NULL);
|
||||
baton.per_cu = dlbaton->per_cu;
|
||||
|
||||
objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
|
||||
|
||||
ctx->gdbarch = get_objfile_arch (objfile);
|
||||
ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
|
||||
ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
|
||||
ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
|
||||
ctx->funcs = &dwarf_expr_ctx_funcs;
|
||||
ctx->baton = &baton;
|
||||
|
||||
dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
|
||||
|
||||
switch (ctx->location)
|
||||
{
|
||||
case DWARF_VALUE_REGISTER:
|
||||
case DWARF_VALUE_MEMORY:
|
||||
case DWARF_VALUE_STACK:
|
||||
*valp = dwarf_expr_fetch_address (ctx, 0);
|
||||
if (ctx->location == DWARF_VALUE_REGISTER)
|
||||
*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
|
||||
do_cleanups (cleanup);
|
||||
return 1;
|
||||
case DWARF_VALUE_LITERAL:
|
||||
*valp = extract_signed_integer (ctx->data, ctx->len,
|
||||
gdbarch_byte_order (ctx->gdbarch));
|
||||
do_cleanups (cleanup);
|
||||
return 1;
|
||||
/* Unsupported dwarf values. */
|
||||
case DWARF_VALUE_OPTIMIZED_OUT:
|
||||
case DWARF_VALUE_IMPLICIT_POINTER:
|
||||
break;
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See dwarf2loc.h. */
|
||||
|
||||
int
|
||||
dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
|
||||
CORE_ADDR *value)
|
||||
{
|
||||
if (prop == NULL)
|
||||
return 0;
|
||||
|
||||
switch (prop->kind)
|
||||
{
|
||||
case PROP_LOCEXPR:
|
||||
{
|
||||
const struct dwarf2_property_baton *baton = prop->data.baton;
|
||||
|
||||
if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
|
||||
{
|
||||
if (baton->referenced_type)
|
||||
{
|
||||
struct value *val = value_at (baton->referenced_type, *value);
|
||||
|
||||
*value = value_as_address (val);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_LOCLIST:
|
||||
{
|
||||
struct dwarf2_property_baton *baton = prop->data.baton;
|
||||
struct frame_info *frame = get_selected_frame (NULL);
|
||||
CORE_ADDR pc = get_frame_address_in_block (frame);
|
||||
const gdb_byte *data;
|
||||
struct value *val;
|
||||
size_t size;
|
||||
|
||||
data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
|
||||
if (data != NULL)
|
||||
{
|
||||
val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
|
||||
size, baton->loclist.per_cu);
|
||||
if (!value_optimized_out (val))
|
||||
{
|
||||
*value = value_as_address (val);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_CONST:
|
||||
*value = prop->data.const_val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
|
||||
|
||||
|
|
|
@ -90,14 +90,6 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
|
|||
size_t size,
|
||||
struct dwarf2_per_cu_data *per_cu);
|
||||
|
||||
/* Converts a dynamic property into a static one. ADDR is the address of
|
||||
the object currently being evaluated and might be nedded.
|
||||
Returns 1 if PROP could be converted and the static value is passed back
|
||||
into VALUE, otherwise returns 0. */
|
||||
|
||||
int dwarf2_evaluate_property (const struct dynamic_prop *prop,
|
||||
CORE_ADDR addr, CORE_ADDR *value);
|
||||
|
||||
CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
|
||||
unsigned int addr_index);
|
||||
|
||||
|
@ -143,26 +135,6 @@ struct dwarf2_loclist_baton
|
|||
unsigned char from_dwo;
|
||||
};
|
||||
|
||||
/* A dynamic property is either expressed as a single location expression
|
||||
or a location list. If the property is an indirection, pointing to
|
||||
another die, keep track of the targeted type in REFERENCED_TYPE. */
|
||||
|
||||
struct dwarf2_property_baton
|
||||
{
|
||||
/* If the property is an indirection, we need to evaluate the location
|
||||
LOCEXPR or LOCLIST in the context of the type REFERENCED_TYPE.
|
||||
If NULL, the location is the actual value of the property. */
|
||||
struct type *referenced_type;
|
||||
union
|
||||
{
|
||||
/* Location expression. */
|
||||
struct dwarf2_locexpr_baton locexpr;
|
||||
|
||||
/* Location list to be evaluated in the context of REFERENCED_TYPE. */
|
||||
struct dwarf2_loclist_baton loclist;
|
||||
};
|
||||
};
|
||||
|
||||
extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
|
||||
extern const struct symbol_computed_ops dwarf2_loclist_funcs;
|
||||
|
||||
|
|
122
gdb/dwarf2read.c
122
gdb/dwarf2read.c
|
@ -14405,84 +14405,6 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
return set_die_type (die, type, cu);
|
||||
}
|
||||
|
||||
/* Parse dwarf attribute if it's a block, reference or constant and put the
|
||||
resulting value of the attribute into struct bound_prop.
|
||||
Returns 1 if ATTR could be resolved into PROP, 0 otherwise. */
|
||||
|
||||
static int
|
||||
attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
|
||||
struct dwarf2_cu *cu, struct dynamic_prop *prop)
|
||||
{
|
||||
struct dwarf2_property_baton *baton;
|
||||
struct obstack *obstack = &cu->objfile->objfile_obstack;
|
||||
|
||||
if (attr == NULL || prop == NULL)
|
||||
return 0;
|
||||
|
||||
if (attr_form_is_block (attr))
|
||||
{
|
||||
baton = obstack_alloc (obstack, sizeof (*baton));
|
||||
baton->referenced_type = NULL;
|
||||
baton->locexpr.per_cu = cu->per_cu;
|
||||
baton->locexpr.size = DW_BLOCK (attr)->size;
|
||||
baton->locexpr.data = DW_BLOCK (attr)->data;
|
||||
prop->data.baton = baton;
|
||||
prop->kind = PROP_LOCEXPR;
|
||||
gdb_assert (prop->data.baton != NULL);
|
||||
}
|
||||
else if (attr_form_is_ref (attr))
|
||||
{
|
||||
struct dwarf2_cu *target_cu = cu;
|
||||
struct die_info *target_die;
|
||||
struct attribute *target_attr;
|
||||
|
||||
target_die = follow_die_ref (die, attr, &target_cu);
|
||||
target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
|
||||
if (target_attr == NULL)
|
||||
return 0;
|
||||
|
||||
if (attr_form_is_section_offset (target_attr))
|
||||
{
|
||||
baton = obstack_alloc (obstack, sizeof (*baton));
|
||||
baton->referenced_type = die_type (target_die, target_cu);
|
||||
fill_in_loclist_baton (cu, &baton->loclist, target_attr);
|
||||
prop->data.baton = baton;
|
||||
prop->kind = PROP_LOCLIST;
|
||||
gdb_assert (prop->data.baton != NULL);
|
||||
}
|
||||
else if (attr_form_is_block (target_attr))
|
||||
{
|
||||
baton = obstack_alloc (obstack, sizeof (*baton));
|
||||
baton->referenced_type = die_type (target_die, target_cu);
|
||||
baton->locexpr.per_cu = cu->per_cu;
|
||||
baton->locexpr.size = DW_BLOCK (target_attr)->size;
|
||||
baton->locexpr.data = DW_BLOCK (target_attr)->data;
|
||||
prop->data.baton = baton;
|
||||
prop->kind = PROP_LOCEXPR;
|
||||
gdb_assert (prop->data.baton != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
|
||||
"dynamic property");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (attr_form_is_constant (attr))
|
||||
{
|
||||
prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
|
||||
prop->kind = PROP_CONST;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
|
||||
dwarf2_name (die, cu));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read the given DW_AT_subrange DIE. */
|
||||
|
||||
static struct type *
|
||||
|
@ -14493,7 +14415,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
struct attribute *attr;
|
||||
struct dynamic_prop low, high;
|
||||
int low_default_is_valid;
|
||||
int high_bound_is_count = 0;
|
||||
const char *name;
|
||||
LONGEST negative_mask;
|
||||
|
||||
|
@ -14557,16 +14478,38 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
die->offset.sect_off, objfile_name (cu->objfile));
|
||||
|
||||
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
|
||||
if (!attr_to_dynamic_prop (attr, die, cu, &high))
|
||||
if (attr)
|
||||
{
|
||||
if (attr_form_is_block (attr) || attr_form_is_ref (attr))
|
||||
{
|
||||
/* GCC encodes arrays with unspecified or dynamic length
|
||||
with a DW_FORM_block1 attribute or a reference attribute.
|
||||
FIXME: GDB does not yet know how to handle dynamic
|
||||
arrays properly, treat them as arrays with unspecified
|
||||
length for now.
|
||||
|
||||
FIXME: jimb/2003-09-22: GDB does not really know
|
||||
how to handle arrays of unspecified length
|
||||
either; we just represent them as zero-length
|
||||
arrays. Choose an appropriate upper bound given
|
||||
the lower bound we've computed above. */
|
||||
high.data.const_val = low.data.const_val - 1;
|
||||
}
|
||||
else
|
||||
high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
attr = dwarf2_attr (die, DW_AT_count, cu);
|
||||
if (attr_to_dynamic_prop (attr, die, cu, &high))
|
||||
if (attr)
|
||||
{
|
||||
/* If bounds are constant do the final calculation here. */
|
||||
if (low.kind == PROP_CONST && high.kind == PROP_CONST)
|
||||
high.data.const_val = low.data.const_val + high.data.const_val - 1;
|
||||
else
|
||||
high_bound_is_count = 1;
|
||||
int count = dwarf2_get_attr_constant_value (attr, 1);
|
||||
high.data.const_val = low.data.const_val + count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unspecified array length. */
|
||||
high.data.const_val = low.data.const_val - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14626,8 +14569,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
|
|||
|
||||
range_type = create_range_type (NULL, orig_base_type, &low, &high);
|
||||
|
||||
if (high_bound_is_count)
|
||||
TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;
|
||||
/* Mark arrays with dynamic length at least as an array of unspecified
|
||||
length. GDB could check the boundary but before it gets implemented at
|
||||
least allow accessing the array elements. */
|
||||
if (attr && attr_form_is_block (attr))
|
||||
TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
|
||||
|
||||
/* Ada expects an empty array on no boundary attributes. */
|
||||
if (attr == NULL && cu->language != language_ada)
|
||||
|
|
59
gdb/eval.c
59
gdb/eval.c
|
@ -50,8 +50,7 @@ extern int overload_resolution;
|
|||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
|
||||
enum noside);
|
||||
static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
|
||||
|
||||
static struct value *evaluate_subexp_for_address (struct expression *,
|
||||
int *, enum noside);
|
||||
|
@ -2563,7 +2562,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
|||
evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
|
||||
goto nosideret;
|
||||
}
|
||||
return evaluate_subexp_for_sizeof (exp, pos, noside);
|
||||
return evaluate_subexp_for_sizeof (exp, pos);
|
||||
|
||||
case UNOP_CAST:
|
||||
(*pos) += 2;
|
||||
|
@ -2985,7 +2984,6 @@ evaluate_subexp_with_coercion (struct expression *exp,
|
|||
{
|
||||
(*pos) += 4;
|
||||
val = address_of_variable (var, exp->elts[pc + 1].block);
|
||||
type = value_type (val);
|
||||
return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
||||
val);
|
||||
}
|
||||
|
@ -2998,13 +2996,10 @@ evaluate_subexp_with_coercion (struct expression *exp,
|
|||
|
||||
/* Evaluate a subexpression of EXP, at index *POS,
|
||||
and return a value for the size of that subexpression.
|
||||
Advance *POS over the subexpression. If NOSIDE is EVAL_NORMAL
|
||||
we allow side-effects on the operand if its type is a variable
|
||||
length array. */
|
||||
Advance *POS over the subexpression. */
|
||||
|
||||
static struct value *
|
||||
evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
|
||||
enum noside noside)
|
||||
evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
|
||||
{
|
||||
/* FIXME: This should be size_t. */
|
||||
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
|
||||
|
@ -3030,10 +3025,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
|
|||
&& TYPE_CODE (type) != TYPE_CODE_REF
|
||||
&& TYPE_CODE (type) != TYPE_CODE_ARRAY)
|
||||
error (_("Attempt to take contents of a non-pointer value."));
|
||||
if (is_dynamic_type (type))
|
||||
type = value_type (value_ind (val));
|
||||
else
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
break;
|
||||
|
||||
case UNOP_MEMVAL:
|
||||
|
@ -3048,47 +3040,10 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
|
|||
break;
|
||||
|
||||
case OP_VAR_VALUE:
|
||||
type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
|
||||
if (is_dynamic_type (type))
|
||||
{
|
||||
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
|
||||
type = value_type (val);
|
||||
}
|
||||
else
|
||||
(*pos) += 4;
|
||||
(*pos) += 4;
|
||||
type = SYMBOL_TYPE (exp->elts[pc + 2].symbol);
|
||||
break;
|
||||
|
||||
/* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting
|
||||
type of the subscript is a variable length array type. In this case we
|
||||
must re-evaluate the right hand side of the subcription to allow
|
||||
side-effects. */
|
||||
case BINOP_SUBSCRIPT:
|
||||
if (noside == EVAL_NORMAL)
|
||||
{
|
||||
int pc = (*pos) + 1;
|
||||
|
||||
val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
|
||||
type = check_typedef (value_type (val));
|
||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
type = TYPE_INDEX_TYPE (type);
|
||||
/* Only re-evaluate the right hand side if the resulting type
|
||||
is a variable length type. */
|
||||
if (TYPE_RANGE_DATA (type)->flag_bound_evaluated)
|
||||
{
|
||||
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
|
||||
type = value_type (val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
default:
|
||||
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
||||
type = value_type (val);
|
||||
|
|
|
@ -437,12 +437,7 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
|
|||
switch (SYMBOL_CLASS (var))
|
||||
{
|
||||
case LOC_CONST:
|
||||
if (is_dynamic_type (type))
|
||||
{
|
||||
/* Value is a constant byte-sequence and needs no memory access. */
|
||||
type = resolve_dynamic_type (type, /* Unused address. */ 0);
|
||||
}
|
||||
/* Put the constant back in target format. */
|
||||
/* Put the constant back in target format. */
|
||||
v = allocate_value (type);
|
||||
store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
|
||||
gdbarch_byte_order (get_type_arch (type)),
|
||||
|
@ -469,11 +464,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
|
|||
return v;
|
||||
|
||||
case LOC_CONST_BYTES:
|
||||
if (is_dynamic_type (type))
|
||||
{
|
||||
/* Value is a constant byte-sequence and needs no memory access. */
|
||||
type = resolve_dynamic_type (type, /* Unused address. */ 0);
|
||||
}
|
||||
v = allocate_value (type);
|
||||
memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
|
||||
TYPE_LENGTH (type));
|
||||
|
|
214
gdb/gdbtypes.c
214
gdb/gdbtypes.c
|
@ -853,17 +853,6 @@ create_static_range_type (struct type *result_type, struct type *index_type,
|
|||
return result_type;
|
||||
}
|
||||
|
||||
/* Predicate tests whether BOUNDS are static. Returns 1 if all bounds values
|
||||
are static, otherwise returns 0. */
|
||||
|
||||
static int
|
||||
has_static_range (const struct range_bounds *bounds)
|
||||
{
|
||||
return (bounds->low.kind == PROP_CONST
|
||||
&& bounds->high.kind == PROP_CONST);
|
||||
}
|
||||
|
||||
|
||||
/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
|
||||
TYPE. Return 1 if type is a range type, 0 if it is discrete (and
|
||||
bounds will fit in LONGEST), or -1 otherwise. */
|
||||
|
@ -997,41 +986,27 @@ create_array_type_with_stride (struct type *result_type,
|
|||
struct type *range_type,
|
||||
unsigned int bit_stride)
|
||||
{
|
||||
LONGEST low_bound, high_bound;
|
||||
|
||||
if (result_type == NULL)
|
||||
result_type = alloc_type_copy (range_type);
|
||||
|
||||
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
|
||||
TYPE_TARGET_TYPE (result_type) = element_type;
|
||||
if (has_static_range (TYPE_RANGE_DATA (range_type)))
|
||||
{
|
||||
LONGEST low_bound, high_bound;
|
||||
|
||||
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
|
||||
low_bound = high_bound = 0;
|
||||
CHECK_TYPEDEF (element_type);
|
||||
/* Be careful when setting the array length. Ada arrays can be
|
||||
empty arrays with the high_bound being smaller than the low_bound.
|
||||
In such cases, the array length should be zero. */
|
||||
if (high_bound < low_bound)
|
||||
TYPE_LENGTH (result_type) = 0;
|
||||
else if (bit_stride > 0)
|
||||
TYPE_LENGTH (result_type) =
|
||||
(bit_stride * (high_bound - low_bound + 1) + 7) / 8;
|
||||
else
|
||||
TYPE_LENGTH (result_type) =
|
||||
TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
|
||||
}
|
||||
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
|
||||
low_bound = high_bound = 0;
|
||||
CHECK_TYPEDEF (element_type);
|
||||
/* Be careful when setting the array length. Ada arrays can be
|
||||
empty arrays with the high_bound being smaller than the low_bound.
|
||||
In such cases, the array length should be zero. */
|
||||
if (high_bound < low_bound)
|
||||
TYPE_LENGTH (result_type) = 0;
|
||||
else if (bit_stride > 0)
|
||||
TYPE_LENGTH (result_type) =
|
||||
(bit_stride * (high_bound - low_bound + 1) + 7) / 8;
|
||||
else
|
||||
{
|
||||
/* This type is dynamic and its length needs to be computed
|
||||
on demand. In the meantime, avoid leaving the TYPE_LENGTH
|
||||
undefined by setting it to zero. Although we are not expected
|
||||
to trust TYPE_LENGTH in this case, setting the size to zero
|
||||
allows us to avoid allocating objects of random sizes in case
|
||||
we accidently do. */
|
||||
TYPE_LENGTH (result_type) = 0;
|
||||
}
|
||||
|
||||
TYPE_LENGTH (result_type) =
|
||||
TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
|
||||
TYPE_NFIELDS (result_type) = 1;
|
||||
TYPE_FIELDS (result_type) =
|
||||
(struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
|
||||
|
@ -1610,126 +1585,6 @@ stub_noname_complaint (void)
|
|||
complaint (&symfile_complaints, _("stub type has NULL name"));
|
||||
}
|
||||
|
||||
/* See gdbtypes.h. */
|
||||
|
||||
int
|
||||
is_dynamic_type (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
{
|
||||
const struct type *range_type;
|
||||
|
||||
gdb_assert (TYPE_NFIELDS (type) == 1);
|
||||
range_type = TYPE_INDEX_TYPE (type);
|
||||
if (!has_static_range (TYPE_RANGE_DATA (range_type)))
|
||||
return 1;
|
||||
else
|
||||
return is_dynamic_type (TYPE_TARGET_TYPE (type));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Resolves dynamic bound values of an array type TYPE to static ones.
|
||||
ADDRESS might be needed to resolve the subrange bounds, it is the location
|
||||
of the associated array. */
|
||||
|
||||
static struct type *
|
||||
resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
|
||||
{
|
||||
CORE_ADDR value;
|
||||
struct type *elt_type;
|
||||
struct type *range_type;
|
||||
struct type *ary_dim;
|
||||
const struct dynamic_prop *prop;
|
||||
const struct dwarf2_locexpr_baton *baton;
|
||||
struct dynamic_prop low_bound, high_bound;
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||
{
|
||||
struct type *copy = copy_type (type);
|
||||
|
||||
TYPE_TARGET_TYPE (copy)
|
||||
= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
|
||||
|
||||
elt_type = type;
|
||||
range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
|
||||
|
||||
prop = &TYPE_RANGE_DATA (range_type)->low;
|
||||
if (dwarf2_evaluate_property (prop, addr, &value))
|
||||
{
|
||||
low_bound.kind = PROP_CONST;
|
||||
low_bound.data.const_val = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
low_bound.kind = PROP_UNDEFINED;
|
||||
low_bound.data.const_val = 0;
|
||||
}
|
||||
|
||||
prop = &TYPE_RANGE_DATA (range_type)->high;
|
||||
if (dwarf2_evaluate_property (prop, addr, &value))
|
||||
{
|
||||
high_bound.kind = PROP_CONST;
|
||||
high_bound.data.const_val = value;
|
||||
|
||||
if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count)
|
||||
high_bound.data.const_val
|
||||
= low_bound.data.const_val + high_bound.data.const_val - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high_bound.kind = PROP_UNDEFINED;
|
||||
high_bound.data.const_val = 0;
|
||||
}
|
||||
|
||||
ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
|
||||
|
||||
if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
|
||||
elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
|
||||
else
|
||||
elt_type = TYPE_TARGET_TYPE (type);
|
||||
|
||||
range_type = create_range_type (NULL,
|
||||
TYPE_TARGET_TYPE (range_type),
|
||||
&low_bound, &high_bound);
|
||||
TYPE_RANGE_DATA (range_type)->flag_bound_evaluated = 1;
|
||||
return create_array_type (copy_type (type),
|
||||
elt_type,
|
||||
range_type);
|
||||
}
|
||||
|
||||
/* See gdbtypes.h */
|
||||
|
||||
struct type *
|
||||
resolve_dynamic_type (struct type *type, CORE_ADDR addr)
|
||||
{
|
||||
struct type *real_type = check_typedef (type);
|
||||
struct type *resolved_type;
|
||||
|
||||
if (!is_dynamic_type (real_type))
|
||||
return type;
|
||||
|
||||
resolved_type = resolve_dynamic_bounds (type, addr);
|
||||
|
||||
return resolved_type;
|
||||
}
|
||||
|
||||
/* Find the real type of TYPE. This function returns the real type,
|
||||
after removing all layers of typedefs, and completing opaque or stub
|
||||
types. Completion changes the TYPE argument, but stripping of
|
||||
|
@ -1905,6 +1760,45 @@ check_typedef (struct type *type)
|
|||
{
|
||||
/* Nothing we can do. */
|
||||
}
|
||||
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
&& TYPE_NFIELDS (type) == 1
|
||||
&& (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
|
||||
== TYPE_CODE_RANGE))
|
||||
{
|
||||
/* Now recompute the length of the array type, based on its
|
||||
number of elements and the target type's length.
|
||||
Watch out for Ada null Ada arrays where the high bound
|
||||
is smaller than the low bound. */
|
||||
const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
|
||||
const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
|
||||
ULONGEST len;
|
||||
|
||||
if (high_bound < low_bound)
|
||||
len = 0;
|
||||
else
|
||||
{
|
||||
/* For now, we conservatively take the array length to be 0
|
||||
if its length exceeds UINT_MAX. The code below assumes
|
||||
that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
|
||||
which is technically not guaranteed by C, but is usually true
|
||||
(because it would be true if x were unsigned with its
|
||||
high-order bit on). It uses the fact that
|
||||
high_bound-low_bound is always representable in
|
||||
ULONGEST and that if high_bound-low_bound+1 overflows,
|
||||
it overflows to 0. We must change these tests if we
|
||||
decide to increase the representation of TYPE_LENGTH
|
||||
from unsigned int to ULONGEST. */
|
||||
ULONGEST ulow = low_bound, uhigh = high_bound;
|
||||
ULONGEST tlen = TYPE_LENGTH (target_type);
|
||||
|
||||
len = tlen * (uhigh - ulow + 1);
|
||||
if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh
|
||||
|| len > UINT_MAX)
|
||||
len = 0;
|
||||
}
|
||||
TYPE_LENGTH (type) = len;
|
||||
TYPE_TARGET_STUB (type) = 0;
|
||||
}
|
||||
else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
|
||||
{
|
||||
TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/* Internal type definitions for GDB.
|
||||
|
||||
Copyright (C) 1992-2014 Free Software Foundation, Inc.
|
||||
|
@ -663,16 +662,6 @@ struct main_type
|
|||
/* * High bound of range. */
|
||||
|
||||
struct dynamic_prop high;
|
||||
|
||||
/* True if HIGH range bound contains the number of elements in the
|
||||
subrange. This affects how the final hight bound is computed. */
|
||||
|
||||
int flag_upper_bound_is_count : 1;
|
||||
|
||||
/* True if LOW or/and HIGH are resolved into a static bound from
|
||||
a dynamic one. */
|
||||
|
||||
int flag_bound_evaluated : 1;
|
||||
} *bounds;
|
||||
|
||||
} flds_bnds;
|
||||
|
@ -1693,15 +1682,6 @@ extern void get_unsigned_type_max (struct type *, ULONGEST *);
|
|||
|
||||
extern void get_signed_type_minmax (struct type *, LONGEST *, LONGEST *);
|
||||
|
||||
/* * 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
|
||||
static properties is returned. */
|
||||
extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
|
||||
|
||||
/* * Predicate if the type has dynamic values, which are not resolved yet. */
|
||||
extern int is_dynamic_type (struct type *type);
|
||||
|
||||
extern struct type *check_typedef (struct type *);
|
||||
|
||||
#define CHECK_TYPEDEF(TYPE) \
|
||||
|
|
|
@ -65,7 +65,6 @@ java_value_print (struct value *val, struct ui_file *stream,
|
|||
type = lookup_pointer_type (type);
|
||||
|
||||
val = value_at (type, address);
|
||||
type = value_type (val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
2014-04-11 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
Revert the following changes (regressions):
|
||||
|
||||
* gdb.base/vla-sideeffect.c: New file.
|
||||
* gdb.base/vla-sideeffect.exp: New file.
|
||||
|
||||
* gdb.dwarf2/count.exp: New file.
|
||||
|
||||
* gdb.base/vla-multi.c: New file.
|
||||
* gdb.base/vla-multi.exp: New file.
|
||||
|
||||
* gdb.base/vla-ptr.c: New file.
|
||||
* gdb.base/vla-ptr.exp: New file.
|
||||
|
||||
* gdb.base/vla-datatypes.c: New file.
|
||||
* gdb.base/vla-datatypes.exp: New file.
|
||||
|
||||
* gdb.mi/mi-vla-c99.exp: New file.
|
||||
* gdb.mi/vla.c: New file.
|
||||
|
||||
2014-04-11 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
PR c++/16675
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#define SIZE 5
|
||||
|
||||
struct foo
|
||||
{
|
||||
int a;
|
||||
};
|
||||
|
||||
typedef struct bar
|
||||
{
|
||||
int x;
|
||||
struct foo y;
|
||||
} BAR;
|
||||
|
||||
void
|
||||
vla_factory (int n)
|
||||
{
|
||||
int int_vla[n];
|
||||
unsigned int unsigned_int_vla[n];
|
||||
double double_vla[n];
|
||||
float float_vla[n];
|
||||
long long_vla[n];
|
||||
unsigned long unsigned_long_vla[n];
|
||||
char char_vla[n];
|
||||
short short_vla[n];
|
||||
unsigned short unsigned_short_vla[n];
|
||||
unsigned char unsigned_char_vla[n];
|
||||
struct foo foo_vla[n];
|
||||
BAR bar_vla[n];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
int_vla[i] = i*2;
|
||||
unsigned_int_vla[i] = i*2;
|
||||
double_vla[i] = i/2.0;
|
||||
float_vla[i] = i/2.0f;
|
||||
long_vla[i] = i*2;
|
||||
unsigned_long_vla[i] = i*2;
|
||||
char_vla[i] = 'A';
|
||||
short_vla[i] = i*2;
|
||||
unsigned_short_vla[i] = i*2;
|
||||
unsigned_char_vla[i] = 'A';
|
||||
foo_vla[i].a = i*2;
|
||||
bar_vla[i].x = i*2;
|
||||
bar_vla[i].y.a = i*2;
|
||||
}
|
||||
|
||||
size_t int_size = sizeof(int_vla); /* vlas_filled */
|
||||
size_t uint_size = sizeof(unsigned_int_vla);
|
||||
size_t double_size = sizeof(double_vla);
|
||||
size_t float_size = sizeof(float_vla);
|
||||
size_t long_size = sizeof(long_vla);
|
||||
size_t char_size = sizeof(char_vla);
|
||||
size_t short_size = sizeof(short_vla);
|
||||
size_t ushort_size = sizeof(unsigned_short_vla);
|
||||
size_t uchar_size = sizeof(unsigned_char_vla);
|
||||
size_t foo_size = sizeof(foo_vla);
|
||||
size_t bar_size = sizeof(bar_vla);
|
||||
|
||||
return; /* break_end_of_vla_factory */
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
vla_factory(SIZE);
|
||||
return 0;
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vlas_filled"]
|
||||
gdb_continue_to_breakpoint "vlas_filled"
|
||||
|
||||
# Check the values of VLA's.
|
||||
gdb_test "print int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print int_vla"
|
||||
gdb_test "print unsigned_int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print unsigned_int_vla"
|
||||
gdb_test "print double_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
|
||||
"print double_vla"
|
||||
gdb_test "print float_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
|
||||
"print float_vla"
|
||||
gdb_test "print long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print long_vla"
|
||||
gdb_test "print unsigned_long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print unsigned_long_vla"
|
||||
gdb_test "print char_vla" " = \"AAAAA\"" \
|
||||
"print char_vla"
|
||||
gdb_test "print short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print short_vla"
|
||||
gdb_test "print unsigned_short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
|
||||
"print unsigned_short_vla"
|
||||
gdb_test "print unsigned_char_vla" " = \"AAAAA\"" \
|
||||
"print unsigned_char_vla"
|
||||
gdb_test "print foo_vla" \
|
||||
"\\\{\\\{a = 0\\\}, \\\{a = 2\\\}, \\\{a = 4\\\}, \\\{a = 6\\\}, \\\{a = 8\\\}\\\}" \
|
||||
"print foo_vla"
|
||||
gdb_test "print bar_vla" \
|
||||
"\\\{\\\{x = 0, y = \\\{a = 0\\\}\\\}, \\\{x = 2, y = \\\{a = 2\\\}\\\}, \\\{x = 4, y = \\\{a = 4\\\}\\\}, \\\{x = 6, y = \\\{a = 6\\\}\\\}, \\\{x = 8, y = \\\{a = 8\\\}\\\}\\\}" \
|
||||
"print bar_vla"
|
||||
|
||||
# Check whatis of VLA's.
|
||||
gdb_test "whatis int_vla" "type = int \\\[5\\\]" "whatis int_vla"
|
||||
gdb_test "whatis unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
|
||||
"whatis unsigned_int_vla"
|
||||
gdb_test "whatis double_vla" "type = double \\\[5\\\]" "whatis double_vla"
|
||||
gdb_test "whatis float_vla" "type = float \\\[5\\\]" "whatis float_vla"
|
||||
gdb_test "whatis long_vla" "type = long( int)? \\\[5\\\]" "whatis long_vla"
|
||||
gdb_test "whatis unsigned_long_vla" \
|
||||
"type = (long unsigned int|unsigned long) \\\[5\\\]" \
|
||||
"whatis unsigned_long_vla"
|
||||
gdb_test "whatis char_vla" "type = char \\\[5\\\]" "whatis char_vla"
|
||||
gdb_test "whatis short_vla" "type = short( int)? \\\[5\\\]" \
|
||||
"whatis short_vla"
|
||||
gdb_test "whatis unsigned_short_vla" \
|
||||
"type = (short unsigned int|unsigned short) \\\[5\\\]" \
|
||||
"whatis unsigned_short_vla"
|
||||
gdb_test "whatis unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
|
||||
"whatis unsigned_char_vla"
|
||||
gdb_test "whatis foo_vla" "type = struct foo \\\[5\\\]" "whatis foo_vla"
|
||||
gdb_test "whatis bar_vla" "type = BAR \\\[5\\\]" "whatis bar_vla"
|
||||
|
||||
# Check ptype of VLA's.
|
||||
gdb_test "ptype int_vla" "type = int \\\[5\\\]" "ptype int_vla"
|
||||
gdb_test "ptype unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
|
||||
"ptype unsigned_int_vla"
|
||||
gdb_test "ptype double_vla" "type = double \\\[5\\\]" "ptype double_vla"
|
||||
gdb_test "ptype float_vla" "type = float \\\[5\\\]" "ptype float_vla"
|
||||
gdb_test "ptype long_vla" "type = long( int)? \\\[5\\\]" "ptype long_vla"
|
||||
gdb_test "ptype unsigned_long_vla" "type = unsigned long \\\[5\\\]" \
|
||||
"ptype unsigned_long_vla"
|
||||
gdb_test "ptype char_vla" "type = char \\\[5\\\]" "ptype char_vla"
|
||||
gdb_test "ptype short_vla" "type = short( int)? \\\[5\\\]" \
|
||||
"ptype short_vla"
|
||||
gdb_test "ptype unsigned_short_vla" "type = unsigned short \\\[5\\\]" \
|
||||
"ptype unsigned_short_vla"
|
||||
gdb_test "ptype unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
|
||||
"ptype unsigned_char_vla"
|
||||
gdb_test "ptype foo_vla" "type = struct foo {\r\n\\s+int a;\r\n} \\\[5\\\]" \
|
||||
"ptype foo_vla"
|
||||
gdb_test "ptype bar_vla" \
|
||||
"type = struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \\\[5\\\]" \
|
||||
"ptype bar_vla"
|
||||
|
||||
# Check the size of the VLA's.
|
||||
gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"]
|
||||
gdb_continue_to_breakpoint "break_end_of_vla_factory"
|
||||
gdb_test "print int_size == sizeof(int_vla)" " = 1" "size of int_vla"
|
||||
gdb_test "print uint_size == sizeof(unsigned_int_vla)" " = 1" \
|
||||
"size of unsigned_int_vla"
|
||||
gdb_test "print double_size == sizeof(double_vla)" " = 1" \
|
||||
"size of double_vla"
|
||||
gdb_test "print float_size == sizeof(float_vla)" " = 1" \
|
||||
"size of float_vla"
|
||||
gdb_test "print long_size == sizeof(long_vla)" " = 1" \
|
||||
"size of long_vla"
|
||||
gdb_test "print char_size == sizeof(char_vla)" " = 1" \
|
||||
"size of char_vla"
|
||||
gdb_test "print short_size == sizeof(short_vla)" " = 1" \
|
||||
"size of short_vla"
|
||||
gdb_test "print ushort_size == sizeof(unsigned_short_vla)" " = 1" \
|
||||
"size of unsigned_short_vla"
|
||||
gdb_test "print uchar_size == sizeof(unsigned_char_vla)" " = 1" \
|
||||
"size of unsigned_char_vla"
|
||||
gdb_test "print foo_size == sizeof(foo_vla)" " = 1" "size of foo_vla"
|
||||
gdb_test "print bar_size == sizeof(bar_vla)" " = 1" "size of bar_vla"
|
||||
|
||||
# Check side effects for sizeof argument.
|
||||
set sizeof_int [get_sizeof "int" 4]
|
||||
gdb_test_no_output "set variable int_vla\[0\] = 42" \
|
||||
"set variable int_vla\[0\] = 42"
|
||||
|
||||
gdb_test "print sizeof (++int_vla\[0\])" " = ${sizeof_int}" \
|
||||
"print sizeof (++int_vla\[0\])"
|
||||
gdb_test "print int_vla\[0\]" " = 42" \
|
||||
"print int_vla\[0\] - sizeof no side effects"
|
||||
|
||||
gdb_test "ptype ++int_vla\[0\]" "type = int" "ptype ++int_vla\[0\]"
|
||||
gdb_test "print int_vla\[0\]" " = 42" \
|
||||
"print int_vla\[0\] - ptype no side effects"
|
||||
|
||||
gdb_test "whatis ++int_vla\[0\]" "type = int" "whatis ++int_vla\[0\]"
|
||||
gdb_test "print int_vla\[0\]" " = 42" \
|
||||
"print int_vla\[0\] - whatis no side effects"
|
|
@ -1,48 +0,0 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
void
|
||||
f1 (int n, int m, int vla_ptr[n][m])
|
||||
{
|
||||
return; /* f1_breakpoint */
|
||||
}
|
||||
|
||||
void
|
||||
vla_mult (int n, int m)
|
||||
{
|
||||
int vla[n][m];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (j = 0; j < m; j++)
|
||||
{
|
||||
vla[i][j] = i + j;
|
||||
}
|
||||
}
|
||||
|
||||
f1(n, m, vla); /* vla_filled */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
vla_mult(2, 2);
|
||||
return 0;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
set sizeof_int [get_sizeof "int" 4]
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla_filled"]
|
||||
gdb_continue_to_breakpoint "vla_filled"
|
||||
gdb_test "print vla" " = \\\{\\\{0, 1\\\}, \\\{1, 2\\\}\\\}" \
|
||||
"print vla"
|
||||
gdb_test "print vla\[0\]\[1\]" " = 1" "print vla\[0\]\[1\]"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "f1_breakpoint"]
|
||||
gdb_continue_to_breakpoint "f1_breakpoint"
|
||||
|
||||
# Calculate the overall size of the vla.
|
||||
set sizeof_vla [ expr "2" * "$sizeof_int" ]
|
||||
gdb_test "ptype &vla_ptr" \
|
||||
"type = int \\\(\\\*\\\*\\\)\\\[variable length\\\]" \
|
||||
"ptype &vla_ptr"
|
|
@ -1,58 +0,0 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define SIZE 5
|
||||
|
||||
void
|
||||
foo (int n, int vla_ptr[n])
|
||||
{
|
||||
return; /* foo_bp */
|
||||
}
|
||||
|
||||
void
|
||||
bar (int *vla_ptr)
|
||||
{
|
||||
return; /* bar_bp */
|
||||
}
|
||||
|
||||
void
|
||||
vla_func (int n)
|
||||
{
|
||||
int vla[n];
|
||||
typedef int typedef_vla[n];
|
||||
typedef_vla td_vla;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
vla[i] = 2+i;
|
||||
td_vla[i] = 4+i;
|
||||
}
|
||||
|
||||
foo(n, vla);
|
||||
bar(vla);
|
||||
|
||||
return; /* vla_func_bp */
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
vla_func(SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
set sizeof_int [get_sizeof "int" 4]
|
||||
|
||||
# Check that VLA passed to function (pointer) points to the first element.
|
||||
gdb_breakpoint [gdb_get_line_number "foo_bp"]
|
||||
gdb_continue_to_breakpoint "foo_bp"
|
||||
gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (foo)"
|
||||
gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (foo)"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "bar_bp"]
|
||||
gdb_continue_to_breakpoint "bar_bp"
|
||||
gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (bar)"
|
||||
gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (bar)"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla_func_bp"]
|
||||
gdb_continue_to_breakpoint "vla_func_bp"
|
||||
gdb_test "print td_vla" " = \\\{4, 5, 6, 7, 8\\\}" "print td_vla"
|
|
@ -1,42 +0,0 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#define SIZE 10
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int n = SIZE;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int vla2[SIZE][n];
|
||||
int vla1[n];
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
vla1[i] = (i * 2) + n;
|
||||
|
||||
for (i = 0; i < SIZE; i++)
|
||||
for (j = 0; j < n; j++)
|
||||
vla2[i][j] = (i + j) + n;
|
||||
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
|
||||
return 0; /* vla-filled */
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Tests side-effects of sizeof evaluation.
|
||||
# Based on gcc/testsuite/gcc.dg/vla-4.c; vla-15.c
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla-filled"]
|
||||
gdb_continue_to_breakpoint "vla-filled"
|
||||
|
||||
# Check side effects for sizeof argument.
|
||||
set sizeof_int [get_sizeof "int" 4]
|
||||
set sizeof_vla [ expr "10" * "$sizeof_int" ]
|
||||
|
||||
gdb_test "print sizeof (vla1\[i++\])" " = ${sizeof_int}" \
|
||||
"print sizeof (vla1\[i++\])"
|
||||
gdb_test "print i" " = 0" \
|
||||
"print i - sizeof no side effects"
|
||||
|
||||
gdb_test "print sizeof (++vla1\[0\])" " = ${sizeof_int}" \
|
||||
"print sizeof (++vla1\[0\])"
|
||||
gdb_test "print vla1\[0\]" " = 10" \
|
||||
"print vla1\[0\] - sizeof no side effects"
|
||||
|
||||
gdb_test "ptype ++vla1\[0\]" "type = int" "ptype ++vla1\[0\]"
|
||||
gdb_test "print vla1\[0\]" " = 10" \
|
||||
"print vla1\[0\] - ptype no side effects"
|
||||
|
||||
gdb_test "whatis ++vla1\[0\]" "type = int" "whatis ++vla1\[0\]"
|
||||
gdb_test "print vla1\[0\]" " = 10" \
|
||||
"print vla1\[0\] - whatis no side effects"
|
||||
|
||||
|
||||
gdb_test "print sizeof (vla2\[i++\])" " = ${sizeof_vla}" \
|
||||
"print sizeof (vla2\[i++\])"
|
||||
gdb_test "print i" " = 1" \
|
||||
"print i - sizeof with side effects (1)"
|
||||
|
||||
gdb_test "print sizeof (vla2\[i++ + sizeof(j++)\])" " = ${sizeof_vla}" \
|
||||
"print sizeof (vla2\[i++ + sizeof(j++)\])"
|
||||
gdb_test "print i" " = 2" \
|
||||
"print i - sizeof with side effects (2)"
|
||||
gdb_test "print j" " = 0" \
|
||||
"print j - sizeof with no side effects"
|
||||
|
||||
gdb_test "ptype vla2\[i++\]" "type = int \\\[10\\\]" \
|
||||
"ptype vla2\[i++\]"
|
||||
gdb_test "print i" " = 2" \
|
||||
"print i - ptype with side effects (1)"
|
||||
|
||||
gdb_test "ptype vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
|
||||
"ptype vla2\[i++ + sizeof(j++)\]"
|
||||
gdb_test "print i" " = 2" \
|
||||
"print i - ptype with side effects (2)"
|
||||
gdb_test "print j" " = 0" \
|
||||
"print j - ptype with no side effects"
|
||||
|
||||
gdb_test "whatis vla2\[i++\]" "type = int \\\[10\\\]" \
|
||||
"whatis vla2\[i++\]"
|
||||
gdb_test "print i" " = 2" \
|
||||
"print i - whatis with side effects (1)"
|
||||
|
||||
gdb_test "whatis vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
|
||||
"whatis vla2\[i++ + sizeof(j++)\]"
|
||||
gdb_test "print i" " = 2" \
|
||||
"print i - whatis with side effects (2)"
|
||||
gdb_test "print j" " = 0" \
|
||||
"print j - whatis with no side effects"
|
|
@ -1,125 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Tests to cover DW_AT_count attribute in subranges.
|
||||
|
||||
load_lib dwarf.exp
|
||||
|
||||
# Only run on targets which support dwarf and gas.
|
||||
if { ![dwarf2_support] } {
|
||||
return 0
|
||||
}
|
||||
|
||||
standard_testfile main.c count.S
|
||||
|
||||
set asm_file [standard_output_file $srcfile2]
|
||||
Dwarf::assemble $asm_file {
|
||||
cu {} {
|
||||
compile_unit {{language @DW_LANG_C99}} {
|
||||
declare_labels char_label array_label array_label2 static_array_label
|
||||
|
||||
char_label: base_type {
|
||||
{name char}
|
||||
{encoding @DW_ATE_signed}
|
||||
{byte_size 1 DW_FORM_sdata}
|
||||
}
|
||||
|
||||
array_label: array_type {
|
||||
{type :$char_label}
|
||||
} {
|
||||
subrange_type {
|
||||
{count {DW_OP_lit5} SPECIAL_expr}
|
||||
{type :$char_label}
|
||||
}
|
||||
}
|
||||
|
||||
array_label2: array_type {
|
||||
{type :$char_label}
|
||||
} {
|
||||
subrange_type {
|
||||
{count {DW_OP_lit1} SPECIAL_expr}
|
||||
{type :$char_label}
|
||||
}
|
||||
}
|
||||
|
||||
static_array_label: array_type {
|
||||
{type :$char_label}
|
||||
} {
|
||||
subrange_type {
|
||||
{count 5 DW_FORM_sdata}
|
||||
{type :$char_label}
|
||||
}
|
||||
}
|
||||
|
||||
DW_TAG_variable {
|
||||
{name array2}
|
||||
{type :$array_label2}
|
||||
{const_value 65 DW_FORM_udata}
|
||||
}
|
||||
|
||||
DW_TAG_variable {
|
||||
{name array}
|
||||
{type :$array_label}
|
||||
{const_value hello DW_FORM_block1}
|
||||
}
|
||||
|
||||
DW_TAG_variable {
|
||||
{name static_array}
|
||||
{type :$static_array_label}
|
||||
{const_value world DW_FORM_block1}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
|
||||
object {nodebug}] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [gdb_compile $asm_file ${binfile}2.o object {nodebug}] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [gdb_compile [list ${binfile}1.o ${binfile}2.o] \
|
||||
"${binfile}" executable {}] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
global GDBFLAGS
|
||||
set saved_gdbflags $GDBFLAGS
|
||||
set GDBFLAGS [concat $GDBFLAGS " -readnow"]
|
||||
clean_restart ${testfile}
|
||||
set GDBFLAGS $saved_gdbflags
|
||||
|
||||
if ![runto_main] {
|
||||
perror "couldn't run to main"
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_test "ptype array" "type = char \\\[5\\\]" "ptype array"
|
||||
gdb_test "whatis array" "type = char \\\[5\\\]" "whatis array"
|
||||
gdb_test "print array" " = \"hello\"" "print array"
|
||||
gdb_test "print sizeof array" " = 5" "print sizeof array"
|
||||
|
||||
gdb_test "ptype array2" "type = char \\\[1\\\]" "ptype array"
|
||||
gdb_test "whatis array2" "type = char \\\[1\\\]" "whatis array"
|
||||
gdb_test "print array2" " = \"A\"" "print array"
|
||||
gdb_test "print sizeof array2" " = 1" "print sizeof array"
|
||||
|
||||
gdb_test "ptype static_array" "type = char \\\[5\\\]" "ptype static_array"
|
||||
gdb_test "whatis static_array" "type = char \\\[5\\\]" "whatis static_array"
|
||||
gdb_test "print static_array" " = \"world\"" "print static_array"
|
||||
gdb_test "print sizeof static_array" " = 5" "print sizeof static_array"
|
|
@ -1,82 +0,0 @@
|
|||
# Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
# Contributed by Intel Corp. <keven.boell@intel.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Verify that, using the MI, we can evaluate a simple C Variable Length
|
||||
# Array (VLA).
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi"
|
||||
|
||||
gdb_exit
|
||||
if [mi_gdb_start] {
|
||||
continue
|
||||
}
|
||||
|
||||
standard_testfile vla.c
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" \
|
||||
"${binfile}" executable {debug}] != "" } {
|
||||
untested mi-vla-basics.exp
|
||||
return -1
|
||||
}
|
||||
|
||||
mi_delete_breakpoints
|
||||
mi_gdb_reinitialize_dir $srcdir/$subdir
|
||||
mi_gdb_load ${binfile}
|
||||
|
||||
set bp_lineno [gdb_get_line_number "vla-filled"]
|
||||
|
||||
mi_create_breakpoint "-t vla.c:$bp_lineno" 1 "del" "func" \
|
||||
".*vla.c" $bp_lineno $hex \
|
||||
"insert breakpoint at line $bp_lineno after vla is filled"
|
||||
mi_run_cmd
|
||||
mi_expect_stop "breakpoint-hit" "func" "\{name=\"n\",value=\"5\"\}" \
|
||||
".*vla.c" "$bp_lineno" { "" "disp=\"del\"" } \
|
||||
"run to breakpoint at line $bp_lineno"
|
||||
|
||||
mi_gdb_test "500-data-evaluate-expression vla" \
|
||||
"500\\^done,value=\"\\{0, 1, 2, 3, 4\\}\"" "evaluate complete vla"
|
||||
|
||||
mi_gdb_test "501-data-evaluate-expression vla\[0\]" \
|
||||
"501\\^done,value=\"0\"" "evaluate vla\[0\]"
|
||||
|
||||
mi_gdb_test "502-data-evaluate-expression vla\[2\]" \
|
||||
"502\\^done,value=\"2\"" "evaluate vla\[2\]"
|
||||
|
||||
mi_gdb_test "503-data-evaluate-expression vla\[4\]" \
|
||||
"503\\^done,value=\"4\"" "evaluate vla\[4\]"
|
||||
|
||||
mi_create_varobj_checked vla vla "int \\\[5\\\]" \
|
||||
"create local variable vla"
|
||||
|
||||
mi_gdb_test "504-var-info-type vla" \
|
||||
"504\\^done,type=\"int \\\[5\\\]\"" \
|
||||
"info type variable vla"
|
||||
|
||||
mi_gdb_test "505-var-show-format vla" \
|
||||
"505\\^done,format=\"natural\"" \
|
||||
"show format variable vla"
|
||||
|
||||
mi_gdb_test "506-var-evaluate-expression vla" \
|
||||
"506\\^done,value=\"\\\[5\\\]\"" \
|
||||
"eval variable vla"
|
||||
|
||||
mi_list_array_varobj_children "vla" "5" "int" \
|
||||
"get children of vla"
|
||||
|
||||
mi_gdb_exit
|
||||
return 0
|
|
@ -1,37 +0,0 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Contributed by Intel Corp. <keven.boell@intel.com>
|
||||
|
||||
Copyright 2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
int
|
||||
func (int n)
|
||||
{
|
||||
int vla[n], i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
vla[i] = i;
|
||||
|
||||
return n; /* vla-filled */
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
func (5);
|
||||
|
||||
return 0;
|
||||
}
|
19
gdb/valops.c
19
gdb/valops.c
|
@ -266,7 +266,6 @@ value_cast_structs (struct type *type, struct value *v2)
|
|||
{
|
||||
v = value_full_object (v2, real_type, full, top, using_enc);
|
||||
v = value_at_lazy (real_type, value_address (v));
|
||||
real_type = value_type (v);
|
||||
|
||||
/* We might be trying to cast to the outermost enclosing
|
||||
type, in which case search_struct_field won't work. */
|
||||
|
@ -802,7 +801,6 @@ value_dynamic_cast (struct type *type, struct value *arg)
|
|||
return value_at_lazy (type, addr);
|
||||
|
||||
tem = value_at (type, addr);
|
||||
type = value_type (tem);
|
||||
|
||||
/* The first dynamic check specified in 5.2.7. */
|
||||
if (is_public_ancestor (arg_type, TYPE_TARGET_TYPE (resolved_type)))
|
||||
|
@ -902,10 +900,7 @@ value_one (struct type *type)
|
|||
return val;
|
||||
}
|
||||
|
||||
/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
|
||||
The type of the created value may differ from the passed type TYPE.
|
||||
Make sure to retrieve the returned values's new type after this call
|
||||
e.g. in case the type is a variable length array. */
|
||||
/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack. */
|
||||
|
||||
static struct value *
|
||||
get_value_at (struct type *type, CORE_ADDR addr, int lazy)
|
||||
|
@ -930,10 +925,7 @@ get_value_at (struct type *type, CORE_ADDR addr, int lazy)
|
|||
value_at_lazy instead. value_at_lazy simply records the address of
|
||||
the data and sets the lazy-evaluation-required flag. The lazy flag
|
||||
is tested in the value_contents macro, which is used if and when
|
||||
the contents are actually required. The type of the created value
|
||||
may differ from the passed type TYPE. Make sure to retrieve the
|
||||
returned values's new type after this call e.g. in case the type
|
||||
is a variable length array.
|
||||
the contents are actually required.
|
||||
|
||||
Note: value_at does *NOT* handle embedded offsets; perform such
|
||||
adjustments before or after calling it. */
|
||||
|
@ -944,10 +936,7 @@ value_at (struct type *type, CORE_ADDR addr)
|
|||
return get_value_at (type, addr, 0);
|
||||
}
|
||||
|
||||
/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
|
||||
The type of the created value may differ from the passed type TYPE.
|
||||
Make sure to retrieve the returned values's new type after this call
|
||||
e.g. in case the type is a variable length array. */
|
||||
/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
|
||||
|
||||
struct value *
|
||||
value_at_lazy (struct type *type, CORE_ADDR addr)
|
||||
|
@ -1322,7 +1311,6 @@ address_of_variable (struct symbol *var, const struct block *b)
|
|||
Lazy evaluation pays off here. */
|
||||
|
||||
val = value_of_variable (var, b);
|
||||
type = value_type (val);
|
||||
|
||||
if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
|
||||
|| TYPE_CODE (type) == TYPE_CODE_FUNC)
|
||||
|
@ -1571,7 +1559,6 @@ value_ind (struct value *arg1)
|
|||
(value_as_address (arg1)
|
||||
- value_pointed_to_offset (arg1)));
|
||||
|
||||
enc_type = value_type (arg2);
|
||||
return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
|
||||
}
|
||||
|
||||
|
|
20
gdb/value.c
20
gdb/value.c
|
@ -3319,39 +3319,32 @@ value_from_ulongest (struct type *type, ULONGEST num)
|
|||
|
||||
|
||||
/* Create a value representing a pointer of type TYPE to the address
|
||||
ADDR. The type of the created value may differ from the passed
|
||||
type TYPE. Make sure to retrieve the returned values's new type
|
||||
after this call e.g. in case of an variable length array. */
|
||||
|
||||
ADDR. */
|
||||
struct value *
|
||||
value_from_pointer (struct type *type, CORE_ADDR addr)
|
||||
{
|
||||
struct type *resolved_type = resolve_dynamic_type (type, addr);
|
||||
struct value *val = allocate_value (resolved_type);
|
||||
struct value *val = allocate_value (type);
|
||||
|
||||
store_typed_address (value_contents_raw (val),
|
||||
check_typedef (resolved_type), addr);
|
||||
store_typed_address (value_contents_raw (val), check_typedef (type), addr);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/* Create a value of type TYPE whose contents come from VALADDR, if it
|
||||
is non-null, and whose memory address (in the inferior) is
|
||||
ADDRESS. The type of the created value may differ from the passed
|
||||
type TYPE. Make sure to retrieve values new type after this call. */
|
||||
ADDRESS. */
|
||||
|
||||
struct value *
|
||||
value_from_contents_and_address (struct type *type,
|
||||
const gdb_byte *valaddr,
|
||||
CORE_ADDR address)
|
||||
{
|
||||
struct type *resolved_type = resolve_dynamic_type (type, address);
|
||||
struct value *v;
|
||||
|
||||
if (valaddr == NULL)
|
||||
v = allocate_value_lazy (resolved_type);
|
||||
v = allocate_value_lazy (type);
|
||||
else
|
||||
v = value_from_contents (resolved_type, valaddr);
|
||||
v = value_from_contents (type, valaddr);
|
||||
set_value_address (v, address);
|
||||
VALUE_LVAL (v) = lval_memory;
|
||||
return v;
|
||||
|
@ -3505,7 +3498,6 @@ coerce_ref (struct value *arg)
|
|||
retval = value_at_lazy (enc_type,
|
||||
unpack_pointer (value_type (arg),
|
||||
value_contents (arg)));
|
||||
enc_type = value_type (retval);
|
||||
return readjust_indirect_value_type (retval, enc_type,
|
||||
value_type_arg_tmp, arg);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue