From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.151]) by sourceware.org (Postfix) with ESMTPS id CCD6A3858C20 for ; Mon, 4 Sep 2023 22:30:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CCD6A3858C20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693866624; x=1725402624; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i1h0CzA5GuJeKFPoTNAz3mD3SzIQOLjlOdeUnsGMZAw=; b=oFZfjEwEZGyFFl6bQ2ttziMZ25bkaKbYMHS+xYZJkJoEomu/9mhU4bbU 4GqdzuVX2gnx53b45XxIP2XWeFIhXGX9yHIgIbrxMrtM1dcW/3G/+g25w Ntzw0yJYqyXCqwyu/Ekf7MJq75McAssZuzuVzcCZ3GtZsYpcyC1jT7fhu VLNaxLGYog05Vg1SPJuyz2zH+V6liralFV6DiuY1DKn4XOUJPCMGxDroe PPVLAo/xiJ0RCJprieCRy5FA9B9dXhsL7vdCV8fXO8A4qPtHLl2NQSHfg 925rbuUJYew+X9aso0Yigah279r0dMmJXkuGPfCbxKGF4kOoVSGCjhZpB Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10823"; a="356973336" X-IronPort-AV: E=Sophos;i="6.02,227,1688454000"; d="scan'208";a="356973336" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Sep 2023 15:30:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10823"; a="884109272" X-IronPort-AV: E=Sophos;i="6.02,227,1688454000"; d="scan'208";a="884109272" Received: from abijaz-mobl2.ger.corp.intel.com (HELO localhost) ([10.252.60.194]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Sep 2023 15:30:16 -0700 From: Abdul Basit Ijaz To: gdb-patches@sourceware.org Cc: abdul.b.ijaz@intel.com, simark@simark.ca, tom@tromey.com Subject: [PATCH v3 2/4] gdb, types: Resolve pointer types dynamically Date: Tue, 5 Sep 2023 00:29:54 +0200 Message-Id: <20230904222956.15203-3-abdul.b.ijaz@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230904222956.15203-1-abdul.b.ijaz@intel.com> References: <20230904222956.15203-1-abdul.b.ijaz@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: "Ijaz, Abdul B" This commit allows pointers to be dynamic types (on the outmost level). Similar to references, a pointer is considered a dynamic type if its target type is a dynamic type and it is on the outmost level. The pointer resolution follows the one of references. This generally makes the GDB output more verbose. We are able to print more details about a pointer's target like the dimension of an array. In Fortran, if we have a pointer to a dynamic type type buffer real, dimension(:), pointer :: ptr end type buffer type(buffer), pointer :: buffer_ptr allocate (buffer_ptr) allocate (buffer_ptr%ptr (5)) which then gets allocated, we now resolve the dynamic type before printing the pointer's type: Before: (gdb) ptype buffer_ptr type = PTR TO -> ( Type buffer real(kind=4) :: alpha(:) End Type buffer ) After: (gdb) ptype buffer_ptr type = PTR TO -> ( Type buffer real(kind=4) :: alpha(5) End Type buffer ) Similarly in C++ we can dynamically resolve e.g. pointers to arrays: int len = 3; int arr[len]; int (*ptr)[len]; int ptr = &arr; Once the pointer is assigned one gets: Before: (gdb) p ptr $1 = (int (*)[variable length]) 0x123456 (gdb) ptype ptr type = int (*)[variable length] After: (gdb) p ptr $1 = (int (*)[3]) 0x123456 (gdb) ptype ptr type = int (*)[3] For more examples see the modified/added test cases. --- gdb/gdbtypes.c | 7 +- gdb/testsuite/gdb.cp/vla-cxx.cc | 4 + gdb/testsuite/gdb.cp/vla-cxx.exp | 15 +++ gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp | 16 +-- .../gdb.fortran/pointer-to-pointer.exp | 2 +- gdb/testsuite/gdb.fortran/pointers.exp | 115 ++++++++++++++++++ gdb/testsuite/gdb.fortran/pointers.f90 | 29 +++++ gdb/valprint.c | 6 - 8 files changed, 177 insertions(+), 17 deletions(-) create mode 100644 gdb/testsuite/gdb.fortran/pointers.exp diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5e15ec64c41..4b1787b62e6 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2038,8 +2038,10 @@ is_dynamic_type_internal (struct type *type, int top_level) { type = check_typedef (type); - /* We only want to recognize references at the outermost level. */ - if (top_level && type->code () == TYPE_CODE_REF) + /* We only want to recognize references and pointers at the outermost + level. */ + if (top_level + && (type->code () == TYPE_CODE_REF || type->code () == TYPE_CODE_PTR)) type = check_typedef (type->target_type ()); /* Types that have a dynamic TYPE_DATA_LOCATION are considered @@ -2775,6 +2777,7 @@ resolve_dynamic_type_internal (struct type *type, switch (type->code ()) { case TYPE_CODE_REF: + case TYPE_CODE_PTR: { struct property_addr_info pinfo; diff --git a/gdb/testsuite/gdb.cp/vla-cxx.cc b/gdb/testsuite/gdb.cp/vla-cxx.cc index 0ecb130f676..83e238339ac 100644 --- a/gdb/testsuite/gdb.cp/vla-cxx.cc +++ b/gdb/testsuite/gdb.cp/vla-cxx.cc @@ -40,6 +40,10 @@ int main(int argc, char **argv) typedef typeof (vla) &vlareftypedef; vlareftypedef vlaref2 (vla); container c; + typeof (vla) *ptr = nullptr; + + // Before pointer assignment. + ptr = &vla; for (int i = 0; i < z; ++i) vla[i] = 5 + 2 * i; diff --git a/gdb/testsuite/gdb.cp/vla-cxx.exp b/gdb/testsuite/gdb.cp/vla-cxx.exp index 0a588220679..ade688cedda 100644 --- a/gdb/testsuite/gdb.cp/vla-cxx.exp +++ b/gdb/testsuite/gdb.cp/vla-cxx.exp @@ -23,6 +23,18 @@ if ![runto_main] { return -1 } +gdb_breakpoint [gdb_get_line_number "Before pointer assignment"] +gdb_continue_to_breakpoint "Before pointer assignment" + +gdb_test "ptype ptr" "= int \\(\\*\\)\\\[3\\\]" \ + "ptype ptr, before pointer assignment" + +gdb_test "print ptr" "= \\(int \\(\\*\\)\\\[3\\\]\\) 0x0" \ + "print ptr, before pointer assignment" + +gdb_test "print *ptr" "Cannot access memory at address 0x0" \ + "print *ptr, before pointer assignment" + gdb_breakpoint [gdb_get_line_number "vlas_filled"] gdb_continue_to_breakpoint "vlas_filled" @@ -33,3 +45,6 @@ gdb_test "print vlaref" " = \\(int \\(&\\)\\\[3\\\]\\) @$hex: \\{5, 7, 9\\}" # bug being tested, it's better not to depend on the exact spelling. gdb_test "print vlaref2" " = \\(.*\\) @$hex: \\{5, 7, 9\\}" gdb_test "print c" " = \\{e = \\{c = @$hex\\}\\}" +gdb_test "ptype ptr" "int \\(\\*\\)\\\[3\\\]" +gdb_test "print ptr" "\\(int \\(\\*\\)\\\[3\\\]\\) $hex" +gdb_test "print *ptr" " = \\{5, 7, 9\\}" diff --git a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp index 6e4a331eca8..d6b20086c89 100644 --- a/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp +++ b/gdb/testsuite/gdb.dwarf2/dynarr-ptr.exp @@ -154,7 +154,7 @@ gdb_test "print foo.three_ptr.all'length" \ " = 3" gdb_test "ptype foo.three_ptr.all" \ - " = array \\(<>\\) of integer" + " = array \\(1 \\.\\. 3\\) of integer" # foo.three_ptr @@ -177,7 +177,7 @@ gdb_test "print foo.three_ptr'length" \ " = 3" gdb_test "ptype foo.three_ptr" \ - " = access array \\(<>\\) of integer" + " = access array \\(1 \\.\\. 3\\) of integer" # foo.three_ptr_tdef.all @@ -203,7 +203,7 @@ gdb_test "print foo.three_ptr_tdef.all'length" \ " = 3" gdb_test "ptype foo.three_ptr_tdef.all" \ - " = array \\(<>\\) of integer" + " = array \\(1 \\.\\. 3\\) of integer" # foo.three_ptr_tdef @@ -226,7 +226,7 @@ gdb_test "print foo.three_ptr_tdef'length" \ " = 3" gdb_test "ptype foo.three_ptr_tdef" \ - " = access array \\(<>\\) of integer" + " = access array \\(1 \\.\\. 3\\) of integer" # foo.five_ptr.all @@ -258,7 +258,7 @@ gdb_test "print foo.five_ptr.all'length" \ " = 5" gdb_test "ptype foo.five_ptr.all" \ - " = array \\(<>\\) of integer" + " = array \\(2 \\.\\. 6\\) of integer" # foo.five_ptr @@ -287,7 +287,7 @@ gdb_test "print foo.five_ptr'length" \ " = 5" gdb_test "ptype foo.five_ptr" \ - " = access array \\(<>\\) of integer" + " = access array \\(2 \\.\\. 6\\) of integer" # foo.five_ptr_tdef.all @@ -319,7 +319,7 @@ gdb_test "print foo.five_ptr_tdef.all'length" \ " = 5" gdb_test "ptype foo.five_ptr_tdef.all" \ - " = array \\(<>\\) of integer" + " = array \\(2 \\.\\. 6\\) of integer" # foo.five_ptr_tdef @@ -348,4 +348,4 @@ gdb_test "print foo.five_ptr_tdef'length" \ " = 5" gdb_test "ptype foo.five_ptr_tdef" \ - " = access array \\(<>\\) of integer" + " = access array \\(2 \\.\\. 6\\) of integer" diff --git a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp index 0fd5fb0996f..78b7ba17588 100644 --- a/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp +++ b/gdb/testsuite/gdb.fortran/pointer-to-pointer.exp @@ -41,7 +41,7 @@ gdb_test "print buffer" \ gdb_test "ptype buffer" \ [multi_line \ "type = PTR TO -> \\( Type l_buffer" \ - " $real4 :: alpha\\(:\\)" \ + " $real4 :: alpha\\(5\\)" \ "End Type l_buffer \\)" ] gdb_test "ptype buffer%alpha" "type = $real4 \\(5\\)" diff --git a/gdb/testsuite/gdb.fortran/pointers.exp b/gdb/testsuite/gdb.fortran/pointers.exp new file mode 100644 index 00000000000..ca2195bbfe6 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/pointers.exp @@ -0,0 +1,115 @@ +# Copyright 2016-2023 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 . + +standard_testfile "pointers.f90" +load_lib fortran.exp + +if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}]} { + return -1 +} + +if {![fortran_runto_main]} { + untested "could not run to main" + return -1 +} + +# Depending on the compiler being used, the type names can be printed +# differently. +set logical [fortran_logical4] +set real [fortran_real4] +set int [fortran_int4] +set complex [fortran_complex4] + +gdb_breakpoint [gdb_get_line_number "Before pointer assignment"] +gdb_continue_to_breakpoint "Before pointer assignment" +gdb_test "print logp" "= \\(PTR TO -> \\( $logical \\)\\) 0x0" \ + "print logp, not associated" +gdb_test "print *logp" "Cannot access memory at address 0x0" \ + "print *logp, not associated" +gdb_test "print comp" "= \\(PTR TO -> \\( $complex \\)\\) 0x0" \ + "print comp, not associated" +gdb_test "print *comp" "Cannot access memory at address 0x0" \ + "print *comp, not associated" +gdb_test "print charp" "= \\(PTR TO -> \\( character\\*1 \\)\\) 0x0" \ + "print charp, not associated" +gdb_test "print *charp" "Cannot access memory at address 0x0" \ + "print *charp, not associated" +gdb_test "print charap" "= \\(PTR TO -> \\( character\\*3 \\)\\) 0x0" \ + "print charap, not associated" +gdb_test "print *charap" "Cannot access memory at address 0x0" \ + "print *charap, not associated" +gdb_test "print intp" "= \\(PTR TO -> \\( $int \\)\\) 0x0" \ + "print intp, not associated" +gdb_test "print *intp" "Cannot access memory at address 0x0" \ + "print *intp, not associated" +gdb_test "print intap" " = " "print intap, not associated" +gdb_test "print realp" "= \\(PTR TO -> \\( $real \\)\\) 0x0" \ + "print realp, not associated" +gdb_test "print *realp" "Cannot access memory at address 0x0" \ + "print *realp, not associated" +gdb_test "print \$my_var = intp" "= \\(PTR TO -> \\( $int \\)\\) 0x0" +gdb_test "print cyclicp1" "= \\( i = -?\\d+, p = 0x0 \\)" \ + "print cyclicp1, not associated" +gdb_test "print cyclicp1%p" \ + "= \\(PTR TO -> \\( Type typewithpointer \\)\\) 0x0" \ + "print cyclicp1%p, not associated" + +gdb_breakpoint [gdb_get_line_number "Before value assignment"] +gdb_continue_to_breakpoint "Before value assignment" +gdb_test "print *(twop)%ivla2" "= " + +gdb_breakpoint [gdb_get_line_number "After value assignment"] +gdb_continue_to_breakpoint "After value assignment" +gdb_test "print logp" "= \\(PTR TO -> \\( $logical \\)\\) $hex\( <.*>\)?" +gdb_test "print *logp" "= \\.TRUE\\." +gdb_test "print comp" "= \\(PTR TO -> \\( $complex \\)\\) $hex\( <.*>\)?" +gdb_test "print *comp" "= \\(1,2\\)" +gdb_test "print charp" "= \\(PTR TO -> \\( character\\*1 \\)\\) $hex\( <.*>\)?" +gdb_test "print *charp" "= 'a'" +gdb_test "print charap" "= \\(PTR TO -> \\( character\\*3 \\)\\) $hex\( <.*>\)?" +gdb_test "print *charap" "= 'abc'" +gdb_test "print intp" "= \\(PTR TO -> \\( $int \\)\\) $hex\( <.*>\)?" +gdb_test "print *intp" "= 10" +gdb_test "print intap" "= \\(\\(1, 1, 3(, 1){7}\\) \\(1(, 1){9}\\)\\)" \ + "print intap, associated" +gdb_test "print intvlap" "= \\(2, 2, 2, 4(, 2){6}\\)" \ + "print intvlap, associated" +gdb_test "print realp" "= \\(PTR TO -> \\( $real \\)\\) $hex\( <.*>\)?" +gdb_test "print *realp" "= 3\\.14000\\d+" +gdb_test "print arrayOfPtr(2)%p" "= \\(PTR TO -> \\( Type two \\)\\) $hex\( <.*>\)?" +gdb_test "print *(arrayOfPtr(2)%p)" \ + "= \\( ivla1 = \\(11, 12, 13\\), ivla2 = \\(\\(211, 221\\) \\(212, 222\\)\\) \\)" +gdb_test "print arrayOfPtr(3)%p" "= \\(PTR TO -> \\( Type two \\)\\) 0x0" \ + "print arrayOfPtr(3)%p" + +gdb_test_multiple "print *(arrayOfPtr(3)%p)" \ + "print *(arrayOfPtr(3)%p), associated" { + # gfortran + -re -wrap "Cannot access memory at address 0x0" { + pass $gdb_test_name + } + # ifx + -re -wrap "Location address is not set." { + pass $gdb_test_name + } +} + +gdb_test "print cyclicp1" "= \\( i = 1, p = $hex\( <.*>\)? \\)" +gdb_test "print cyclicp1%p" "= \\(PTR TO -> \\( Type typewithpointer \\)\\) $hex\( <.*>\)?" +gdb_test "print *((integer*) &inta + 2)" "= 3" "print temporary pointer, array" +gdb_test "print *((integer*) &intvla + 3)" "= 4" "print temporary pointer, allocated vla" +gdb_test "print \$pc" "\\(PTR TO -> \\( void \\(\\) \\(\\) \\)\\) $hex " \ + "Print program counter" diff --git a/gdb/testsuite/gdb.fortran/pointers.f90 b/gdb/testsuite/gdb.fortran/pointers.f90 index 8708d505ada..0fb6b36a25c 100644 --- a/gdb/testsuite/gdb.fortran/pointers.f90 +++ b/gdb/testsuite/gdb.fortran/pointers.f90 @@ -20,14 +20,26 @@ program pointers integer, allocatable :: ivla2 (:, :) end type two + type :: typeWithPointer + integer i + type(typeWithPointer), pointer:: p + end type typeWithPointer + + type :: twoPtr + type (two), pointer :: p + end type twoPtr + logical, target :: logv complex, target :: comv character, target :: charv character (len=3), target :: chara integer, target :: intv integer, target, dimension (10,2) :: inta + integer, target, allocatable, dimension (:) :: intvla real, target :: realv type(two), target :: twov + type(twoPtr) :: arrayOfPtr (3) + type(typeWithPointer), target:: cyclicp1,cyclicp2 logical, pointer :: logp complex, pointer :: comp @@ -35,6 +47,7 @@ program pointers character (len=3), pointer :: charap integer, pointer :: intp integer, pointer, dimension (:,:) :: intap + integer, pointer, dimension (:) :: intvlap real, pointer :: realp type(two), pointer :: twop @@ -44,8 +57,14 @@ program pointers nullify (charap) nullify (intp) nullify (intap) + nullify (intvlap) nullify (realp) nullify (twop) + nullify (arrayOfPtr(1)%p) + nullify (arrayOfPtr(2)%p) + nullify (arrayOfPtr(3)%p) + nullify (cyclicp1%p) + nullify (cyclicp2%p) logp => logv ! Before pointer assignment comp => comv @@ -53,8 +72,14 @@ program pointers charap => chara intp => intv intap => inta + intvlap => intvla realp => realv twop => twov + arrayOfPtr(2)%p => twov + cyclicp1%i = 1 + cyclicp1%p => cyclicp2 + cyclicp2%i = 2 + cyclicp2%p => cyclicp1 logv = associated(logp) ! Before value assignment comv = cmplx(1,2) @@ -63,6 +88,10 @@ program pointers intv = 10 inta(:,:) = 1 inta(3,1) = 3 + allocate (intvla(10)) + intvla(:) = 2 + intvla(4) = 4 + intvlap => intvla realv = 3.14 allocate (twov%ivla1(3)) diff --git a/gdb/valprint.c b/gdb/valprint.c index b65dda15c04..c71ae089f46 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1156,12 +1156,6 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } - if (type_not_associated (val->type ())) - { - val_print_not_associated (stream); - return 0; - } - if (type_not_allocated (val->type ())) { val_print_not_allocated (stream); -- 2.34.1 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928