mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-12 12:16:04 +08:00
9704b8b4bc
It is not necessary to call get_compiler_info before calling test_compiler_info, and, after recent commits that removed setting up the gcc_compiled, true, and false globals from get_compiler_info, there is now no longer any need for any test script to call get_compiler_info directly. As a result every call to get_compiler_info outside of lib/gdb.exp is redundant, and this commit removes them all. There should be no change in what is tested after this commit.
631 lines
18 KiB
Plaintext
631 lines
18 KiB
Plaintext
# Copyright 1998-2022 Free Software Foundation, Inc.
|
|
|
|
# This file is part of the gdb testsuite
|
|
|
|
# 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/>.
|
|
|
|
# Tests for pointer-to-member support
|
|
# Written by Satish Pai <pai@apollo.hp.com> 1997-08-19
|
|
# Rewritten by Michael Chastain <mec.gnu@mindspring.com> 2004-01-11
|
|
|
|
set vhn "\\$\[0-9\]+"
|
|
|
|
if { [skip_cplus_tests] } { return }
|
|
|
|
|
|
standard_testfile .cc
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] then {
|
|
perror "couldn't run to breakpoint"
|
|
return
|
|
}
|
|
|
|
gdb_breakpoint [gdb_get_line_number "Breakpoint 1 here"]
|
|
gdb_continue_to_breakpoint "continue to pmi = NULL"
|
|
|
|
# ======================
|
|
# pointer to member data
|
|
# ======================
|
|
|
|
# ptype on pointer to data member
|
|
|
|
set name "ptype pmi (A::j)"
|
|
gdb_test_multiple "ptype pmi" $name {
|
|
-re "type = int A::\\*\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
}
|
|
|
|
# print pointer to data member
|
|
|
|
set name "print pmi (A::j) "
|
|
gdb_test_multiple "print pmi" $name {
|
|
-re "$vhn = &A::j\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::j\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) ?&A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "$vhn = &A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
|
|
# gcc HEAD 2004-01-11 05:33:21 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to data member
|
|
|
|
set name "print a.*pmi (A::j)"
|
|
gdb_test_multiple "print a.*pmi" $name {
|
|
-re "$vhn = 121\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = 855638016\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to data member
|
|
# this time, dereferenced through a pointer
|
|
|
|
set name "print a_p->*pmi (A::j)"
|
|
gdb_test_multiple "print a_p->*pmi" $name {
|
|
-re "$vhn = 121\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = 855638016\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# set the pointer to a different data member
|
|
|
|
set name "set var pmi = &A::jj"
|
|
gdb_test_multiple "set var pmi = &A::jj" $name {
|
|
-re "Invalid cast.\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "set var pmi = &A::jj\r\n$gdb_prompt $" {
|
|
# I have to match the echo'ed input explicitly here.
|
|
# If I leave it out, the pattern becomes too general
|
|
# and matches anything that ends in "$gdb_prompt $".
|
|
pass $name
|
|
}
|
|
}
|
|
|
|
# print the pointer again
|
|
|
|
set name "print pmi (A::jj)"
|
|
gdb_test_multiple "print pmi" $name {
|
|
-re "$vhn = &A::jj\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
|
|
# gcc HEAD 2004-01-11 05:33:21 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to data member again
|
|
|
|
set name "print a.*pmi (A::jj)"
|
|
gdb_test_multiple "print a.*pmi" $name {
|
|
-re "$vhn = 1331\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# set the pointer to data member back to A::j
|
|
|
|
set name "set var pmi = &A::j"
|
|
gdb_test_multiple "set var pmi = &A::j" $name {
|
|
-re "Invalid cast.\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "set var pmi = &A::j\r\n$gdb_prompt $" {
|
|
# I have to match the echo'ed input explicitly here.
|
|
# If I leave it out, the pattern becomes too general
|
|
# and matches anything that ends in "$gdb_prompt $".
|
|
pass $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to data member yet again (extra check, why not)
|
|
|
|
set name "print a.*pmi (A::j) (again)"
|
|
gdb_test_multiple "print a.*pmi" $name {
|
|
-re "$vhn = 121\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Set the data member pointed to.
|
|
|
|
set name "print a.*pmi = 33"
|
|
gdb_test_multiple "print a.*pmi = 33" $name {
|
|
-re "$vhn = 33\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Now check that the data really was changed
|
|
|
|
set name "print a.*pmi (A::j) (33)"
|
|
gdb_test_multiple "print a.*pmi" $name {
|
|
-re "$vhn = 33\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Double-check by printing a.
|
|
|
|
set name "print a (j = 33)"
|
|
gdb_test_multiple "print a" $name {
|
|
-re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{(_vptr.A|_vptr\\$) = ${hex}( <vtable for A.*>)?, c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Set the data member pointed to, using ->*
|
|
|
|
set name "print a_p->*pmi = 44"
|
|
gdb_test_multiple "print a_p->*pmi = 44" $name {
|
|
-re "$vhn = 44\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Check that the data really was changed
|
|
|
|
set name "print a_p->*pmi (44)"
|
|
gdb_test_multiple "print a_p->*pmi" $name {
|
|
-re "$vhn = 44\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Double-check by printing a.
|
|
|
|
set name "print a (j = 44)"
|
|
gdb_test_multiple "print a" $name {
|
|
-re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{(_vptr.A|_vptr\\$) = ${hex}( <vtable for A.*>), c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# ptype the dereferenced pointer to member.
|
|
|
|
set name "ptype a.*pmi"
|
|
gdb_test_multiple "ptype a.*pmi" $name {
|
|
-re "type = int\r\n$gdb_prompt" {
|
|
pass $name
|
|
}
|
|
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# dereference the pointer to data member without any object
|
|
# this is not allowed: a pmi must be bound to an object to dereference
|
|
|
|
set name "print *pmi"
|
|
gdb_test_multiple "print *pmi" $name {
|
|
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Cannot access memory at address 0x4\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
-re "Cannot access memory at address 0x8\r\n$gdb_prompt $" {
|
|
# gcc 3.3.2 -gdwarf-2
|
|
# gcc 3.3.2 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# dereference the pointer to data member without any object
|
|
# this is not allowed: a pmi must be bound to an object to dereference
|
|
|
|
set name "ptype *pmi"
|
|
gdb_test_multiple "ptype *pmi" $name {
|
|
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "type = int A::\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Check cast of pointer to member to integer.
|
|
# This is similar to "offset-of".
|
|
# such as "A a; print (size_t) &A.j - (size_t) &A".
|
|
|
|
set name "print (int) pmi"
|
|
gdb_test_multiple "print (int) pmi" $name {
|
|
-re "$vhn = (4|8|12)\r\n$gdb_prompt" {
|
|
pass $name
|
|
}
|
|
}
|
|
|
|
# Check "(int) pmi" explicitly for equality.
|
|
|
|
set name "print ((int) pmi) == ((char *) &a.j - (char *) &a)"
|
|
gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
|
|
-re "$vhn = true\r\n$gdb_prompt" {
|
|
pass $name
|
|
}
|
|
}
|
|
|
|
# Check pointers to data members, which are themselves pointers to
|
|
# functions. These behave like data members, not like pointers to
|
|
# member functions.
|
|
|
|
gdb_test "ptype diamond_pfunc_ptr" \
|
|
"type = int \\(\\*Diamond::\\*\\)\\(int\\)"
|
|
|
|
gdb_test "ptype diamond.*diamond_pfunc_ptr" \
|
|
"type = int \\(\\*\\)\\(int\\)"
|
|
|
|
# This one is invalid; () binds more tightly than .*, so it tries to
|
|
# call the member pointer as a normal pointer-to-function.
|
|
|
|
gdb_test "print diamond.*diamond_pfunc_ptr (20)" \
|
|
"Invalid data type for function to be called."
|
|
|
|
# With parentheses, it is valid.
|
|
|
|
gdb_test "print (diamond.*diamond_pfunc_ptr) (20)" \
|
|
"$vhn = 39"
|
|
|
|
# Make sure that we do not interpret this as either a member pointer
|
|
# call or a member function call.
|
|
|
|
gdb_test "print diamond.func_ptr (20)" \
|
|
"$vhn = 39"
|
|
|
|
# ==========================
|
|
# pointer to member function
|
|
# ==========================
|
|
|
|
# ptype a pointer to a method
|
|
|
|
set name "ptype pmf"
|
|
gdb_test_multiple "ptype pmf" $name {
|
|
-re "type = int \\( ?A::\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "type = struct \{.*\}\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print a pointer to a method
|
|
|
|
set name "print pmf"
|
|
gdb_test_multiple "print pmf" $name {
|
|
-re "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \{.*\}\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# ptype a pointer to a pointer to a method
|
|
|
|
set name "ptype pmf_p"
|
|
gdb_test_multiple "ptype pmf_p" $name {
|
|
-re "type = int \\( ?A::\\*\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "type = struct \{.*\} \\*\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print a pointer to a pointer to a method
|
|
|
|
set name "print pmf_p"
|
|
gdb_test_multiple "print pmf_p" $name {
|
|
-re "$vhn = \\(int \\( ?A::\\*\\*\\)\\)\\(int\\)\\) $hex\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "$vhn = \\(PMF \\*\\) $hex\r\n$gdb_prompt $" {
|
|
pass "gdb/NNNN"
|
|
}
|
|
-re "$vhn = \\(struct \{.*\} \\*\\) $hex\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to method
|
|
|
|
set name "print a.*pmf"
|
|
gdb_test_multiple "print a.*pmf" $name {
|
|
-re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# print dereferenced pointer to method, using ->*
|
|
|
|
set name "print a_p->*pmf"
|
|
gdb_test_multiple "print a_p->*pmf" $name {
|
|
-re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# set the pointer to data member
|
|
|
|
set name "set var pmf = &A::foo"
|
|
gdb_test_multiple "set var pmf = &A::foo" $name {
|
|
-re "set var pmf = &A::foo\r\n$gdb_prompt $" {
|
|
# I have to match the echo'ed input explicitly here.
|
|
# If I leave it out, the pattern becomes too general
|
|
# and matches anything that ends in "$gdb_prompt $".
|
|
pass $name
|
|
}
|
|
-re "Invalid cast.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.2.2 -gdwarf-2
|
|
# gcc 3.2.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# dereference the pointer to data member without any object
|
|
# this is not allowed: a pmf must be bound to an object to dereference
|
|
|
|
set name "print *pmf"
|
|
gdb_test_multiple "print *pmf" $name {
|
|
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.3.2 -gdwarf-2
|
|
# gcc 3.3.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# dereference the pointer to data member without any object
|
|
# this is not allowed: a pmf must be bound to an object to dereference
|
|
|
|
set name "ptype *pmf"
|
|
gdb_test_multiple "ptype *pmf" $name {
|
|
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.3.2 -gdwarf-2
|
|
# gcc 3.3.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
# Call a function through a pmf.
|
|
|
|
set name "print (a.*pmf)(3)"
|
|
gdb_test_multiple "print (a.*pmf)(3)" $name {
|
|
-re "$vhn = 50\r\n$gdb_prompt $" {
|
|
pass $name
|
|
}
|
|
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
|
|
# gcc 2.95.3 -gdwarf-2
|
|
# gcc 2.95.3 -gstabs+
|
|
# gcc 3.3.2 -gdwarf-2
|
|
# gcc 3.3.2 -gstabs+
|
|
# gcc HEAD 2004-01-10 -gdwarf-2
|
|
# gcc HEAD 2004-01-10 -gstabs+
|
|
kfail "gdb/NNNN" $name
|
|
}
|
|
}
|
|
|
|
gdb_test "ptype a.*pmf" "type = int \\(A \\*( const)?, int\\)"
|
|
gdb_test "ptype (a.*pmf)(3)" "type = int"
|
|
|
|
# Print out a pointer to data member which requires looking into
|
|
# a base class.
|
|
gdb_test "print diamond_pmi" "$vhn = &Base::x"
|
|
gdb_test "print diamond.*diamond_pmi" "$vhn = 77"
|
|
|
|
# Examine some more complicated pmfs, which require adjusting "this"
|
|
# and looking through virtual tables.
|
|
|
|
# These two have a different object adjustment, but call the same method.
|
|
gdb_test "print diamond.*left_pmf" \
|
|
"$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
|
|
gdb_test "print diamond.*right_pmf" \
|
|
"$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
|
|
|
|
gdb_test "print (diamond.*left_pmf) ()" "$vhn = 77"
|
|
gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
|
|
|
|
# These two point to different methods, although they have the same
|
|
# virtual table offsets.
|
|
gdb_test "print diamond.*left_vpmf" \
|
|
"$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Left::vget\\((void|)\\)>"
|
|
gdb_test "print diamond.*right_vpmf" \
|
|
"$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Right::vget\\((void|)\\)>"
|
|
|
|
gdb_test "print (diamond.*left_vpmf) ()" "$vhn = 177"
|
|
gdb_test "print (diamond.*left_base_vpmf) ()" "$vhn = 2077"
|
|
gdb_test "print (diamond.*right_vpmf) ()" "$vhn = 288"
|
|
|
|
# We should be able to figure out left_vpmf even without an object,
|
|
# because it comes from a non-virtual base. The same for right_vpmf.
|
|
gdb_test "print left_vpmf" "$vhn = &virtual Left::vget\\(\\)"
|
|
gdb_test "print right_vpmf" "$vhn = &virtual Right::vget\\(\\)"
|
|
|
|
# But we should gracefully fail to figure out base_vpmf, because
|
|
# its runtime type is more derived than its static type. This
|
|
# is a valid but unspecified cast (it is value preserving, i.e.
|
|
# can be casted back to the correct type and used).
|
|
gdb_test "print base_vpmf" \
|
|
"$vhn = &virtual table offset \[0-9\]*, this adjustment -\[0-9\]*"
|
|
|
|
# Make sure we parse this correctly; it's invalid.
|
|
gdb_test "print diamond.*left_vpmf ()" \
|
|
"Invalid data type for function to be called\\."
|
|
|
|
# NULL pointer to member tests.
|
|
gdb_test "print null_pmi" "$vhn = NULL"
|
|
gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
|
|
gdb_test "print null_pmi = 0" "$vhn = NULL"
|
|
|
|
gdb_test "print null_pmf" "$vhn = NULL"
|
|
gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::foo ?\\(int\\)>"
|
|
gdb_test "print null_pmf = 0" "$vhn = NULL"
|