Commit | Line | Data |
---|---|---|
c906108c SS |
1 | # Copyright (C) 1998 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 2 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, write to the Free Software | |
15 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
16 | ||
17 | # Please email any bugs, comments, and/or additions to this file to: | |
18 | # bug-gdb@prep.ai.mit.edu | |
19 | # Tests for pointer-to-member support | |
20 | # Written by Satish Pai <pai@apollo.hp.com> 1997-08-19 | |
21 | ||
22 | # This file is part of the gdb testsuite | |
23 | ||
24 | ||
25 | if $tracelevel then { | |
26 | strace $tracelevel | |
27 | } | |
28 | ||
29 | # | |
30 | # test running programs | |
31 | # | |
32 | ||
33 | # Start with a fresh gdb | |
34 | gdb_exit | |
35 | gdb_start | |
36 | gdb_reinitialize_dir $srcdir/$subdir | |
37 | ||
38 | set prms_id 0 | |
39 | set bug_id 0 | |
40 | ||
41 | set testfile "member-ptr" | |
42 | set srcfile ${testfile}.cc | |
43 | set binfile ${objdir}/${subdir}/${testfile} | |
44 | ||
085dd6e6 JM |
45 | # Create and source the file that provides information about the compiler |
46 | # used to compile the test case. | |
47 | ||
48 | if [get_compiler_info ${binfile} "c++"] { | |
49 | return -1 | |
50 | } | |
51 | ||
52 | # Nearly all of these tests fail when compiled with G++, so just give up | |
53 | # until GDB gets enhanced. -sts 1999-06-22 | |
54 | ||
55 | if {$gcc_compiled} { | |
56 | continue | |
57 | } | |
58 | ||
c906108c SS |
59 | if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { |
60 | gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." | |
61 | } | |
62 | ||
63 | ||
64 | gdb_exit | |
65 | gdb_start | |
66 | gdb_reinitialize_dir $srcdir/$subdir | |
67 | gdb_load ${binfile} | |
68 | ||
69 | ||
70 | if ![runto_main] then { | |
71 | perror "couldn't run to breakpoint" | |
72 | continue | |
73 | } | |
74 | ||
75 | send_gdb "break 83\n" | |
76 | gdb_expect { | |
77 | -re "Breakpoint \[0-9\]*.*line 83\\.\r\n$gdb_prompt $" { | |
78 | pass "set break at 83" | |
79 | } | |
80 | -re ".*$gdb_prompt $" { fail "set break at 83" } | |
81 | timeout { fail "(timeout) set break at 83" } | |
82 | } | |
83 | ||
84 | send_gdb "continue\n" | |
85 | gdb_expect { | |
86 | -re "Continuing\\.\r\n\r\nBreakpoint.*at.*member-ptr\\.cc:83\r\n83\[ \t]*pmi = NULL;\r\n$gdb_prompt $" { | |
87 | pass "continue to 83" | |
88 | } | |
89 | -re ".*$gdb_prompt $" { fail "continue to 83" } | |
90 | timeout { fail "(timeout) continue to 83" } | |
91 | } | |
92 | ||
93 | # ptype on pointer to data member | |
94 | ||
95 | send_gdb "ptype pmi\n" | |
96 | gdb_expect { | |
97 | -re "type = int \\( A::\\*\\)\r\n$gdb_prompt $" { | |
98 | pass "ptype pmi" | |
99 | } | |
100 | -re ".*$gdb_prompt $" { fail "ptype pmi" } | |
101 | timeout { fail "(timeout) ptype pmi" } | |
102 | } | |
103 | ||
104 | # print pointer to data member | |
105 | ||
106 | send_gdb "print pmi\n" | |
107 | gdb_expect { | |
108 | -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::j\r\n$gdb_prompt $" { | |
109 | pass "print pmi" | |
110 | } | |
111 | -re ".*$gdb_prompt $" { fail "print pmi" } | |
112 | timeout { fail "(timeout) print pmi" } | |
113 | } | |
114 | ||
115 | ||
116 | # print dereferenced pointer to data member | |
117 | ||
118 | send_gdb "print a.*pmi\n" | |
119 | gdb_expect { | |
120 | -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" { | |
121 | pass "print a.*pmi" | |
122 | } | |
123 | -re ".*$gdb_prompt $" { fail "print a.*pmi" } | |
124 | timeout { fail "(timeout) print a.*pmi" } | |
125 | } | |
126 | ||
127 | # print dereferenced pointer to data member | |
128 | # this time, dereferenced through a pointer | |
129 | ||
130 | send_gdb "print a_p->*pmi\n" | |
131 | gdb_expect { | |
132 | -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" { | |
133 | pass "print a->*pmi" | |
134 | } | |
135 | -re ".*$gdb_prompt $" { fail "print a->*pmi" } | |
136 | timeout { fail "(timeout) print a->*pmi" } | |
137 | } | |
138 | ||
139 | ||
140 | # set the pointer to data member | |
141 | ||
142 | send_gdb "set var pmi = &A::jj\n" | |
143 | gdb_expect { | |
144 | -re "$gdb_prompt $" { | |
145 | pass "set var (not really a pass)" | |
146 | } | |
147 | timeout { fail "(timeout) " } | |
148 | } | |
149 | ||
150 | # Now print the pointer again | |
151 | ||
152 | send_gdb "print pmi\n" | |
153 | gdb_expect { | |
154 | -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" { | |
155 | pass "print pmi after setting" | |
156 | } | |
157 | -re ".*$gdb_prompt $" { fail "print pmi after setting" } | |
158 | timeout { fail "(timeout) print pmi after setting" } | |
159 | } | |
160 | ||
161 | # print dereferenced pointer to data member again | |
162 | ||
163 | send_gdb "print a.*pmi\n" | |
164 | gdb_expect { | |
165 | -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" { | |
166 | pass "print a.*pmi after setting" | |
167 | } | |
168 | -re ".*$gdb_prompt $" { fail "print a.*pmi after setting" } | |
169 | timeout { fail "(timeout) print a.*pmi after setting" } | |
170 | } | |
171 | ||
172 | # set the pointer to data member back to A::j | |
173 | ||
174 | send_gdb "set var pmi = &A::j\n" | |
175 | gdb_expect { | |
176 | -re "$gdb_prompt $" { | |
177 | pass "set var back to A::j (not really a pass)" | |
178 | } | |
179 | timeout { fail "(timeout) set var pmi" } | |
180 | } | |
181 | ||
182 | # print dereferenced pointer to data member yet again (extra check, why not) | |
183 | ||
184 | send_gdb "print a.*pmi\n" | |
185 | gdb_expect { | |
186 | -re "\\$\[0-9\]* = 121\r\n$gdb_prompt $" { | |
187 | pass "print a.*pmi after resetting" | |
188 | } | |
189 | -re ".*$gdb_prompt $" { fail "print a.*pmi after resetting" } | |
190 | timeout { fail "(timeout) print a.*pmi after resetting" } | |
191 | } | |
192 | ||
193 | # Set the data member pointed to. | |
194 | ||
195 | send_gdb "print a.*pmi = 33\n" | |
196 | gdb_expect { | |
197 | -re "\\$\[0-9\]* = 33\r\n$gdb_prompt $" { | |
198 | pass "print command to set" | |
199 | } | |
200 | -re ".*$gdb_prompt $" { fail "print command to set" } | |
201 | timeout { fail "(timeout) print command to set" } | |
202 | } | |
203 | ||
204 | # Now check that the data really was changed | |
205 | send_gdb "print a.*pmi\n" | |
206 | gdb_expect { | |
207 | -re "\\$\[0-9\]* = 33\r\n$gdb_prompt $" { | |
208 | pass "print a.*pmi after setting member pointed to" | |
209 | } | |
210 | -re ".*$gdb_prompt $" { fail "print a.*pmi after setting member pointed to" } | |
211 | timeout { fail "(timeout) print a.*pmi after setting member pointed to" } | |
212 | } | |
213 | ||
214 | # Double-check by printing a. | |
215 | send_gdb "print a\n" | |
216 | gdb_expect { | |
217 | -re "\\$\[0-9\]* = \{c = 120 'x', j = 33, jj = 1331, static s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" { | |
218 | pass "print a after setting member pointed to by pmi" | |
219 | } | |
220 | -re ".*$gdb_prompt $" { fail "print a after setting member pointed to by pmi" } | |
221 | timeout { fail "(timeout) print a after setting member pointed to by pmi" } | |
222 | } | |
223 | ||
224 | ||
225 | # Set the data member pointed to, using ->* | |
226 | ||
227 | send_gdb "print a_p->*pmi = 44\n" | |
228 | gdb_expect { | |
229 | -re "\\$\[0-9\]* = 44\r\n$gdb_prompt $" { | |
230 | pass "print command to set (->)" | |
231 | } | |
232 | -re ".*$gdb_prompt $" { fail "print command to set (->)" } | |
233 | timeout { fail "(timeout) print command to set (->)" } | |
234 | } | |
235 | ||
236 | # Now check that the data really was changed | |
237 | send_gdb "print a_p->*pmi\n" | |
238 | gdb_expect { | |
239 | -re "\\$\[0-9\]* = 44\r\n$gdb_prompt $" { | |
240 | pass "print a_p->*pmi after setting member pointed to" | |
241 | } | |
242 | -re ".*$gdb_prompt $" { fail "print a_p->*pmi after setting member pointed to" } | |
243 | timeout { fail "(timeout) print a_p->*pmi after setting member pointed to" } | |
244 | } | |
245 | ||
246 | # Double-check by printing a. | |
247 | send_gdb "print a\n" | |
248 | gdb_expect { | |
249 | -re "\\$\[0-9\]* = \{c = 120 'x', j = 44, jj = 1331, static s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" { | |
250 | pass "print a after setting member pointed to by pmi (->) " | |
251 | } | |
252 | -re ".*$gdb_prompt $" { fail "print a after setting member pointed to by pmi (->) " } | |
253 | timeout { fail "(timeout) print a after setting member pointed to by pmi (->) " } | |
254 | } | |
255 | ||
256 | ||
257 | # Do a ptype on the dereferenced pointer to member | |
258 | # pai/1997-08-20 Doesn't work | |
259 | ||
260 | # send_gdb "ptype a.*pmi\n" | |
261 | # gdb_expect { | |
262 | # -re "type = int\r\n$gdb_prompt $" { | |
263 | # pass "ptype a.*pmi" | |
264 | # } | |
265 | # -re ".*$gdb_prompt $" { fail "ptype a.*pmi" } | |
266 | # timeout { fail "(timeout) ptype a.*pmi" } | |
267 | #} | |
268 | ||
269 | # Try to dereference the pointer to data member without any object | |
270 | ||
271 | send_gdb "print *pmi\n" | |
272 | gdb_expect { | |
273 | -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" { | |
274 | pass "attempt to print ptr to member without object" | |
275 | } | |
276 | -re ".*$gdb_prompt $" { fail "attempt to print ptr to member without object" } | |
277 | timeout { fail "(timeout) attempt to print ptr to member without object" } | |
278 | } | |
279 | ||
280 | # Try to ptype a dereference of the pointer to data member without any object | |
281 | ||
282 | send_gdb "ptype *pmi\n" | |
283 | gdb_expect { | |
284 | -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" { | |
285 | pass "attempt to ptype ptr to member without object" | |
286 | } | |
287 | -re ".*$gdb_prompt $" { fail "attempt to ptype ptr to member without object" } | |
288 | timeout { fail "(timeout) attempt to ptype ptr to member without object" } | |
289 | } | |
290 | ||
291 | # Ptype a pointer to a method. | |
292 | ||
293 | send_gdb "ptype pmf\n" | |
294 | gdb_expect { | |
295 | -re "type = int \\( A::\\*\\)\\(\\.\\.\\.\\)\r\n$gdb_prompt $" { | |
296 | pass "ptype pmf" | |
297 | } | |
298 | -re ".*$gdb_prompt $" { fail "ptype pmf" } | |
299 | timeout { fail "(timeout) ptype pmf" } | |
300 | } | |
301 | ||
302 | # print a pointer to a method | |
303 | ||
304 | send_gdb "print pmf\n" | |
305 | gdb_expect { | |
306 | -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\(\\.\\.\\.\\)\\) \\?\\? <not supported with HP aCC>\r\n$gdb_prompt $" { | |
307 | pass "print pmf" | |
308 | } | |
309 | -re ".*$gdb_prompt $" { fail "print pmf" } | |
310 | timeout { fail "(timeout) print pmf" } | |
311 | } | |
312 | ||
313 | ||
314 | # Ptype a pointer to a pointer to a method | |
315 | ||
316 | send_gdb "ptype pmf_p\n" | |
317 | gdb_expect { | |
318 | -re "type = int \\( A::\\*\\*\\)\\(\\.\\.\\.\\)\r\n$gdb_prompt $" { | |
319 | pass "ptype pmf_p" | |
320 | } | |
321 | -re ".*$gdb_prompt $" { fail "ptype pmf_p" } | |
322 | timeout { fail "(timeout) ptype pmf_p" } | |
323 | } | |
324 | ||
325 | # print a pointer to a pointer to a method | |
326 | ||
327 | send_gdb "print pmf_p\n" | |
328 | gdb_expect { | |
329 | -re "\\$\[0-9\]* = \\(int \\( A::\\*\\*\\)\\(\\.\\.\\.\\)\\) $hex\r\n$gdb_prompt $" { | |
330 | pass "print pmf_p" | |
331 | } | |
332 | -re ".*$gdb_prompt $" { fail "print pmf_p" } | |
333 | timeout { fail "(timeout) print pmf_p" } | |
334 | } | |
335 | ||
336 | # print dereferenced pointer to method | |
337 | ||
338 | send_gdb "print a.*pmf\n" | |
339 | gdb_expect { | |
340 | -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" { | |
341 | pass "print a.*pmf (known aCC limitation)" | |
342 | } | |
343 | -re ".*$gdb_prompt $" { fail "print a.*pmf -- ??" } | |
344 | timeout { fail "(timeout) print a.*pmf" } | |
345 | } | |
346 | ||
347 | # print dereferenced pointer to method, using ->* | |
348 | ||
349 | send_gdb "print a_p->*pmf\n" | |
350 | gdb_expect { | |
351 | -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" { | |
352 | pass "print a_p->*pmf (known aCC limitation)" | |
353 | } | |
354 | -re ".*$gdb_prompt $" { fail "print a_p->*pmf -- ??" } | |
355 | timeout { fail "(timeout) print a_p->*pmf" } | |
356 | } | |
357 | ||
358 | # set the pointer to data member | |
359 | ||
360 | send_gdb "set var pmf = &A::foo\n" | |
361 | gdb_expect { | |
362 | -re "Assignment to pointers to methods not implemented with HP aCC\r\n$gdb_prompt $" { | |
363 | pass "set var pmf (known aCC limitation)" | |
364 | } | |
365 | -re ".*$gdb_prompt $" { fail "set var pmf -- ??" } | |
366 | timeout { fail "(timeout) set var pmf" } | |
367 | } | |
368 | ||
369 | # Try to dereference the pointer to method without any object | |
370 | ||
371 | send_gdb "print *pmf\n" | |
372 | gdb_expect { | |
373 | -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" { | |
374 | pass "attempt to print ptr to method without object" | |
375 | } | |
376 | -re ".*$gdb_prompt $" { fail "attempt to print ptr to method without object" } | |
377 | timeout { fail "(timeout) attempt to print ptr to method without object" } | |
378 | } | |
379 | ||
380 | # Try to ptype a dereference of the pointer to method without any object | |
381 | ||
382 | send_gdb "ptype *pmi\n" | |
383 | gdb_expect { | |
384 | -re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" { | |
385 | pass "attempt to ptype ptr to member without object" | |
386 | } | |
387 | -re ".*$gdb_prompt $" { fail "attempt to ptype ptr to member without object" } | |
388 | timeout { fail "(timeout) attempt to ptype ptr to member without object" } | |
389 | } | |
390 | ||
391 | # Check cast of pointer to member to integer | |
392 | send_gdb "print (int) pmi\n" | |
393 | gdb_expect { | |
394 | -re "\\$\[0-9\]* = 8\r\n$gdb_prompt $" { | |
395 | pass "casting pmi to int" | |
396 | } | |
397 | -re ".*$gdb_prompt $" { fail "casting pmi to int" } | |
398 | timeout { fail "(timeout) casting pmi to int" } | |
399 | } | |
400 | ||
401 | # Check cast of pointer to method to integer | |
402 | send_gdb "print (int) pmf\n" | |
403 | gdb_expect { | |
404 | -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" { | |
405 | pass "casting pmf to int (known aCC limitation)" | |
406 | } | |
407 | -re ".*$gdb_prompt $" { fail "casting pmf to int -- ??" } | |
408 | timeout { fail "(timeout) casting pmf to int" } | |
409 | } | |
410 | ||
411 | # Try to invoke a function through a pointer to data member | |
412 | send_gdb "print (a.*pmi)(3)\n" | |
413 | gdb_expect { | |
414 | -re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" { | |
415 | pass "print (a.*pmi)(3) -- error message should be different" | |
416 | } | |
417 | -re ".*$gdb_prompt $" { fail "print (a.*pmi)(3) -- ???" } | |
418 | timeout { fail "(timeout) print (a.*pmi)(3)" } | |
419 | } | |
420 | ||
421 | # Try to invoke a function through a pointer to a method | |
422 | send_gdb "print (a.*pmf)(3)\n" | |
423 | gdb_expect { | |
424 | -re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" { | |
425 | pass "print (a.*pmi)(3) -- known aCC limitation" | |
426 | } | |
427 | -re ".*$gdb_prompt $" { fail "print (a.*pmf)(3) -- ???" } | |
428 | timeout { fail "(timeout) print (a.*pmf)(3)" } | |
429 | } | |
430 | ||
431 | ||
432 | # Go past assignment of NULL to pmi | |
433 | send_gdb "next\n" | |
434 | gdb_expect { | |
435 | -re "\r\n85\[ \t\]*k = \\(a.\\*pmf\\)\\(3\\);\r\n$gdb_prompt $" { | |
436 | pass "next past 83" | |
437 | } | |
438 | -re ".*$gdb_prompt $" { fail "next past 83" } | |
439 | timeout { fail "(timeout) next past 83" } | |
440 | } | |
441 | ||
442 | #send_gdb "print pmi\n" | |
443 | #gdb_expect { | |
444 | # -re "Attempted dereference of null pointer-to-member\r\n$gdb_prompt $" { | |
445 | # pass "" | |
446 | # } | |
447 | # -re ".*$gdb_prompt $" { fail "" } | |
448 | # timeout { fail "(timeout) " } | |
449 | #} | |
450 | ||
451 | # Dereference the null pointer to member | |
452 | send_gdb "print a.*pmi\n" | |
453 | gdb_expect { | |
454 | -re "Attempted dereference of null pointer-to-member\r\n$gdb_prompt $" { | |
455 | pass "print a.*NULL" | |
456 | } | |
457 | -re ".*$gdb_prompt $" { fail "print a.*NULL" } | |
458 | timeout { fail "(timeout) print a.*NULL" } | |
459 | } | |
460 | ||
461 | ||
462 | # Go to another part of the program | |
463 | send_gdb "break 91\n" | |
464 | gdb_expect { | |
465 | -re "Breakpoint \[0-9\]*.*line 91\\.\r\n$gdb_prompt $" { | |
466 | pass "set break at 91" | |
467 | } | |
468 | -re ".*$gdb_prompt $" { fail "set break at 91" } | |
469 | timeout { fail "(timeout) set break at 91" } | |
470 | } | |
471 | ||
472 | send_gdb "continue\n" | |
473 | gdb_expect { | |
474 | -re "Continuing\\.\r\n\r\nBreakpoint.*at.*member-ptr\\.cc:91\r\n91\[ \t]*k = \\(a.\\*pmf\\)\\(4\\);\r\n$gdb_prompt $" { | |
475 | pass "continue to 91" | |
476 | } | |
477 | -re ".*$gdb_prompt $" { fail "continue to 91" } | |
478 | timeout { fail "(timeout) continue to 91" } | |
479 | } | |
480 | ||
481 | ||
482 | # Now check again that pmi works even when not set to | |
483 | # something that's at the beginning of the object | |
484 | ||
485 | send_gdb "print pmi\n" | |
486 | gdb_expect { | |
487 | -re "\\$\[0-9\]* = \\(int \\( A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" { | |
488 | pass "print pmi (2)" | |
489 | } | |
490 | -re ".*$gdb_prompt $" { fail "print pmi (2)" } | |
491 | timeout { fail "(timeout) print pmi (2)" } | |
492 | } | |
493 | ||
494 | ||
495 | # print dereferenced pointer to data member | |
496 | ||
497 | send_gdb "print a.*pmi\n" | |
498 | gdb_expect { | |
499 | -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" { | |
500 | pass "print a.*pmi (2)" | |
501 | } | |
502 | -re ".*$gdb_prompt $" { fail "print a.*pmi (2)" } | |
503 | timeout { fail "(timeout) print a.*pmi (2)" } | |
504 | } | |
505 | ||
506 | # print dereferenced pointer to data member | |
507 | # this time, dereferenced through a pointer | |
508 | ||
509 | send_gdb "print a_p->*pmi\n" | |
510 | gdb_expect { | |
511 | -re "\\$\[0-9\]* = 1331\r\n$gdb_prompt $" { | |
512 | pass "print a->*pmi" | |
513 | } | |
514 | -re ".*$gdb_prompt $" { fail "print a->*pmi (2)" } | |
515 | timeout { fail "(timeout) print a->*pmi (2)" } | |
516 | } | |
517 | ||
518 | ||
519 | # p a.*pmf - fail | |
520 | ||
521 | # p pmi | |
522 | ||
523 | # p a.*pmi | |
524 |