diff options
author | Joel Brobecker <brobecker@adacore.com> | 2013-11-27 17:42:24 +0400 |
---|---|---|
committer | Joel Brobecker <brobecker@adacore.com> | 2013-12-13 09:55:24 +0100 |
commit | 8a48ac9579f34efea9bc4f2d5b02230e2ac3dfc1 (patch) | |
tree | 45accfbd397324a64c302499d1f743419ee8091f /gdb/ada-lang.c | |
parent | fb5e3d5c693cf9d56188a0ebd7ead5eba99bfdb4 (diff) | |
download | gdb-8a48ac9579f34efea9bc4f2d5b02230e2ac3dfc1.zip gdb-8a48ac9579f34efea9bc4f2d5b02230e2ac3dfc1.tar.gz gdb-8a48ac9579f34efea9bc4f2d5b02230e2ac3dfc1.tar.bz2 |
wrong dimension found in ada-lang.c:ada_array_bound_from_type
This function has the following code:
elt_type = type;
for (i = n; i > 1; i--)
elt_type = TYPE_TARGET_TYPE (type);
For multi-dimension arrays, the code above tries to find the array
type corresponding to the dimension we're trying to inspect.
The problem is that, past the second dimension, the loop does
nothing other than repeat the first iteration. There is a little
thinko where it got the TYPE_TARGET_TYPE of TYPE instead of ELT_TYPE!
To my surprise, I was unable to produce an Ada exemple that demonstrated
the problem. That's because the examples I created all trigger a parallel
___XA type which we then use in place of the ELT_TYPE in order to
determine the bounds - see the code that immediately follows our
loop above:
index_type_desc = ada_find_parallel_type (type, "___XA");
ada_fixup_array_indexes_type (index_type_desc);
if (index_type_desc != NULL)
[...]
So, in order to avoid depending on an Ada example where the compiler
can potentially decide one way or the other, I decided to use an
artificial example, written in C. With ...
int multi[1][2][3];
... forcing the language to Ada, and trying to print the 'last,
we get:
(gdb) p multi'last(1)
$1 = 0
(gdb) p multi'last(2)
$2 = 1
(gdb) p multi'last(3)
$3 = 1 <<<--- This should be 2!
Additionally, I noticed that a couple of check_typedef's were missing.
This patch adds them. And since the variable in question only gets
used within an "else" block, I moved the variable declaration and
use inside that block - making it clear what the scope of the variable
is.
gdb/ChangeLog:
* ada-lang.c (ada_array_bound_from_type): Move the declaration
and assignment of variable "elt_type" inside the else block
where it is used. Add two missing check_typedef calls.
Fix bug where we got TYPE's TYPE_TARGET_TYPE, where in fact
we really wanted to get ELT_TYPE's TYPE_TARGET_TYPE.
gdb/testsuite/ChangeLog:
* gdb.ada/arraydim: New testcase.
Diffstat (limited to 'gdb/ada-lang.c')
-rw-r--r-- | gdb/ada-lang.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 19ddf5d..a0d6715 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -2790,7 +2790,7 @@ ada_index_type (struct type *type, int n, const char *name) static LONGEST ada_array_bound_from_type (struct type *arr_type, int n, int which) { - struct type *type, *elt_type, *index_type_desc, *index_type; + struct type *type, *index_type_desc, *index_type; int i; gdb_assert (which == 0 || which == 1); @@ -2806,17 +2806,20 @@ ada_array_bound_from_type (struct type *arr_type, int n, int which) else type = arr_type; - elt_type = type; - for (i = n; i > 1; i--) - elt_type = TYPE_TARGET_TYPE (type); - index_type_desc = ada_find_parallel_type (type, "___XA"); ada_fixup_array_indexes_type (index_type_desc); if (index_type_desc != NULL) index_type = to_fixed_range_type (TYPE_FIELD_TYPE (index_type_desc, n - 1), NULL); else - index_type = TYPE_INDEX_TYPE (elt_type); + { + struct type *elt_type = check_typedef (type); + + for (i = 1; i < n; i++) + elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type)); + + index_type = TYPE_INDEX_TYPE (elt_type); + } return (LONGEST) (which == 0 |