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