1 # Copyright 2020-2024 Free Software Foundation, Inc. 2 3 # This program is free software; you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation; either version 3 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program. If not, see <http://www.gnu.org/licenses/> . 15 16 # Create a slice of an array, then take a slice of that slice. 17 18 require allow_fortran_tests 19 20 standard_testfile ".f90" 21 load_lib fortran.exp 22 23 if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ 24 {debug f90}]} { 25 return -1 26 } 27 28 if ![fortran_runto_main] { 29 return -1 30 } 31 32 # Avoid libc symbols, in particular the 'array' type. 33 gdb_test_no_output "nosharedlibrary" 34 35 # gdb_breakpoint [gdb_get_line_number "Display Message Breakpoint"] 36 gdb_breakpoint [gdb_get_line_number "Stop Here"] 37 gdb_breakpoint [gdb_get_line_number "Final Breakpoint"] 38 39 # We're going to print some reasonably large arrays. 40 gdb_test_no_output "set print elements unlimited" 41 42 gdb_continue_to_breakpoint "Stop Here" 43 44 # Print a slice, capture the convenience variable name created. 45 set cmd "print array (1:10:2, 1:10:2)" 46 gdb_test_multiple $cmd $cmd { 47 -re "\r\n\\\$(\\d+) = .*\r\n$gdb_prompt $" { 48 set varname "\$$expect_out(1,string)" 49 } 50 } 51 52 # Now check that we can correctly extract all the elements from this 53 # slice. 54 for { set j 1 } { $j < 6 } { incr j } { 55 for { set i 1 } { $i < 6 } { incr i } { 56 set val [expr ((($i - 1) * 2) + (($j - 1) * 20)) + 1] 57 gdb_test "print ${varname} ($i,$j)" " = $val" 58 } 59 } 60 61 # Now take a slice of the slice. 62 gdb_test "print ${varname} (3:5, 3:5)" \ 63 " = \\(\\(45, 47, 49\\) \\(65, 67, 69\\) \\(85, 87, 89\\)\\)" 64 65 # Now take a different slice of a slice. 66 set cmd "print ${varname} (1:5:2, 1:5:2)" 67 gdb_test_multiple $cmd $cmd { 68 -re "\r\n\\\$(\\d+) = \\(\\(1, 5, 9\\) \\(41, 45, 49\\) \\(81, 85, 89\\)\\)\r\n$gdb_prompt $" { 69 set varname "\$$expect_out(1,string)" 70 pass $gdb_test_name 71 } 72 } 73 74 # Now take a slice from the slice, of a slice! 75 set cmd "print ${varname} (1:3:2, 1:3:2)" 76 gdb_test_multiple $cmd $cmd { 77 -re "\r\n\\\$(\\d+) = \\(\\(1, 9\\) \\(81, 89\\)\\)\r\n$gdb_prompt $" { 78 set varname "\$$expect_out(1,string)" 79 pass $gdb_test_name 80 } 81 } 82 83 # And again! 84 set cmd "print ${varname} (1:2:2, 1:2:2)" 85 gdb_test_multiple $cmd $cmd { 86 -re "\r\n\\\$(\\d+) = \\(\\(1\\)\\)\r\n$gdb_prompt $" { 87 set varname "\$$expect_out(1,string)" 88 pass $gdb_test_name 89 } 90 } 91 92 # Test taking a slice with stride of a string. This isn't actually 93 # supported within gfortran (at least), but naturally drops out of how 94 # GDB models arrays and strings in a similar way, so we may as well 95 # test that this is still working. 96 gdb_test "print str (1:26:2)" " = 'acegikmoqsuwy'" 97 gdb_test "print str (26:1:-1)" " = 'zyxwvutsrqponmlkjihgfedcba'" 98 gdb_test "print str (26:1:-2)" " = 'zxvtrpnljhfdb'" 99 100 # Now test the memory requirements of taking a slice from an array. 101 # The idea is that we shouldn't require more memory to extract a slice 102 # than the size of the slice. 103 # 104 # This will only work if array repacking is turned on, otherwise GDB 105 # will create the slice by generating a new type that sits over the 106 # existing value in memory. 107 gdb_test_no_output "set fortran repack-array-slices on" 108 set element_size [get_integer_valueof "sizeof (array (1,1))" "unknown"] 109 set slice_size [expr $element_size * 4] 110 gdb_test_no_output "set max-value-size $slice_size" 111 gdb_test "print array (1:2, 1:2)" "= \\(\\(1, 2\\) \\(11, 12\\)\\)" 112 gdb_test "print array (2:3, 2:3)" "= \\(\\(12, 13\\) \\(22, 23\\)\\)" 113 gdb_test "print array (2:5:2, 2:5:2)" "= \\(\\(12, 14\\) \\(32, 34\\)\\)" 114