1 # Copyright 1998-1999, 2003-2004, 2006-2012 Free Software Foundation,
4 # This file is part of the gdb testsuite
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # Tests for pointer-to-member support
25 if { [skip_cplus_tests] } { continue }
30 if [get_compiler_info "c++"] {
34 if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
38 if ![runto_main] then {
39 perror "couldn't run to breakpoint"
43 gdb_breakpoint [gdb_get_line_number "Breakpoint 1 here"]
44 gdb_continue_to_breakpoint "continue to pmi = NULL"
46 # ======================
47 # pointer to member data
48 # ======================
50 # ptype on pointer to data member
52 set name "ptype pmi (A::j)"
53 gdb_test_multiple "ptype pmi" $name {
54 -re "type = int A::\\*\r\n$gdb_prompt $" {
59 # print pointer to data member
61 set name "print pmi (A::j) "
62 gdb_test_multiple "print pmi" $name {
63 -re "$vhn = &A::j\r\n$gdb_prompt $" {
66 -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::j\r\n$gdb_prompt $" {
69 -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) ?&A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
70 # gcc 2.95.3 -gdwarf-2
71 kfail "gdb/NNNN" $name
73 -re "$vhn = &A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
75 kfail "gdb/NNNN" $name
77 -re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
78 # gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
79 # gcc HEAD 2004-01-11 05:33:21 -gstabs+
80 kfail "gdb/NNNN" $name
82 -re "$vhn = \\(int ?\\( A::\\*\\)\\) 536870920\r\n$gdb_prompt $" {
83 # the value is 0x20000008 hex. 0x20000000 is an internal flag.
84 # Use '|' to add in more values as needed.
86 kfail "gdb/NNNN" $name
90 # print dereferenced pointer to data member
92 set name "print a.*pmi (A::j)"
93 gdb_test_multiple "print a.*pmi" $name {
94 -re "$vhn = 121\r\n$gdb_prompt $" {
97 -re "$vhn = 855638016\r\n$gdb_prompt $" {
98 # gcc 2.95.3 -gdwarf-2
100 kfail "gdb/NNNN" $name
102 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
103 # gcc HEAD 2004-01-10 -gdwarf-2
104 # gcc HEAD 2004-01-10 -gstabs+
105 kfail "gdb/NNNN" $name
109 # print dereferenced pointer to data member
110 # this time, dereferenced through a pointer
112 set name "print a_p->*pmi (A::j)"
113 gdb_test_multiple "print a_p->*pmi" $name {
114 -re "$vhn = 121\r\n$gdb_prompt $" {
117 -re "$vhn = 855638016\r\n$gdb_prompt $" {
118 # gcc 2.95.3 -gdwarf-2
119 # gcc 2.95.3 -gstabs+
120 kfail "gdb/NNNN" $name
122 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
123 # gcc HEAD 2004-01-10 -gdwarf-2
124 # gcc HEAD 2004-01-10 -gstabs+
125 kfail "gdb/NNNN" $name
129 # set the pointer to a different data member
131 set name "set var pmi = &A::jj"
132 gdb_test_multiple "set var pmi = &A::jj" $name {
133 -re "Invalid cast.\r\n$gdb_prompt $" {
134 # gcc HEAD 2004-01-10 -gdwarf-2
135 # gcc HEAD 2004-01-10 -gstabs+
136 kfail "gdb/NNNN" $name
138 -re "set var pmi = &A::jj\r\n$gdb_prompt $" {
139 # I have to match the echo'ed input explicitly here.
140 # If I leave it out, the pattern becomes too general
141 # and matches anything that ends in "$gdb_prompt $".
146 # print the pointer again
148 set name "print pmi (A::jj)"
149 gdb_test_multiple "print pmi" $name {
150 -re "$vhn = &A::jj\r\n$gdb_prompt $" {
153 -re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
156 -re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
157 # gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
158 # gcc HEAD 2004-01-11 05:33:21 -gstabs+
159 kfail "gdb/NNNN" $name
161 -re "$vhn = \\(int ?\\( A::\\*\\)\\) 536870924\r\n$gdb_prompt $" {
162 # the value is 0x20000008 hex. 0x20000000 is an internal flag.
163 # Use '|' to add in more values as needed.
165 kfail "gdb/NNNN" $name
169 # print dereferenced pointer to data member again
171 set name "print a.*pmi (A::jj)"
172 gdb_test_multiple "print a.*pmi" $name {
173 -re "$vhn = 1331\r\n$gdb_prompt $" {
176 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
177 # gcc HEAD 2004-01-10 -gdwarf-2
178 # gcc HEAD 2004-01-10 -gstabs+
179 kfail "gdb/NNNN" $name
183 # set the pointer to data member back to A::j
185 set name "set var pmi = &A::j"
186 gdb_test_multiple "set var pmi = &A::j" $name {
187 -re "Invalid cast.\r\n$gdb_prompt $" {
188 # gcc HEAD 2004-01-10 -gdwarf-2
189 # gcc HEAD 2004-01-10 -gstabs+
190 kfail "gdb/NNNN" $name
192 -re "set var pmi = &A::j\r\n$gdb_prompt $" {
193 # I have to match the echo'ed input explicitly here.
194 # If I leave it out, the pattern becomes too general
195 # and matches anything that ends in "$gdb_prompt $".
200 # print dereferenced pointer to data member yet again (extra check, why not)
202 set name "print a.*pmi (A::j) (again)"
203 gdb_test_multiple "print a.*pmi" $name {
204 -re "$vhn = 121\r\n$gdb_prompt $" {
207 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
208 # gcc HEAD 2004-01-10 -gdwarf-2
209 # gcc HEAD 2004-01-10 -gstabs+
210 kfail "gdb/NNNN" $name
214 # Set the data member pointed to.
216 set name "print a.*pmi = 33"
217 gdb_test_multiple "print a.*pmi = 33" $name {
218 -re "$vhn = 33\r\n$gdb_prompt $" {
221 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
222 # gcc HEAD 2004-01-10 -gdwarf-2
223 # gcc HEAD 2004-01-10 -gstabs+
224 kfail "gdb/NNNN" $name
228 # Now check that the data really was changed
230 set name "print a.*pmi (A::j) (33)"
231 gdb_test_multiple "print a.*pmi" $name {
232 -re "$vhn = 33\r\n$gdb_prompt $" {
235 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
236 # gcc HEAD 2004-01-10 -gdwarf-2
237 # gcc HEAD 2004-01-10 -gstabs+
238 kfail "gdb/NNNN" $name
242 # Double-check by printing a.
244 set name "print a (j = 33)"
245 gdb_test_multiple "print a" $name {
246 -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 $" {
249 -re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
252 -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 $" {
255 -re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
256 # gcc HEAD 2004-01-10 -gdwarf-2
257 # gcc HEAD 2004-01-10 -gstabs+
258 kfail "gdb/NNNN" $name
262 # Set the data member pointed to, using ->*
264 set name "print a_p->*pmi = 44"
265 gdb_test_multiple "print a_p->*pmi = 44" $name {
266 -re "$vhn = 44\r\n$gdb_prompt $" {
269 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
270 # gcc HEAD 2004-01-10 -gdwarf-2
271 # gcc HEAD 2004-01-10 -gstabs+
272 kfail "gdb/NNNN" $name
276 # Check that the data really was changed
278 set name "print a_p->*pmi (44)"
279 gdb_test_multiple "print a_p->*pmi" $name {
280 -re "$vhn = 44\r\n$gdb_prompt $" {
283 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
284 # gcc HEAD 2004-01-10 -gdwarf-2
285 # gcc HEAD 2004-01-10 -gstabs+
286 kfail "gdb/NNNN" $name
290 # Double-check by printing a.
292 set name "print a (j = 44)"
293 gdb_test_multiple "print a" $name {
294 -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 $" {
297 -re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
300 -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 $" {
303 -re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
304 # gcc HEAD 2004-01-10 -gdwarf-2
305 # gcc HEAD 2004-01-10 -gstabs+
306 kfail "gdb/NNNN" $name
310 # ptype the dereferenced pointer to member.
312 set name "ptype a.*pmi"
313 gdb_test_multiple "ptype a.*pmi" $name {
314 -re "type = int\r\n$gdb_prompt" {
317 -re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
318 # gcc HEAD 2004-01-10 -gdwarf-2
319 # gcc HEAD 2004-01-10 -gstabs+
320 kfail "gdb/NNNN" $name
324 # dereference the pointer to data member without any object
325 # this is not allowed: a pmi must be bound to an object to dereference
327 set name "print *pmi"
328 gdb_test_multiple "print *pmi" $name {
329 -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
332 -re "Cannot access memory at address 0x4\r\n$gdb_prompt $" {
333 # gcc 2.95.3 -gstabs+
334 kfail "gdb/NNNN" $name
336 -re "Cannot access memory at address 0x8\r\n$gdb_prompt $" {
337 # gcc 3.3.2 -gdwarf-2
339 kfail "gdb/NNNN" $name
343 # dereference the pointer to data member without any object
344 # this is not allowed: a pmi must be bound to an object to dereference
346 set name "ptype *pmi"
347 gdb_test_multiple "ptype *pmi" $name {
348 -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
351 -re "type = int A::\r\n$gdb_prompt $" {
352 # gcc 2.95.3 -gstabs+
353 # gcc HEAD 2004-01-10 -gdwarf-2
354 # gcc HEAD 2004-01-10 -gstabs+
355 kfail "gdb/NNNN" $name
359 # Check cast of pointer to member to integer.
360 # This is similar to "offset-of".
361 # such as "A a; print (size_t) &A.j - (size_t) &A".
363 set name "print (int) pmi"
364 gdb_test_multiple "print (int) pmi" $name {
365 -re "$vhn = (4|8|12)\r\n$gdb_prompt" {
370 # Check "(int) pmi" explicitly for equality.
372 set name "print ((int) pmi) == ((char *) &a.j - (char *) &a)"
373 gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
374 -re "$vhn = true\r\n$gdb_prompt" {
379 # ==========================
380 # pointer to member function
381 # ==========================
383 # ptype a pointer to a method
386 gdb_test_multiple "ptype pmf" $name {
387 -re "type = int \\( ?A::\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
390 -re "type = int \\( ?A::\\*\\)\\(void\\)\r\n$gdb_prompt $" {
392 kfail "gdb/NNNN" $name
394 -re "type = struct \{.*\}\r\n$gdb_prompt $" {
395 # gcc 2.95.3 -gdwarf-2
396 # gcc 2.95.3 -gstabs+
397 # gcc 3.2.2 -gdwarf-2
399 # gcc HEAD 2004-01-10 -gdwarf-2
400 # gcc HEAD 2004-01-10 -gstabs+
401 kfail "gdb/NNNN" $name
405 # print a pointer to a method
408 gdb_test_multiple "print pmf" $name {
409 -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
412 -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
414 kfail "gdb/NNNN" $name
416 -re "$vhn = \{.*\}\r\n$gdb_prompt $" {
417 # gcc 2.95.3 -gdwarf-2
418 # gcc 2.95.3 -gstabs+
419 # gcc 3.2.2 -gdwarf-2
421 # gcc HEAD 2004-01-10 -gdwarf-2
422 # gcc HEAD 2004-01-10 -gstabs+
423 kfail "gdb/NNNN" $name
427 # ptype a pointer to a pointer to a method
429 set name "ptype pmf_p"
430 gdb_test_multiple "ptype pmf_p" $name {
431 -re "type = int \\( ?A::\\*\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
434 -re "type = int \\( ?A::\\*\\*\\)\\(void\\)\r\n$gdb_prompt $" {
436 kfail "gdb/NNNN" $name
438 -re "type = struct \{.*\} \\*\r\n$gdb_prompt $" {
439 # gcc 2.95.3 -gdwarf-2
440 # gcc 2.95.3 -gstabs+
441 # gcc 3.2.2 -gdwarf-2
443 # gcc HEAD 2004-01-10 -gdwarf-2
444 # gcc HEAD 2004-01-10 -gstabs+
445 kfail "gdb/NNNN" $name
449 # print a pointer to a pointer to a method
451 set name "print pmf_p"
452 gdb_test_multiple "print pmf_p" $name {
453 -re "$vhn = \\(int \\( ?A::\\*\\*\\)\\)\\(int\\)\\) $hex\r\n$gdb_prompt $" {
456 -re "$vhn = \\(PMF \\*\\) $hex\r\n$gdb_prompt $" {
459 -re "$vhn = \\(int \\( ?A::\\*\\*\\)\\(void\\)\\) $hex\r\n$gdb_prompt $" {
461 kfail "gdb/NNNN" $name
463 -re "$vhn = \\(struct \{.*\} \\*\\) $hex\r\n$gdb_prompt $" {
464 # gcc 2.95.3 -gdwarf-2
465 kfail "gdb/NNNN" $name
469 # print dereferenced pointer to method
471 set name "print a.*pmf"
472 gdb_test_multiple "print a.*pmf" $name {
473 -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
476 -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
478 kfail "gdb/NNNN" $name
480 -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
481 # gcc 2.95.3 -gdwarf-2
482 # gcc 2.95.3 -gstabs+
483 # gcc 3.2.2 -gdwarf-2
485 # gcc HEAD 2004-01-10 -gdwarf-2
486 # gcc HEAD 2004-01-10 -gstabs+
487 kfail "gdb/NNNN" $name
491 # print dereferenced pointer to method, using ->*
493 set name "print a_p->*pmf"
494 gdb_test_multiple "print a_p->*pmf" $name {
495 -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
498 -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
500 kfail "gdb/NNNN" $name
502 -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
503 # gcc 2.95.3 -gdwarf-2
504 # gcc 2.95.3 -gstabs+
505 # gcc 3.2.2 -gdwarf-2
507 # gcc HEAD 2004-01-10 -gdwarf-2
508 # gcc HEAD 2004-01-10 -gstabs+
509 kfail "gdb/NNNN" $name
513 # set the pointer to data member
515 set name "set var pmf = &A::foo"
516 gdb_test_multiple "set var pmf = &A::foo" $name {
517 -re "set var pmf = &A::foo\r\n$gdb_prompt $" {
518 # I have to match the echo'ed input explicitly here.
519 # If I leave it out, the pattern becomes too general
520 # and matches anything that ends in "$gdb_prompt $".
523 -re "Invalid cast.\r\n$gdb_prompt $" {
524 # gcc 2.95.3 -gdwarf-2
525 # gcc 2.95.3 -gstabs+
526 # gcc 3.2.2 -gdwarf-2
528 # gcc HEAD 2004-01-10 -gdwarf-2
529 # gcc HEAD 2004-01-10 -gstabs+
530 kfail "gdb/NNNN" $name
532 -re "Assignment to pointers to methods not implemented with HP aCC\r\n$gdb_prompt $" {
533 kfail "gdb/NNNN" $name
537 # dereference the pointer to data member without any object
538 # this is not allowed: a pmf must be bound to an object to dereference
540 set name "print *pmf"
541 gdb_test_multiple "print *pmf" $name {
542 -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
545 -re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
546 # gcc 2.95.3 -gdwarf-2
547 # gcc 2.95.3 -gstabs+
548 # gcc 3.3.2 -gdwarf-2
550 # gcc HEAD 2004-01-10 -gdwarf-2
551 # gcc HEAD 2004-01-10 -gstabs+
552 kfail "gdb/NNNN" $name
556 # dereference the pointer to data member without any object
557 # this is not allowed: a pmf must be bound to an object to dereference
559 set name "ptype *pmf"
560 gdb_test_multiple "ptype *pmf" $name {
561 -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
564 -re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
565 # gcc 2.95.3 -gdwarf-2
566 # gcc 2.95.3 -gstabs+
567 # gcc 3.3.2 -gdwarf-2
569 # gcc HEAD 2004-01-10 -gdwarf-2
570 # gcc HEAD 2004-01-10 -gstabs+
571 kfail "gdb/NNNN" $name
575 # Call a function through a pmf.
577 set name "print (a.*pmf)(3)"
578 gdb_test_multiple "print (a.*pmf)(3)" $name {
579 -re "$vhn = 50\r\n$gdb_prompt $" {
582 -re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" {
584 kfail "gdb/NNNN" $name
586 -re "Value can't be converted to integer.\r\n$gdb_prompt $" {
587 # gcc 2.95.3 -gdwarf-2
588 # gcc 2.95.3 -gstabs+
589 # gcc 3.3.2 -gdwarf-2
591 # gcc HEAD 2004-01-10 -gdwarf-2
592 # gcc HEAD 2004-01-10 -gstabs+
593 kfail "gdb/NNNN" $name
597 gdb_test "ptype a.*pmf" "type = int \\(A \\*( const)?, int\\)"
599 # Print out a pointer to data member which requires looking into
601 gdb_test "print diamond_pmi" "$vhn = &Base::x"
602 gdb_test "print diamond.*diamond_pmi" "$vhn = 77"
604 # Examine some more complicated pmfs, which require adjusting "this"
605 # and looking through virtual tables.
607 # These two have a different object adjustment, but call the same method.
608 gdb_test "print diamond.*left_pmf" \
609 "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
610 gdb_test "print diamond.*right_pmf" \
611 "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
613 gdb_test "print (diamond.*left_pmf) ()" "$vhn = 77"
614 gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
616 # These two point to different methods, although they have the same
617 # virtual table offsets.
618 gdb_test "print diamond.*left_vpmf" \
619 "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Left::vget\\((void|)\\)>"
620 gdb_test "print diamond.*right_vpmf" \
621 "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Right::vget\\((void|)\\)>"
623 gdb_test "print (diamond.*left_vpmf) ()" "$vhn = 177"
624 gdb_test "print (diamond.*left_base_vpmf) ()" "$vhn = 2077"
625 gdb_test "print (diamond.*right_vpmf) ()" "$vhn = 288"
627 # We should be able to figure out left_vpmf even without an object,
628 # because it comes from a non-virtual base. The same for right_vpmf.
629 gdb_test "print left_vpmf" "$vhn = &virtual Left::vget\\(\\)"
630 gdb_test "print right_vpmf" "$vhn = &virtual Right::vget\\(\\)"
632 # But we should gracefully fail to figure out base_vpmf, because
633 # its runtime type is more derived than its static type. This
634 # is a valid but unspecified cast (it is value preserving, i.e.
635 # can be casted back to the correct type and used).
636 gdb_test "print base_vpmf" \
637 "$vhn = &virtual table offset \[0-9\]*, this adjustment -\[0-9\]*"
639 # Make sure we parse this correctly; it's invalid.
640 gdb_test "print diamond.*left_vpmf ()" \
641 "Invalid data type for function to be called\\."
643 # NULL pointer to member tests.
644 gdb_test "print null_pmi" "$vhn = NULL"
645 gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
646 gdb_test "print null_pmi = 0" "$vhn = NULL"
648 gdb_test "print null_pmf" "$vhn = NULL"
649 gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::foo ?\\(int\\)>"
650 gdb_test "print null_pmf = 0" "$vhn = NULL"