1# Copyright 1998-2023 Free Software Foundation, Inc.
2
3# This file is part of the gdb testsuite
4
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18# Tests for pointer-to-member support
19# Written by Satish Pai <pai@apollo.hp.com> 1997-08-19
20# Rewritten by Michael Chastain <mec.gnu@mindspring.com> 2004-01-11
21
22set vhn "\\$\[0-9\]+"
23
24if { [skip_cplus_tests] } { return }
25
26
27standard_testfile .cc
28
29if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
30    return -1
31}
32
33if {![runto_main]} {
34    return
35}
36
37gdb_breakpoint [gdb_get_line_number "Breakpoint 1 here"]
38gdb_continue_to_breakpoint "continue to pmi = NULL"
39
40# ======================
41# pointer to member data
42# ======================
43
44# ptype on pointer to data member
45
46set name "ptype pmi (A::j)"
47gdb_test_multiple "ptype pmi" $name {
48    -re "type = int A::\\*\r\n$gdb_prompt $" {
49	pass $name
50    }
51}
52
53# print pointer to data member
54
55set name "print pmi (A::j) "
56gdb_test_multiple "print pmi" $name {
57    -re "$vhn = &A::j\r\n$gdb_prompt $" {
58	pass $name
59    }
60    -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::j\r\n$gdb_prompt $" {
61	pass $name
62    }
63    -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) ?&A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
64	# gcc 2.95.3 -gdwarf-2
65	kfail "gdb/NNNN" $name
66    }
67    -re "$vhn = &A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
68	# gcc 2.95.3 -gstabs+
69	kfail "gdb/NNNN" $name
70    }
71    -re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
72	# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
73	# gcc HEAD 2004-01-11 05:33:21 -gstabs+
74	kfail "gdb/NNNN" $name
75    }
76}
77
78# print dereferenced pointer to data member
79
80set name "print a.*pmi (A::j)"
81gdb_test_multiple "print a.*pmi" $name {
82    -re "$vhn = 121\r\n$gdb_prompt $" {
83	pass $name
84    }
85    -re "$vhn = 855638016\r\n$gdb_prompt $" {
86	# gcc 2.95.3 -gdwarf-2
87	# gcc 2.95.3 -gstabs+
88	kfail "gdb/NNNN" $name
89    }
90    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
91	# gcc HEAD 2004-01-10 -gdwarf-2
92	# gcc HEAD 2004-01-10 -gstabs+
93	kfail "gdb/NNNN" $name
94    }
95}
96
97# print dereferenced pointer to data member
98# this time, dereferenced through a pointer
99
100set name "print a_p->*pmi (A::j)"
101gdb_test_multiple "print a_p->*pmi" $name {
102    -re "$vhn = 121\r\n$gdb_prompt $" {
103	pass $name
104    }
105    -re "$vhn = 855638016\r\n$gdb_prompt $" {
106	# gcc 2.95.3 -gdwarf-2
107	# gcc 2.95.3 -gstabs+
108	kfail "gdb/NNNN" $name
109    }
110    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
111	# gcc HEAD 2004-01-10 -gdwarf-2
112	# gcc HEAD 2004-01-10 -gstabs+
113	kfail "gdb/NNNN" $name
114    }
115}
116
117# set the pointer to a different data member
118
119set name "set var pmi = &A::jj"
120gdb_test_multiple "set var pmi = &A::jj" $name {
121    -re "Invalid cast.\r\n$gdb_prompt $" {
122	# gcc HEAD 2004-01-10 -gdwarf-2
123	# gcc HEAD 2004-01-10 -gstabs+
124	kfail "gdb/NNNN" $name
125    }
126    -re "set var pmi = &A::jj\r\n$gdb_prompt $" {
127	# I have to match the echo'ed input explicitly here.
128	# If I leave it out, the pattern becomes too general
129	# and matches anything that ends in "$gdb_prompt $".
130	pass $name
131    }
132}
133
134# print the pointer again
135
136set name "print pmi (A::jj)"
137gdb_test_multiple "print pmi" $name {
138    -re "$vhn = &A::jj\r\n$gdb_prompt $" {
139	pass $name
140    }
141    -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
142	pass $name
143    }
144    -re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
145	# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
146	# gcc HEAD 2004-01-11 05:33:21 -gstabs+
147	kfail "gdb/NNNN" $name
148    }
149}
150
151# print dereferenced pointer to data member again
152
153set name "print a.*pmi (A::jj)"
154gdb_test_multiple "print a.*pmi" $name {
155    -re "$vhn = 1331\r\n$gdb_prompt $" {
156	pass $name
157    }
158    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
159	# gcc HEAD 2004-01-10 -gdwarf-2
160	# gcc HEAD 2004-01-10 -gstabs+
161	kfail "gdb/NNNN" $name
162    }
163}
164
165# set the pointer to data member back to A::j
166
167set name "set var pmi = &A::j"
168gdb_test_multiple "set var pmi = &A::j" $name {
169    -re "Invalid cast.\r\n$gdb_prompt $" {
170	# gcc HEAD 2004-01-10 -gdwarf-2
171	# gcc HEAD 2004-01-10 -gstabs+
172	kfail "gdb/NNNN" $name
173    }
174    -re "set var pmi = &A::j\r\n$gdb_prompt $" {
175	# I have to match the echo'ed input explicitly here.
176	# If I leave it out, the pattern becomes too general
177	# and matches anything that ends in "$gdb_prompt $".
178	pass $name
179    }
180}
181
182# print dereferenced pointer to data member yet again (extra check, why not)
183
184set name "print a.*pmi (A::j) (again)"
185gdb_test_multiple "print a.*pmi" $name {
186    -re "$vhn = 121\r\n$gdb_prompt $" {
187	pass $name
188    }
189    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
190	# gcc HEAD 2004-01-10 -gdwarf-2
191	# gcc HEAD 2004-01-10 -gstabs+
192	kfail "gdb/NNNN" $name
193    }
194}
195
196# Set the data member pointed to.
197
198set name "print a.*pmi = 33"
199gdb_test_multiple "print a.*pmi = 33" $name {
200    -re "$vhn = 33\r\n$gdb_prompt $" {
201	pass $name
202    }
203    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
204	# gcc HEAD 2004-01-10 -gdwarf-2
205	# gcc HEAD 2004-01-10 -gstabs+
206	kfail "gdb/NNNN" $name
207    }
208}
209
210# Now check that the data really was changed
211
212set name "print a.*pmi (A::j) (33)"
213gdb_test_multiple "print a.*pmi" $name {
214    -re "$vhn = 33\r\n$gdb_prompt $" {
215	pass $name
216    }
217    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
218	# gcc HEAD 2004-01-10 -gdwarf-2
219	# gcc HEAD 2004-01-10 -gstabs+
220	kfail "gdb/NNNN" $name
221    }
222}
223
224# Double-check by printing a.
225
226set name "print a (j = 33)"
227gdb_test_multiple "print a" $name {
228    -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 $" {
229	pass $name
230    }
231    -re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
232	pass $name
233    }
234    -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 $" {
235	pass $name
236    }
237    -re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
238	# gcc HEAD 2004-01-10 -gdwarf-2
239	# gcc HEAD 2004-01-10 -gstabs+
240	kfail "gdb/NNNN" $name
241    }
242}
243
244# Set the data member pointed to, using ->*
245
246set name "print a_p->*pmi = 44"
247gdb_test_multiple "print a_p->*pmi = 44" $name {
248    -re "$vhn = 44\r\n$gdb_prompt $" {
249	pass $name
250    }
251    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
252	# gcc HEAD 2004-01-10 -gdwarf-2
253	# gcc HEAD 2004-01-10 -gstabs+
254	kfail "gdb/NNNN" $name
255    }
256}
257
258# Check that the data really was changed
259
260set name "print a_p->*pmi (44)"
261gdb_test_multiple "print a_p->*pmi" $name {
262    -re "$vhn = 44\r\n$gdb_prompt $" {
263	pass $name
264    }
265    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
266	# gcc HEAD 2004-01-10 -gdwarf-2
267	# gcc HEAD 2004-01-10 -gstabs+
268	kfail "gdb/NNNN" $name
269    }
270}
271
272# Double-check by printing a.
273
274set name "print a (j = 44)"
275gdb_test_multiple "print a" $name {
276    -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 $" {
277	pass $name
278    }
279    -re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
280	pass $name
281    }
282    -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 $" {
283	pass $name
284    }
285    -re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
286	# gcc HEAD 2004-01-10 -gdwarf-2
287	# gcc HEAD 2004-01-10 -gstabs+
288	kfail "gdb/NNNN" $name
289    }
290}
291
292# ptype the dereferenced pointer to member.
293
294set name "ptype a.*pmi"
295gdb_test_multiple "ptype a.*pmi" $name {
296    -re "type = int\r\n$gdb_prompt" {
297	pass $name
298    }
299    -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
300	# gcc HEAD 2004-01-10 -gdwarf-2
301	# gcc HEAD 2004-01-10 -gstabs+
302	kfail "gdb/NNNN" $name
303    }
304}
305
306# dereference the pointer to data member without any object
307# this is not allowed: a pmi must be bound to an object to dereference
308
309set name "print *pmi"
310gdb_test_multiple "print *pmi" $name {
311    -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
312	pass $name
313    }
314    -re "Cannot access memory at address 0x4\r\n$gdb_prompt $" {
315	# gcc 2.95.3 -gstabs+
316	kfail "gdb/NNNN" $name
317    }
318    -re "Cannot access memory at address 0x8\r\n$gdb_prompt $" {
319	# gcc 3.3.2 -gdwarf-2
320	# gcc 3.3.2 -gstabs+
321	kfail "gdb/NNNN" $name
322    }
323}
324
325# dereference the pointer to data member without any object
326# this is not allowed: a pmi must be bound to an object to dereference
327
328set name "ptype *pmi"
329gdb_test_multiple "ptype *pmi" $name {
330    -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
331	pass $name
332    }
333    -re "type = int  A::\r\n$gdb_prompt $" {
334	# gcc 2.95.3 -gstabs+
335	# gcc HEAD 2004-01-10 -gdwarf-2
336	# gcc HEAD 2004-01-10 -gstabs+
337	kfail "gdb/NNNN" $name
338    }
339}
340
341# Check cast of pointer to member to integer.
342# This is similar to "offset-of".
343# such as "A a; print (size_t) &A.j - (size_t) &A".
344
345set name "print (int) pmi"
346gdb_test_multiple "print (int) pmi" $name {
347    -re "$vhn = (4|8|12)\r\n$gdb_prompt" {
348	pass $name
349    }
350}
351
352# Check "(int) pmi" explicitly for equality.
353
354set name "print ((int) pmi) == ((char *) &a.j - (char *) &a)"
355gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
356    -re "$vhn = true\r\n$gdb_prompt" {
357	pass $name
358    }
359}
360
361# Check pointers to data members, which are themselves pointers to
362# functions.  These behave like data members, not like pointers to
363# member functions.
364
365gdb_test "ptype diamond_pfunc_ptr" \
366    "type = int \\(\\*Diamond::\\*\\)\\(int\\)"
367
368gdb_test "ptype diamond.*diamond_pfunc_ptr" \
369    "type = int \\(\\*\\)\\(int\\)"
370
371# This one is invalid; () binds more tightly than .*, so it tries to
372# call the member pointer as a normal pointer-to-function.
373
374gdb_test "print diamond.*diamond_pfunc_ptr (20)" \
375    "Invalid data type for function to be called."
376
377# With parentheses, it is valid.
378
379gdb_test "print (diamond.*diamond_pfunc_ptr) (20)" \
380    "$vhn = 39"
381
382# Make sure that we do not interpret this as either a member pointer
383# call or a member function call.
384
385gdb_test "print diamond.func_ptr (20)" \
386    "$vhn = 39"
387
388# ==========================
389# pointer to member function
390# ==========================
391
392# ptype a pointer to a method
393
394set name "ptype pmf"
395gdb_test_multiple "ptype pmf" $name {
396    -re "type = int \\( ?A::\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
397	pass $name
398    }
399    -re "type = struct \{.*\}\r\n$gdb_prompt $" {
400	# gcc 2.95.3 -gdwarf-2
401	# gcc 2.95.3 -gstabs+
402	# gcc 3.2.2 -gdwarf-2
403	# gcc 3.2.2 -gstabs+
404	# gcc HEAD 2004-01-10 -gdwarf-2
405	# gcc HEAD 2004-01-10 -gstabs+
406	kfail "gdb/NNNN" $name
407    }
408}
409
410# print a pointer to a method
411
412set name "print pmf"
413gdb_test_multiple "print pmf" $name {
414    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
415	pass $name
416    }
417    -re "$vhn = \{.*\}\r\n$gdb_prompt $" {
418	# gcc 2.95.3 -gdwarf-2
419	# gcc 2.95.3 -gstabs+
420	# gcc 3.2.2 -gdwarf-2
421	# gcc 3.2.2 -gstabs+
422	# gcc HEAD 2004-01-10 -gdwarf-2
423	# gcc HEAD 2004-01-10 -gstabs+
424	kfail "gdb/NNNN" $name
425    }
426}
427
428# ptype a pointer to a pointer to a method
429
430set name "ptype pmf_p"
431gdb_test_multiple "ptype pmf_p" $name {
432    -re "type = int \\( ?A::\\*\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
433	pass $name
434    }
435    -re "type = struct \{.*\} \\*\r\n$gdb_prompt $" {
436	# gcc 2.95.3 -gdwarf-2
437	# gcc 2.95.3 -gstabs+
438	# gcc 3.2.2 -gdwarf-2
439	# gcc 3.2.2 -gstabs+
440	# gcc HEAD 2004-01-10 -gdwarf-2
441	# gcc HEAD 2004-01-10 -gstabs+
442	kfail "gdb/NNNN" $name
443    }
444}
445
446# print a pointer to a pointer to a method
447
448set name "print pmf_p"
449gdb_test_multiple "print pmf_p" $name {
450    -re "$vhn = \\(int \\( ?A::\\*\\*\\)\\)\\(int\\)\\) $hex\r\n$gdb_prompt $" {
451	pass $name
452    }
453    -re "$vhn = \\(PMF \\*\\) $hex\r\n$gdb_prompt $" {
454	pass "gdb/NNNN"
455    }
456    -re "$vhn = \\(struct \{.*\} \\*\\) $hex\r\n$gdb_prompt $" {
457	# gcc 2.95.3 -gdwarf-2
458	kfail "gdb/NNNN" $name
459    }
460}
461
462# print dereferenced pointer to method
463
464set name "print a.*pmf"
465gdb_test_multiple "print a.*pmf" $name {
466    -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
467	pass $name
468    }
469    -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
470	# gcc 2.95.3 -gdwarf-2
471	# gcc 2.95.3 -gstabs+
472	# gcc 3.2.2 -gdwarf-2
473	# gcc 3.2.2 -gstabs+
474	# gcc HEAD 2004-01-10 -gdwarf-2
475	# gcc HEAD 2004-01-10 -gstabs+
476	kfail "gdb/NNNN" $name
477    }
478}
479
480# print dereferenced pointer to method, using ->*
481
482set name "print a_p->*pmf"
483gdb_test_multiple "print a_p->*pmf" $name {
484    -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
485	pass $name
486    }
487    -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
488	# gcc 2.95.3 -gdwarf-2
489	# gcc 2.95.3 -gstabs+
490	# gcc 3.2.2 -gdwarf-2
491	# gcc 3.2.2 -gstabs+
492	# gcc HEAD 2004-01-10 -gdwarf-2
493	# gcc HEAD 2004-01-10 -gstabs+
494	kfail "gdb/NNNN" $name
495    }
496}
497
498# set the pointer to data member
499
500set name "set var pmf = &A::foo"
501gdb_test_multiple "set var pmf = &A::foo" $name {
502    -re "set var pmf = &A::foo\r\n$gdb_prompt $" {
503	# I have to match the echo'ed input explicitly here.
504	# If I leave it out, the pattern becomes too general
505	# and matches anything that ends in "$gdb_prompt $".
506	pass $name
507    }
508    -re "Invalid cast.\r\n$gdb_prompt $" {
509	# gcc 2.95.3 -gdwarf-2
510	# gcc 2.95.3 -gstabs+
511	# gcc 3.2.2 -gdwarf-2
512	# gcc 3.2.2 -gstabs+
513	# gcc HEAD 2004-01-10 -gdwarf-2
514	# gcc HEAD 2004-01-10 -gstabs+
515	kfail "gdb/NNNN" $name
516    }
517}
518
519# dereference the pointer to data member without any object
520# this is not allowed: a pmf must be bound to an object to dereference
521
522set name "print *pmf"
523gdb_test_multiple "print *pmf" $name {
524    -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
525	pass $name
526    }
527    -re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
528	# gcc 2.95.3 -gdwarf-2
529	# gcc 2.95.3 -gstabs+
530	# gcc 3.3.2 -gdwarf-2
531	# gcc 3.3.2 -gstabs+
532	# gcc HEAD 2004-01-10 -gdwarf-2
533	# gcc HEAD 2004-01-10 -gstabs+
534	kfail "gdb/NNNN" $name
535    }
536}
537
538# dereference the pointer to data member without any object
539# this is not allowed: a pmf must be bound to an object to dereference
540
541set name "ptype *pmf"
542gdb_test_multiple "ptype *pmf" $name {
543    -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
544	pass $name
545    }
546    -re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
547	# gcc 2.95.3 -gdwarf-2
548	# gcc 2.95.3 -gstabs+
549	# gcc 3.3.2 -gdwarf-2
550	# gcc 3.3.2 -gstabs+
551	# gcc HEAD 2004-01-10 -gdwarf-2
552	# gcc HEAD 2004-01-10 -gstabs+
553	kfail "gdb/NNNN" $name
554    }
555}
556
557# Call a function through a pmf.
558
559set name "print (a.*pmf)(3)"
560gdb_test_multiple "print (a.*pmf)(3)" $name {
561    -re "$vhn = 50\r\n$gdb_prompt $" {
562	pass $name
563    }
564    -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
565	# gcc 2.95.3 -gdwarf-2
566	# gcc 2.95.3 -gstabs+
567	# gcc 3.3.2 -gdwarf-2
568	# gcc 3.3.2 -gstabs+
569	# gcc HEAD 2004-01-10 -gdwarf-2
570	# gcc HEAD 2004-01-10 -gstabs+
571	kfail "gdb/NNNN" $name
572    }
573}
574
575gdb_test "ptype a.*pmf" "type = int \\(A \\*( const)?, int\\)"
576gdb_test "ptype (a.*pmf)(3)" "type = int"
577
578# Print out a pointer to data member which requires looking into
579# a base class.
580gdb_test "print diamond_pmi" "$vhn = &Base::x"
581gdb_test "print diamond.*diamond_pmi" "$vhn = 77"
582
583# Examine some more complicated pmfs, which require adjusting "this"
584# and looking through virtual tables.
585
586# These two have a different object adjustment, but call the same method.
587gdb_test "print diamond.*left_pmf" \
588    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
589gdb_test "print diamond.*right_pmf" \
590    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
591
592gdb_test "print (diamond.*left_pmf) ()" "$vhn = 77"
593gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
594
595# These two point to different methods, although they have the same
596# virtual table offsets.
597gdb_test "print diamond.*left_vpmf" \
598    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Left::vget\\((void|)\\)>"
599gdb_test "print diamond.*right_vpmf" \
600    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Right::vget\\((void|)\\)>"
601
602gdb_test "print (diamond.*left_vpmf) ()" "$vhn = 177"
603gdb_test "print (diamond.*left_base_vpmf) ()" "$vhn = 2077"
604gdb_test "print (diamond.*right_vpmf) ()" "$vhn = 288"
605
606# We should be able to figure out left_vpmf even without an object,
607# because it comes from a non-virtual base.  The same for right_vpmf.
608gdb_test "print left_vpmf" "$vhn = &virtual Left::vget\\(\\)"
609gdb_test "print right_vpmf" "$vhn = &virtual Right::vget\\(\\)"
610
611# But we should gracefully fail to figure out base_vpmf, because
612# its runtime type is more derived than its static type.  This
613# is a valid but unspecified cast (it is value preserving, i.e.
614# can be casted back to the correct type and used).
615gdb_test "print base_vpmf" \
616    "$vhn = &virtual table offset \[0-9\]*, this adjustment -\[0-9\]*"
617
618# Make sure we parse this correctly; it's invalid.
619gdb_test "print diamond.*left_vpmf ()" \
620    "Invalid data type for function to be called\\."
621
622# NULL pointer to member tests.
623gdb_test "print null_pmi" "$vhn = NULL"
624gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
625gdb_test "print null_pmi = 0" "$vhn = NULL"
626
627gdb_test "print null_pmf" "$vhn = NULL"
628gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::foo ?\\(int\\)>"
629gdb_test "print null_pmf = 0" "$vhn = NULL"
630
631# Print with a format, bypassing the direct call to the scalar
632# printer.  See PR c++/29243.
633gdb_test "print/x contain" " = {member = $hex}"
634