[commit/Ada] Fix 'address of array subscript

Joel Brobecker brobecker@adacore.com
Wed Jan 2 12:18:00 GMT 2008


The attached patch fixes a problem when trying to take the address
of an element inside an array, like so:

    (gdb) p a(2)'Address
    Attempt to take address of non-lval

The expected behavior is to return address of that array element:

    (gdb) print a(2)'Address
    $1 = (system.address) 0xbf8e00ec

The problem was happing during the EVAL_AVOID_SIDE_EFFECTS pass,
because were were creating non-lval value thinking that it would
be enough for the EVAL_AVOID_SIDE_EFFECTS pass. However, this turned
out to be too limited, as subsequent operations on the result might
fail because they require a lval value.

Fixed with the attached patch.

2008-01-02  Joel Brobecker  <brobecker@adacore.com>

        * ada-lang.c (ada_evaluate_subexp): Modify the value returned
        when noside is EVAL_AVOID_SIDE_EFFECTS to be an lval_memory.
        This is needed to make sure that any other treatment applied
        to the resulting value does not fail for spurious reason,
        such as trying to take the address of this value.

I also wrote a new testcase:

2008-01-02  Joel Brobecker  <brobecker@adacore.com>

        * array_subscript_addr/p.adb: New file.
        * array_subscript_addr.exp: New testcase. 

All tested on x86-linux. No regression. Checked in.

-- 
Joel
-------------- next part --------------
Index: ada-lang.c
===================================================================
--- ada-lang.c	(revision 42)
+++ ada-lang.c	(revision 43)
@@ -9578,7 +9578,7 @@ ada_evaluate_subexp (struct type *expect
             if (arity != nargs)
               error (_("wrong number of subscripts; expecting %d"), arity);
             if (noside == EVAL_AVOID_SIDE_EFFECTS)
-              return allocate_value (ada_aligned_type (type));
+              return value_zero (ada_aligned_type (type), lval_memory);
             return
               unwrap_value (ada_value_subscript
                             (argvec[0], nargs, argvec + 1));
@@ -9590,7 +9590,7 @@ ada_evaluate_subexp (struct type *expect
               if (type == NULL)
                 error (_("element type of array unknown"));
               else
-                return allocate_value (ada_aligned_type (type));
+                return value_zero (ada_aligned_type (type), lval_memory);
             }
           return
             unwrap_value (ada_value_subscript
@@ -9604,7 +9604,7 @@ ada_evaluate_subexp (struct type *expect
               if (type == NULL)
                 error (_("element type of array unknown"));
               else
-                return allocate_value (ada_aligned_type (type));
+                return value_zero (ada_aligned_type (type), lval_memory);
             }
           return
             unwrap_value (ada_value_ptr_subscript (argvec[0], type,
-------------- next part --------------
Index: gdb.ada/array_subscript_addr.exp
===================================================================
--- gdb.ada/array_subscript_addr.exp	(revision 0)
+++ gdb.ada/array_subscript_addr.exp	(revision 44)
@@ -0,0 +1,45 @@
+# Copyright 2008 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/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+load_lib "ada.exp"
+
+set testdir "array_subscript_addr"
+set testfile "${testdir}/p"
+set srcfile ${srcdir}/${subdir}/${testfile}.adb
+set binfile ${objdir}/${subdir}/${testfile}
+
+file mkdir ${objdir}/${subdir}/${testdir}
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } {
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/p.adb]
+runto "p.adb:$bp_location"
+
+# Verify that we can compare a string slice with another string.
+
+gdb_test "print a(2)'Address" \
+         "\\(system\\.address\\) 0x\[0-9a-fA-F\]+" \
+         "print a(2)'Address"
+
Index: gdb.ada/array_subscript_addr/p.adb
===================================================================
--- gdb.ada/array_subscript_addr/p.adb	(revision 0)
+++ gdb.ada/array_subscript_addr/p.adb	(revision 44)
@@ -0,0 +1,29 @@
+--  Copyright 2008 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/>.
+
+procedure P is
+   type Table is array (1 .. 3) of Integer;
+
+   function Create (I : Integer) return Table is
+   begin
+      return (4 + I, 8 * I, 7 * I + 4);
+   end Create;
+
+   A : Table := Create (7);
+   C : Integer;
+begin
+   C := A (1) + A (2);  -- STOP
+end P;
+


More information about the Gdb-patches mailing list