diff options
-rw-r--r-- | gdb/gdbtypes.c | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.fortran/assumedrank.exp | 29 | ||||
-rw-r--r-- | gdb/testsuite/gdb.fortran/assumedrank.f90 | 5 |
3 files changed, 49 insertions, 23 deletions
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 2623278..49ecb19 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2194,7 +2194,11 @@ static struct type *resolve_dynamic_type_internal and stride information set to undefined. The RESOLVE_P set to false case will be used when evaluating a dynamic array that is not allocated, or not associated, i.e. the bounds information might not be - initialized yet. */ + initialized yet. + + RANK is the array rank for which we are resolving this range, and is a + zero based count. The rank should never be negative. +*/ static struct type * resolve_dynamic_range (struct type *dyn_range_type, @@ -2206,6 +2210,7 @@ resolve_dynamic_range (struct type *dyn_range_type, struct dynamic_prop low_bound, high_bound, stride; gdb_assert (dyn_range_type->code () == TYPE_CODE_RANGE); + gdb_assert (rank >= 0); const struct dynamic_prop *prop = &dyn_range_type->bounds ()->low; if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value, @@ -2263,11 +2268,11 @@ resolve_dynamic_range (struct type *dyn_range_type, /* Helper function for resolve_dynamic_array_or_string. This function resolves the properties for a single array at RANK within a nested array - of arrays structure. The RANK value is always greater than 0, and + of arrays structure. The RANK value is greater than or equal to 0, and starts at it's maximum value and goes down by 1 for each recursive call to this function. So, for a 3-dimensional array, the first call to this - function has RANK == 3, then we call ourselves recursively with RANK == - 2, than again with RANK == 1, and at that point we should return. + function has RANK == 2, then we call ourselves recursively with RANK == + 1, than again with RANK == 0, and at that point we should return. TYPE is updated as the dynamic properties are resolved, and so, should be a copy of the dynamic type, rather than the original dynamic type @@ -2297,9 +2302,9 @@ resolve_dynamic_array_or_string_1 (struct type *type, gdb_assert (type->code () == TYPE_CODE_ARRAY || type->code () == TYPE_CODE_STRING); - /* The outer resolve_dynamic_array_or_string should ensure we always have - a rank of at least 1 when we get here. */ - gdb_assert (rank > 0); + /* As the rank is a zero based count we expect this to never be + negative. */ + gdb_assert (rank >= 0); /* Resolve the allocated and associated properties before doing anything else. If an array is not allocated or not associated then (at least @@ -2435,6 +2440,14 @@ resolve_dynamic_array_or_string (struct type *type, ++rank; } + /* The rank that we calculated above is actually a count of the number of + ranks. However, when we resolve the type of each individual array + rank we should actually use a rank "offset", e.g. an array with a rank + count of 1 (calculated above) will use the rank offset 0 in order to + resolve the details of the first array dimension. As a result, we + reduce the rank by 1 here. */ + --rank; + return resolve_dynamic_array_or_string_1 (type, addr_stack, rank, true); } @@ -2823,11 +2836,12 @@ resolve_dynamic_type_internal (struct type *type, break; case TYPE_CODE_RANGE: - /* Pass 1 for the rank value here. The assumption is that this - rank value is not actually required for the resolution of the - dynamic range, otherwise, we'd be resolving this range within - the context of a dynamic array. */ - resolved_type = resolve_dynamic_range (type, addr_stack, 1); + /* Pass 0 for the rank value here, which indicates this is a + range for the first rank of an array. The assumption is that + this rank value is not actually required for the resolution of + the dynamic range, otherwise, we'd be resolving this range + within the context of a dynamic array. */ + resolved_type = resolve_dynamic_range (type, addr_stack, 0); break; case TYPE_CODE_UNION: diff --git a/gdb/testsuite/gdb.fortran/assumedrank.exp b/gdb/testsuite/gdb.fortran/assumedrank.exp index ac5159c..69cd168 100644 --- a/gdb/testsuite/gdb.fortran/assumedrank.exp +++ b/gdb/testsuite/gdb.fortran/assumedrank.exp @@ -62,21 +62,28 @@ while { $test_count < 500 } { break } - # First grab the expected answer. - set answer [get_valueof "" "rank(answer)" "**unknown**"] - - # Now move up a frame and figure out a command for us to run - # as a test. - set command "" - gdb_test_multiple "up" "up" { - -re -wrap "\r\n\[0-9\]+\[ \t\]+call test_rank (\[^\r\n\]+)" { - set command $expect_out(1,string) + # First grab the information from the assumed rank array. + set answer_rank [get_valueof "" "rank(answer)" "**unknown**"] + set answer_content [get_valueof "" "answer" "**unknown**"] + + # Now move up a frame and find the name of a non-assumed rank array + # which we can use to check the values we got above. + set test_array "" + gdb_test_multiple "up" "" { + -re -wrap "\r\n\[0-9\]+\[ \t\]+call test_rank \\((\[^\r\n\]+)\\)" { + set test_array $expect_out(1,string) } } + gdb_assert { ![string equal $test_array ""] } \ + "found the name of a test array to check against" - gdb_assert { ![string equal $command ""] } "found a command to run" + # Check we got the correct array rank. + gdb_test "p rank($test_array)" " = $answer_rank" - gdb_test "p rank($command)" " = ($answer)" + # Check we got the correct array content. + set content [get_valueof "" "$test_array" "**unknown**"] + gdb_assert { [string equal $content $answer_content] } \ + "answer array contains the expected contents" } } diff --git a/gdb/testsuite/gdb.fortran/assumedrank.f90 b/gdb/testsuite/gdb.fortran/assumedrank.f90 index 16f2ee7..7f077c3 100644 --- a/gdb/testsuite/gdb.fortran/assumedrank.f90 +++ b/gdb/testsuite/gdb.fortran/assumedrank.f90 @@ -24,6 +24,11 @@ PROGRAM arank REAL :: array3(3, 4, 5) REAL :: array4(4, 5, 6, 7) + array1 = 1.0 + array2 = 2.0 + array3 = 3.0 + array4 = 4.0 + call test_rank (array1) call test_rank (array2) call test_rank (array3) |