old-cross-binutils/gdb/testsuite/gdb.ada/pkd_arr_elem.exp

39 lines
1.2 KiB
Text
Raw Normal View History

# Copyright 2014-2015 Free Software Foundation, Inc.
varsize-limit error printing element of packed array... ... when that packed array is part of a discriminated record and one of the bounds is a discriminant. Consider the following code: type FUNNY_CHAR_T is (NUL, ' ', '"', '#', [etc]); type FUNNY_STR_T is array (POSITIVE range <>) of FUNNY_CHAR_T; pragma PACK (FUNNY_STR_T); type FUNNY_STRING_T (SIZE : NATURAL := 1) is record STR : FUNNY_STR_T (1 .. SIZE) := (others => '0'); LENGTH : NATURAL := 4; end record; TEST: FUNNY_STRING_T(100); GDB is able to print the value of variable "test" and "test.str". But not "test.str(1)": (gdb) p test $1 = (size => 100, str => (33 'A', nul <repeats 99 times>), length => 1) (gdb) p test.str $2 = (33 'A', nul <repeats 99 times>) (gdb) p test.str(1) object size is larger than varsize-limit The problem occurs during the phase where we are trying to resolve the expression subscript operation. On the one hand of the subscript operator, we have the result of the evaluation of "test.str", which is our packed array. We have the following code to handle packed arrays in particular: if (ada_is_constrained_packed_array_type (desc_base_type (value_type (argvec[0])))) argvec[0] = ada_coerce_to_simple_array (argvec[0]); This eventually leads to a call to constrained_packed_array_type to return the "simple array". This function relies on a parallel ___XA type, when available, to determine the bounds. In our case, we find type... failure__funny_string_t__T4b___XA" ... which has one field describing the bounds of our array as: failure__funny_string_t__T3b___XDLU_1__size The part that interests us is after the ___XD suffix or, in other words: "LU_1__size". What this means in GNAT encoding parlance is that the lower bound is 1, and that the upper bound is the value of "size". "size" is our discriminant in this case. Normally, we would access the record's discriminant in order to get the upper bound's value, but we do not have that information, here. We are in a mode where we are just trying to "fix" the type without an actual value. This is what the call to to_fixed_range_type is doing, and because the fix'ing fails, it ends up returning the ___XDLU type unmodified as our index type. This shouldn't be a problem, except that the later part of constrained_packed_array_type then uses that index_type to determine the array size, via a call to get_discrete_bounds. The problem is that the upper bound of the ___XDLU type is dynamic (in the DWARF sense) while get_discrete_bounds implicitly assumes that the bounds are static, and therefore accesses them using macros that assume the bounds values are constants: case TYPE_CODE_RANGE: *lowp = TYPE_LOW_BOUND (type); *highp = TYPE_HIGH_BOUND (type); This therefore returns a bogus value for the upper bound, leading to an unexpectedly large size for our array, which later triggers the varsize-limit guard we've seen above. This patch avoids the problem by adding special handling of dynamic range types. It also extends the documentation of the constrained_packed_array_type function to document what happens in this situation. gdb/ChangeLog: * ada-lang.c (constrained_packed_array_type): Set the length of the return array as if both bounds where zero if that returned array's index type is dynamic. gdb/testsuite/ChangeLog: * gdb.ada/pkd_arr_elem: New Testcase. Tested on x86_64-linux.
2014-09-12 01:38:04 +00:00
#
# 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/>.
load_lib "ada.exp"
if { [skip_ada_tests] } { return -1 }
standard_ada_testfile failure
if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
return -1
}
clean_restart ${testfile}
set bp_location [gdb_get_line_number "START" ${testdir}/failure.adb]
runto "failure.adb:$bp_location"
gdb_test "print test" \
"= \\(size => 100, str => \\(33 'A', nul <repeats 99 times>\\), length => 1\\)"
gdb_test "print test.str" \
"= \\(33 'A', nul <repeats 99 times>\\)"
gdb_test "print test.str(1)" \
"= 33 'A'"