xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.cp/virtfunc.exp (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
1# Copyright 1992-2023 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# This file was written by Fred Fish. (fnf@cygnus.com)
17# And rewritten by Michael Chastain <mec.gnu@mindspring.com>.
18
19set nl		"\[\r\n\]+"
20
21if { [skip_cplus_tests] } { continue }
22
23load_lib "cp-support.exp"
24
25standard_testfile .cc
26
27if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
28    return -1
29}
30
31proc test_ptype_of_classes {} {
32
33    # class VA
34
35    cp_test_ptype_class \
36	"VA" "" "class" "VA" \
37	{
38	    { field public "int va;" }
39	}
40
41    # class VB
42
43    cp_test_ptype_class \
44	"VB" "" "class" "VB" \
45	{
46	    { field  public "int vb;" }
47	    { method public "int fvb();" }
48	    { method public "virtual int vvb();" }
49	}
50
51    # class V
52
53    cp_test_ptype_class \
54	"V" "" "class" "V" \
55	{
56	    { base          "public VA" }
57	    { base          "public VB" }
58	    { field  public "int w;" }
59	    { method public "int f();" }
60	    { method public "virtual int vv();" }
61	}
62
63    # class A
64
65    cp_test_ptype_class \
66	"A" "" "class" "A" \
67	{
68	    { base           "public virtual V" }
69	    { vbase          "V" }
70	    { field  private "int a;" }
71	    { method public  "virtual int f();" }
72	}
73
74    # class B
75
76    cp_test_ptype_class \
77	"B" "" "class" "B" \
78	{
79	    { base           "public A" }
80	    { field  private "int b;" }
81	    { method public  "virtual int f();" }
82	}
83
84    # class C
85
86    cp_test_ptype_class \
87	"C" "" "class" "C" \
88	{
89	    { base         "public virtual V" }
90	    { vbase        "V" }
91	    { field public "int c;" }
92	}
93
94    # class AD
95
96    cp_test_ptype_class \
97	"AD" "" "class" "AD" \
98	{
99	    { method public "virtual int vg();" }
100	}
101
102    # class D
103
104    cp_test_ptype_class \
105	"D" "" "class" "D" \
106	{
107	    { base          "public AD" }
108	    { base          "public virtual V" }
109	    { vbase         "V" }
110	    { method public "static void s();" }
111	    { method public "virtual int vg();" }
112	    { method public "virtual int vd();" }
113	    { method public "int fd();" }
114	    { field  public "int d;" }
115	}
116
117    # class E
118
119    cp_test_ptype_class \
120	"E" "" "class" "E" \
121	{
122	    { base          "public B" }
123	    { base          "public virtual V" }
124	    { base          "public D" }
125	    { base          "public C" }
126	    { vbase         "V" }
127	    { method public "virtual int f();" }
128	    { method public "virtual int vg();" }
129	    { method public "virtual int vv();" }
130	    { field  public "int e;" }
131	}
132
133    # An instance of D
134
135    cp_test_ptype_class "dd" "" "class" "D" ibid
136
137    # An instance of D *
138
139    cp_test_ptype_class "ppd" "" "class" "D" ibid "*"
140
141    # An instance of AD *
142    # TODO: this should be named pADd, not pAd.
143
144    cp_test_ptype_class "pAd" "" "class" "AD" ibid "*"
145
146    # Instances of these classes.
147
148    cp_test_ptype_class "a" "" "class" "A" ibid
149    cp_test_ptype_class "b" "" "class" "B" ibid
150    cp_test_ptype_class "c" "" "class" "C" ibid
151    cp_test_ptype_class "d" "" "class" "D" ibid
152    cp_test_ptype_class "e" "" "class" "E" ibid
153    cp_test_ptype_class "v" "" "class" "V" ibid
154    cp_test_ptype_class "vb" "" "class" "VB" ibid
155
156    # Instances of pointers to these classes.
157
158    cp_test_ptype_class "pAa" "" "class" "A" ibid "*"
159    cp_test_ptype_class "pAe" "" "class" "A" ibid "*"
160    cp_test_ptype_class "pBe" "" "class" "B" ibid "*"
161    cp_test_ptype_class "pDd" "" "class" "D" ibid "*"
162    cp_test_ptype_class "pDe" "" "class" "D" ibid "*"
163    cp_test_ptype_class "pVa" "" "class" "V" ibid "*"
164    cp_test_ptype_class "pVv" "" "class" "V" ibid "*"
165    cp_test_ptype_class "pVe" "" "class" "V" ibid "*"
166    cp_test_ptype_class "pVd" "" "class" "V" ibid "*"
167    cp_test_ptype_class "pADe" "" "class" "AD" ibid "*"
168    cp_test_ptype_class "pEe" "" "class" "E" ibid "*"
169    cp_test_ptype_class "pVB" "" "class" "VB" ibid "*"
170
171}
172
173# Call virtual functions.
174
175proc test_virtual_calls {} {
176    global gdb_prompt
177    global nl
178
179    if [target_info exists gdb,cannot_call_functions] {
180	unsupported "this target can not call functions"
181	return 0
182    }
183
184    gdb_test "print pAe->f()"   "\\$\[0-9\]+ = 20"
185    gdb_test "print pAa->f()"   "\\$\[0-9\]+ = 1"
186    gdb_test "print pDe->vg()"  "\\$\[0-9\]+ = 202"
187    gdb_test "print pADe->vg()" "\\$\[0-9\]+ = 202"
188    gdb_test "print pDd->vg()"  "\\$\[0-9\]+ = 101"
189    gdb_test "print pEe->vvb()" "\\$\[0-9\]+ = 411"
190    gdb_test "print pVB->vvb()" "\\$\[0-9\]+ = 407"
191    gdb_test "print pBe->vvb()" "\\$\[0-9\]+ = 411"
192    gdb_test "print pDe->vvb()" "\\$\[0-9\]+ = 411"
193    gdb_test "print pEe->vd()"  "\\$\[0-9\]+ = 282"
194    gdb_test "print pEe->fvb()" "\\$\[0-9\]+ = 311"
195
196    # more recent results:
197    # wrong value "202"
198    #   gcc 2.95.3 -gdwarf-2
199    #   gcc 2.95.3 -gstabs+
200    # attempt to take addres of value not located in memory
201    #   gcc 3.3.2 -gdwarf-2
202    #   gcc 3.3.2 -gstabs+
203    #
204    # -- chastain 2003-12-31
205
206    gdb_test_multiple "print pEe->D::vg()" "print pEe->D::vg()" {
207	-re "\\$\[0-9]+ = 102$nl$gdb_prompt $" {
208	    pass "print pEe->D::vg()"
209	}
210	-re "\\$\[0-9]+ = 202$nl$gdb_prompt $" {
211	    # To get this result, we have called pEe->*(&D::vg) ().
212	    # That's how GDB interprets this, but it's wrong; in fact
213	    # the explicit D:: means to bypass virtual function lookup,
214	    # and call D::vg as if it were non-virtual.  We still have
215	    # to e.g. adjust "this", though.
216	    kfail "gdb/1064" "print pEe->D::vg()"
217	}
218	-re "Attempt to take address of value not located in memory.$nl$gdb_prompt $" {
219	    kfail "gdb/1064" "print pEe->D::vg()"
220	}
221    }
222}
223
224# A helper proc that creates a regular expression matching a
225# particular vtable.  NAME is the type name.  Each element of ARGS is
226# the name of a function in the vtable.
227
228proc make_one_vtable_result {name args} {
229    global hex
230
231    set nls "\[\r\n\]+"
232
233    set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls"
234    set count 0
235    foreach func $args {
236	append result ".${count}.:( @$hex:)? $hex <(\.)?$func..>${nls}"
237	incr count
238    }
239
240    return $result
241}
242
243# Test "info vtbl".
244
245proc test_info_vtbl {} {
246    global hex
247
248    set nls "\[\r\n\]+"
249
250    set vt_A [make_one_vtable_result A A::f]
251    set vt_B [make_one_vtable_result B B::f]
252    set vt_V [make_one_vtable_result V VB::vvb V::vv]
253    set vt_V2 [make_one_vtable_result V VB::vvb "virtual thunk to E::vv"]
254    set vt_D [make_one_vtable_result D D::vg D::vd]
255    set vt_D2 [make_one_vtable_result D "non-virtual thunk to E::vg" D::vd]
256    set vt_E [make_one_vtable_result E E::f E::vg E::vv]
257
258    gdb_test "info vtbl a" "${vt_A}${vt_V}"
259    gdb_test "info vtbl b" "${vt_B}${vt_V}"
260    gdb_test "info vtbl c" "${vt_V}"
261    gdb_test "info vtbl d" "${vt_D}${vt_V}"
262    gdb_test "info vtbl e" "${vt_E}${vt_D2}${vt_V2}"
263    gdb_test "info vtbl pEe" "${vt_E}${vt_D2}${vt_V2}"
264
265    gdb_test "info vtbl" "Argument required.*"
266    gdb_test "info vtbl va" \
267	"This object does not have a virtual function table.*"
268    gdb_test "info vtbl all_count" \
269	"This object does not have a virtual function table.*"
270}
271
272proc do_tests {} {
273    gdb_test_no_output "set language c++" ""
274    gdb_test_no_output "set width 0" ""
275
276    if {![runto_main]} {
277	return
278    }
279    test_ptype_of_classes
280    test_info_vtbl
281
282    gdb_breakpoint test_calls
283    gdb_test "continue" ".*Breakpoint .* test_calls.*" ""
284    test_virtual_calls
285
286    gdb_test "next" ".*pAa->f.*" "next to pAa->f call"
287    gdb_test "next" ".*pDe->vg.*" "next to pDe->vg call"
288    gdb_test "step" ".*E::vg.*" "step through thunk into E::vg"
289}
290
291do_tests
292