diff options
author | Ijaz, Abdul B <abdul.b.ijaz@intel.com> | 2024-01-04 15:39:07 +0100 |
---|---|---|
committer | Ijaz, Abdul B <abdul.b.ijaz@intel.com> | 2024-10-29 09:28:41 +0100 |
commit | b0fdcd470653d10612aad561cc06098d3fa5ba17 (patch) | |
tree | 8cc85454b4c6edcb8cd7c1456e1da57656c1e989 /gdb/testsuite/gdb.fortran | |
parent | 287938873c4a001a608349e652e82c2b2da64508 (diff) | |
download | binutils-b0fdcd470653d10612aad561cc06098d3fa5ba17.zip binutils-b0fdcd470653d10612aad561cc06098d3fa5ba17.tar.gz binutils-b0fdcd470653d10612aad561cc06098d3fa5ba17.tar.bz2 |
fortran: Fix arrays of variable length strings for FORTRAN
Before this change resolve_dynamic_array_or_string was called for
all TYPE_CODE_ARRAY and TYPE_CODE_STRING types, but, in the end,
this function always called create_array_type_with_stride, which
creates a TYPE_CODE_ARRAY type.
Suppose we have
subroutine vla_array (arr1, arr2)
character (len=*):: arr1 (:)
character (len=5):: arr2 (:)
print *, arr1 ! break-here
print *, arr2
end subroutine vla_array
The "print arr1" and "print arr2" command at the "break-here" line
gives the following output:
(gdb) print arr1
$1 = <incomplete type>
(gdb) print arr2
$2 = ('abcde', 'abcde', 'abcde')
(gdb) ptype arr1
type = Type
End Type
(gdb) ptype arr2
type = character*5 (3)
Dwarf info using IntelĀ® Fortran Compiler for such case contains following:
<1><fd>: Abbrev Number: 12 (DW_TAG_string_type)
<fe> DW_AT_name : (indirect string, offset: 0xd2): .str.ARR1
<102> DW_AT_string_length: 3 byte block: 97 23 8 (DW_OP_push_object_address; DW_OP_plus_uconst: 8)
After this change resolve_dynamic_array_or_string now calls
create_array_type_with_stride or create_string_type, so if the
incoming dynamic type is a TYPE_CODE_STRING then we'll get back a
TYPE_CODE_STRING type. Now gdb shows following:
(gdb) p arr1
$1 = ('abddefghij', 'abddefghij', 'abddefghij', 'abddefghij', 'abddefghij')
(gdb) p arr2
$2 = ('abcde', 'abcde', 'abcde')
(gdb) ptype arr1
type = character*10 (5)
(gdb) ptype arr2
type = character*5 (3)
In case of GFortran, compiler emits DW_TAG_structure_type for string type
arguments of the subroutine and it has only DW_AT_declaration tag. This
results in <incomplete type> in gdb. So, following issue is raised in gcc
bugzilla "https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101826".
Fixing above issue introduce regression in gdb.fortran/mixed-lang-stack.exp,
i.e. the test forces the language to C/C++ and print a Fortran string value.
The string value is a dynamic type with code TYPE_CODE_STRING.
Before this commit the dynamic type resolution would always convert this to
a TYPE_CODE_ARRAY of characters, which the C value printing could handle.
But now after this commit we get a TYPE_CODE_STRING, which
neither the C value printing, or the generic value printing code can
support. And so, I've added support for TYPE_CODE_STRING to the generic
value printing, all characters of strings are printed together till the
first null character.
Lastly, in gdb.opt/fortran-string.exp and gdb.fortran/string-types.exp
tests it expects type of character array in 'character (3)' format but now
after this change we get 'character*3', so tests are updated accordingly.
Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/testsuite/gdb.fortran')
-rw-r--r-- | gdb/testsuite/gdb.fortran/string-types.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.fortran/vla-array.exp | 60 | ||||
-rw-r--r-- | gdb/testsuite/gdb.fortran/vla-array.f90 | 45 |
3 files changed, 107 insertions, 2 deletions
diff --git a/gdb/testsuite/gdb.fortran/string-types.exp b/gdb/testsuite/gdb.fortran/string-types.exp index 102eaa9..35b8654 100644 --- a/gdb/testsuite/gdb.fortran/string-types.exp +++ b/gdb/testsuite/gdb.fortran/string-types.exp @@ -52,7 +52,7 @@ with_test_prefix "third breakpoint, first time" { # Continue to the third breakpoint. gdb_continue_to_breakpoint "continue" gdb_test "print s" " = 'foo'" - gdb_test "ptype s" "type = character \\(3\\)" + gdb_test "ptype s" "type = character\\*3" } with_test_prefix "third breakpoint, second time" { @@ -65,5 +65,5 @@ with_test_prefix "third breakpoint, second time" { # by most users, so seems good enough. gdb_continue_to_breakpoint "continue" gdb_test "print s" " = 'foo\\\\n\\\\t\\\\r\\\\000bar'" - gdb_test "ptype s" "type = character \\(10\\)" + gdb_test "ptype s" "type = character\\*10" } diff --git a/gdb/testsuite/gdb.fortran/vla-array.exp b/gdb/testsuite/gdb.fortran/vla-array.exp new file mode 100644 index 0000000..4ed2de7 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-array.exp @@ -0,0 +1,60 @@ +# Copyright 2024 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/>. + +standard_testfile ".f90" +load_lib "fortran.exp" + +require allow_fortran_tests + +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug f90 quiet}]} { + return -1 +} + +if ![fortran_runto_main] { + untested "could not run to main" + return -1 +} + +# Try to access vla string / vla string array / string array values. +gdb_breakpoint [gdb_get_line_number "arr_vla1-print"] +gdb_continue_to_breakpoint "arr_vla1-print" + +# GFortran emits DW_TAG_structure_type for strings and it has only +# DW_AT_declaration tag. This results in <incomplete type> in gdb. +if [test_compiler_info "gfortran*" f90] { setup_xfail *-*-* gcc/101826 } +gdb_test "print arr_vla1" \ + " = \\\('vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary', 'vlaaryvlaary'\\\)" \ + "print vla string array" + +if [test_compiler_info "gfortran*" f90] { setup_xfail *-*-* gcc/101826 } +gdb_test "ptype arr_vla1" \ + "type = character\\*12 \\(5\\)" \ + "print variable length string array type" +gdb_test "print arr_vla2" \ + " = 'vlaary'" \ + "print variable length string" +gdb_test "ptype arr_vla2" \ + "type = character\\*6" \ + "print variable length string type" +gdb_test "print arr2" \ + " = \\\('vlaaryvla', 'vlaaryvla', 'vlaaryvla'\\\)" \ + "print string array" +gdb_test "ptype arr2" \ + "type = character\\*9 \\(3\\)" \ + "print string array type" +gdb_test "print rank(arr_vla1)" \ + "$decimal" \ + "print string array rank" diff --git a/gdb/testsuite/gdb.fortran/vla-array.f90 b/gdb/testsuite/gdb.fortran/vla-array.f90 new file mode 100644 index 0000000..56dd85b --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-array.f90 @@ -0,0 +1,45 @@ +! Copyright 2024 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/>. + +subroutine vla_array_func (arr_vla1, arr_vla2, arr2) + character (len=*):: arr_vla1 (:) + character (len=*):: arr_vla2 + character (len=9):: arr2 (:) + + print *, arr_vla1 ! arr_vla1-print + print *, arr_vla2 + print *, arr2 + print *, rank(arr_vla1) +end subroutine vla_array_func + +program vla_array_main +interface + subroutine vla_array_func (arr_vla1, arr_vla2, arr2) + character (len=*):: arr_vla1 (:) + character (len=*):: arr_vla2 + character (len=9):: arr2 (:) + end subroutine vla_array_func +end interface + character (len=9) :: arr1 (3) + character (len=6) :: arr2 + character (len=12) :: arr3 (5) + + arr1 = 'vlaaryvla' + arr2 = 'vlaary' + arr3 = 'vlaaryvlaary' + + call vla_array_func (arr3, arr2, arr1) + +end program vla_array_main |