gdb: Check element of optimised out vla exists
authorAndrew Burgess <andrew.burgess@embecosm.com>
Wed, 25 Jul 2018 16:33:08 +0000 (17:33 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 9 Aug 2018 16:17:35 +0000 (17:17 +0100)
If a vla is not in memory, and the upper bound is not defined, then we
can't know that an array element exists or not, and we should not try
to access the array element.  One case where this happens is for
arrays that have been optimised out, the array will then have
VALUE_LVAL of not_lval, and an undefined upper bound, if we then try
to access an element of this array we will index into random GDB
memory.

An argument could be made that even for arrays that are in inferior
memory, if the upper bound is not defined then we should not try to
access the array element, however, in some of the Fortran tests, it
seems as though we do rely indexing from a base address into an array
which has no bounds defined.  In this case GDBs standard protection
for detecting unreadable target memory prevents bad thing happening.

gdb/ChangeLog:

* valarith.c (value_subscripted_rvalue): If an array is not in
memory, and we don't know the upper bound, then we can't know that
the requested element exists or not.

gdb/testsuite/ChangeLog:

* gdb.base/vla-optimized-out.exp: Add new test.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/vla-optimized-out.exp
gdb/valarith.c

index 4d0593f163044eff20cc0e2eb833df8f0881362c..ebe1747ff0fed19e7f9548b13bf30e82f1af4606 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-09  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * valarith.c (value_subscripted_rvalue): If an array is not in
+       memory, and we don't know the upper bound, then we can't know that
+       the requested element exists or not.
+
 2018-08-08  Simon Marchi  <simon.marchi@ericsson.com>
 
        * target.c (str_comma_list_concat_elem): Fix typo in comment.
index 975705da10abe6daf1e42165b1a50918d78bb094..bd3c3bfec5f18763c874856df2993794ea25bfca 100644 (file)
@@ -1,3 +1,7 @@
+2018-08-09  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * gdb.base/vla-optimized-out.exp: Add new test.
+
 2018-08-09  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.base/vla-optimized-out-o3.exp: Delete.
index 298b689bfbf200fff67d1c7bcb8821dd0f9823f9..88c6fac9b988cbefb30adaf7ba1dd276b26a7370 100644 (file)
@@ -44,6 +44,28 @@ proc vla_optimized_out {exe_suffix options} {
     gdb_test "p sizeof (a)" \
        " = $sizeof_result" \
        "printed size of optimized out vla"
+
+    # At lower optimisation levels, the upper bound of the array is
+    # still defined, it's just the loctaion that tells GDB the array
+    # is optimised out.  In that case, when we access an element that
+    # is within the bounds of the array an answer of '<optimized out>'
+    # is reasonable.
+    #
+    # At higher optimisation levels, the array bounds themselves have
+    # been removed.  As such GDB can't be expected to know if the
+    # array contains _any_ elements at all.  It seems reasonable in
+    # that case to reply with 'no such vector element'.
+    gdb_test "p a\[0\]" \
+       "(= <optimized out>|no such vector element)" \
+       "print out of range element of vla (0)"
+
+    gdb_test "p a\[6\]" \
+       "no such vector element" \
+       "print out of range element of vla (6)"
+
+    gdb_test "p a\[0xffffffff\]" \
+       "no such vector element" \
+       "print out of range element of vla (0xffffffff)"
 }
 
 foreach {test_prefix options} \
index 01ca50d3d21429eb3ddec6f69cb2a94f6b5353d8..807cdd5dbd4d1e2a4def2d08ab739010e3dcc53e 100644 (file)
@@ -189,8 +189,11 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
   ULONGEST elt_size = type_length_units (elt_type);
   ULONGEST elt_offs = elt_size * (index - lowerbound);
 
-  if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
-                            && elt_offs >= type_length_units (array_type)))
+  if (index < lowerbound
+      || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)
+          && elt_offs >= type_length_units (array_type))
+      || (VALUE_LVAL (array) != lval_memory
+          && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type)))
     {
       if (type_not_associated (array_type))
         error (_("no such vector element (vector not associated)"));