]>
Commit | Line | Data |
---|---|---|
1d506c26 | 1 | # Copyright 1998-2024 Free Software Foundation, Inc. |
a0b3c4fd JM |
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 | |
e22f8b7c | 5 | # the Free Software Foundation; either version 3 of the License, or |
a0b3c4fd | 6 | # (at your option) any later version. |
e22f8b7c | 7 | # |
a0b3c4fd JM |
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. | |
e22f8b7c | 12 | # |
a0b3c4fd | 13 | # You should have received a copy of the GNU General Public License |
e22f8b7c | 14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
a0b3c4fd | 15 | |
a0b3c4fd JM |
16 | # This file is part of the gdb testsuite |
17 | ||
87a37e5e PA |
18 | # Print out various class objects' members and check that the error |
19 | # about the field or baseclass being ambiguous is emitted at the right | |
20 | # times. | |
a0b3c4fd | 21 | |
0b94d2b9 | 22 | require allow_cplus_tests |
d4f3574e | 23 | |
f5f3a911 | 24 | standard_testfile .cc |
a0b3c4fd | 25 | |
9f68b453 GB |
26 | set additional_flags "" |
27 | if {[test_compiler_info {gcc-[0-9]-*}]} { | |
28 | # GCCs prior to 10.1 do not support -Wno-inaccessible-base. | |
29 | set additional_flags "additional_flags=-w" | |
30 | } elseif {[test_compiler_info gcc*] || [test_compiler_info clang*]} { | |
31 | set additional_flags "additional_flags=-Wno-inaccessible-base" | |
32 | } | |
a0b3c4fd | 33 | |
9f68b453 GB |
34 | if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ |
35 | [list debug c++ $additional_flags]]} { | |
f5f3a911 | 36 | return -1 |
a0b3c4fd JM |
37 | } |
38 | ||
95701cae | 39 | if {![runto_main]} { |
cdd42066 | 40 | return |
a0b3c4fd JM |
41 | } |
42 | ||
87a37e5e PA |
43 | # Run to a breakpoint after the variables have been initialized so we |
44 | # can play with the variable values. | |
45 | ||
46 | set lineno [gdb_get_line_number "set breakpoint here"] | |
47 | ||
48 | gdb_breakpoint $lineno | |
49 | gdb_continue_to_breakpoint "breakpoint here" | |
50 | ||
51 | set number -?$decimal | |
52 | ||
53 | with_test_prefix "all vars" { | |
54 | gdb_test "print a1" \ | |
55 | " = \{x = 1, y = 2\}" | |
56 | ||
57 | gdb_test "print a2" \ | |
58 | " = \{x = 1, y = 2\}" | |
59 | ||
60 | gdb_test "print a3" \ | |
61 | " = \{x = 1, y = 2\}" | |
62 | ||
63 | gdb_test "print x" \ | |
64 | " = \{<A1> = \{x = 1, y = 2\}, <A2> = \{x = 3, y = 4\}, z = 5\}" | |
65 | ||
66 | gdb_test "print l" \ | |
67 | " = \{<A1> = \{x = 1, y = 2\}, z = 3\}" | |
68 | ||
69 | gdb_test "print m" \ | |
70 | " = \{<A2> = \{x = 1, y = 2\}, w = 3\}" | |
71 | ||
72 | gdb_test "print n" \ | |
73 | " = \{<L> = \{<A1> = \{x = 1, y = 2\}, z = 7\}, <M> = \{<A2> = \{x = 3, y = 4\}, w = 5\}, r = 6\}" | |
74 | ||
75 | gdb_test "print k" \ | |
76 | " = \{<A1> = \{x = 1, y = 2\}, i = 3\}" | |
77 | ||
78 | gdb_test "print j" \ | |
79 | " = {<K> = {<A1> = {x = 1, y = 2}, i = 5}, <L> = {<A1> = {x = 3, y = 4}, z = 6}, j = 7}" | |
80 | ||
81 | gdb_test "print jv" \ | |
82 | " = \{<KV> = \{<A1> = \{x = 1, y = 2\}, _vptr.KV = $hex <vtable for JV.*>, i = 3\}, <LV> = \{_vptr.LV = $hex <VTT for JV>, z = 4\}, jv = 5\}" | |
83 | ||
84 | # No way to initialize one of the A1's, so just take any number there. | |
85 | gdb_test "print jva1" \ | |
86 | " = \{<KV> = \{<A1> = \{x = 3, y = 4\}, _vptr.KV = $hex <vtable for JVA1.*>, i = 6\}, <LV> = \{_vptr.LV = $hex <VTT for JVA1>, z = 5\}, <A1> = \{x = $number, y = $number\}, jva1 = 7\}" | |
87 | ||
88 | gdb_test "print jva2" \ | |
89 | " = \{<KV> = \{<A1> = \{x = 3, y = 4\}, _vptr.KV = $hex <vtable for JVA2.*>, i = 8\}, <LV> = \{_vptr.LV = $hex <VTT for JVA2>, z = 7\}, <A2> = \{x = 5, y = 6\}, jva2 = 9\}" | |
90 | ||
91 | gdb_test "print jva1v" \ | |
92 | " = \{<KV> = \{<A1> = \{x = 1, y = 2\}, _vptr.KV = $hex <vtable for JVA1V+.*>, i = 4\}, <LV> = \{_vptr.LV = $hex <VTT for JVA1V>, z = 3\}, jva1v = 5\}" | |
93 | } | |
94 | ||
95 | # Check that we can access all the fields correctly, using the same | |
96 | # syntax as used in the .cc file. Keep the order here in sync with | |
97 | # the .cc file. | |
98 | with_test_prefix "all fields" { | |
99 | gdb_test "print a1.x" " = 1" | |
100 | gdb_test "print a1.y" " = 2" | |
101 | ||
102 | gdb_test "print a2.x" " = 1" | |
103 | gdb_test "print a2.y" " = 2" | |
104 | ||
105 | gdb_test "print a3.x" " = 1" | |
106 | gdb_test "print a3.y" " = 2" | |
107 | ||
108 | gdb_test "print x.A1::x" " = 1" | |
109 | gdb_test "print x.A1::y" " = 2" | |
110 | gdb_test "print x.A2::x" " = 3" | |
111 | gdb_test "print x.A2::y" " = 4" | |
112 | gdb_test "print x.z" " = 5" | |
113 | ||
114 | gdb_test "print l.x" " = 1" | |
115 | gdb_test "print l.y" " = 2" | |
116 | gdb_test "print l.z" " = 3" | |
117 | ||
118 | gdb_test "print m.x" " = 1" | |
119 | gdb_test "print m.y" " = 2" | |
120 | gdb_test "print m.w" " = 3" | |
121 | ||
122 | gdb_test "print n.A1::x" " = 1" | |
123 | gdb_test "print n.A1::y" " = 2" | |
124 | gdb_test "print n.A2::x" " = 3" | |
125 | gdb_test "print n.A2::y" " = 4" | |
bf716a53 | 126 | gdb_test "print n->A2::y" " = 4" |
87a37e5e PA |
127 | gdb_test "print n.w" " = 5" |
128 | gdb_test "print n.r" " = 6" | |
129 | gdb_test "print n.z" " = 7" | |
130 | ||
131 | gdb_test "print k.x" " = 1" | |
132 | gdb_test "print k.y" " = 2" | |
133 | gdb_test "print k.i" " = 3" | |
134 | ||
135 | gdb_test "print j.K::x" " = 1" | |
136 | gdb_test "print j.K::y" " = 2" | |
137 | gdb_test "print j.L::x" " = 3" | |
138 | gdb_test "print j.L::y" " = 4" | |
139 | gdb_test "print j.i" " = 5" | |
140 | gdb_test "print j.z" " = 6" | |
141 | gdb_test "print j.j" " = 7" | |
142 | ||
143 | gdb_test "print jv.x" " = 1" | |
144 | gdb_test "print jv.y" " = 2" | |
145 | gdb_test "print jv.i" " = 3" | |
146 | gdb_test "print jv.z" " = 4" | |
147 | gdb_test "print jv.jv" " = 5" | |
148 | ||
149 | setup_kfail "c++/26550" *-*-* | |
150 | gdb_test "print jva1.KV::x" " = 1" | |
151 | setup_kfail "c++/26550" *-*-* | |
152 | gdb_test "print jva1.KV::y" " = 2" | |
153 | setup_kfail "c++/26550" *-*-* | |
154 | gdb_test "print jva1.LV::x" " = 3" | |
155 | setup_kfail "c++/26550" *-*-* | |
156 | gdb_test "print jva1.LV::y" " = 4" | |
157 | gdb_test "print jva1.z" " = 5" | |
158 | gdb_test "print jva1.i" " = 6" | |
159 | gdb_test "print jva1.jva1" "= 7" | |
160 | ||
161 | setup_kfail "c++/26550" *-*-* | |
162 | gdb_test "print jva2.KV::x" " = 1" | |
163 | setup_kfail "c++/26550" *-*-* | |
164 | gdb_test "print jva2.KV::y" " = 2" | |
165 | setup_kfail "c++/26550" *-*-* | |
166 | gdb_test "print jva2.LV::x" " = 3" | |
167 | setup_kfail "c++/26550" *-*-* | |
168 | gdb_test "print jva2.LV::y" " = 4" | |
169 | gdb_test "print jva2.A2::x" " = 5" | |
170 | gdb_test "print jva2.A2::y" " = 6" | |
171 | gdb_test "print jva2.z" " = 7" | |
172 | gdb_test "print jva2.i" " = 8" | |
173 | gdb_test "print jva2.jva2" "= 9" | |
174 | ||
175 | gdb_test "print jva1v.x" " = 1" | |
176 | gdb_test "print jva1v.y" " = 2" | |
177 | gdb_test "print jva1v.z" " = 3" | |
178 | gdb_test "print jva1v.i" " = 4" | |
179 | gdb_test "print jva1v.jva1v" " = 5" | |
180 | } | |
181 | ||
182 | # Test that printing WHAT reports an error about FIELD being ambiguous | |
183 | # in TYPE, and that the candidates are CANDIDATES. | |
184 | proc test_ambiguous {what field type candidates} { | |
185 | set msg "Request for member '$field' is ambiguous in type '$type'. Candidates are:" | |
186 | ||
187 | foreach c $candidates { | |
188 | set c_re [string_to_regexp $c] | |
189 | append msg "\r\n $c_re" | |
a0b3c4fd JM |
190 | } |
191 | ||
87a37e5e PA |
192 | gdb_test "print $what" $msg |
193 | } | |
a0b3c4fd JM |
194 | |
195 | # X is derived from A1 and A2; both A1 and A2 have a member 'x' | |
87a37e5e PA |
196 | test_ambiguous "x.x" "x" "X" { |
197 | "'int A1::x' (X -> A1)" | |
198 | "'int A2::x' (X -> A2)" | |
a0b3c4fd JM |
199 | } |
200 | ||
a0b3c4fd JM |
201 | # N is derived from A1 and A2, but not immediately -- two steps |
202 | # up in the hierarchy. Both A1 and A2 have a member 'x'. | |
87a37e5e PA |
203 | test_ambiguous "n.x" "x" "N" { |
204 | "'int A1::x' (N -> L -> A1)" | |
205 | "'int A2::x' (N -> M -> A2)" | |
a0b3c4fd JM |
206 | } |
207 | ||
87a37e5e PA |
208 | # J is derived from A1 twice. A1 has a member x. |
209 | test_ambiguous "j.x" "x" "J" { | |
210 | "'int A1::x' (J -> K -> A1)" | |
211 | "'int A1::x' (J -> L -> A1)" | |
a0b3c4fd JM |
212 | } |
213 | ||
214 | # JV is derived from A1 but A1 is a virtual base. Should not | |
87a37e5e PA |
215 | # report an ambiguity in this case. |
216 | gdb_test "print jv.x" " = 1" | |
a0b3c4fd JM |
217 | |
218 | # JVA1 is derived from A1; A1 occurs as a virtual base in two | |
219 | # ancestors, and as a non-virtual immediate base. Ambiguity must | |
87a37e5e PA |
220 | # be reported. |
221 | test_ambiguous "jva1.x" "x" "JVA1" { | |
222 | "'int A1::x' (JVA1 -> KV -> A1)" | |
223 | "'int A1::x' (JVA1 -> A1)" | |
a0b3c4fd JM |
224 | } |
225 | ||
226 | # JVA2 is derived from A1 & A2; A1 occurs as a virtual base in two | |
227 | # ancestors, and A2 is a non-virtual immediate base. Ambiguity must | |
228 | # be reported as A1 and A2 both have a member 'x'. | |
87a37e5e PA |
229 | test_ambiguous "jva2.x" "x" "JVA2" { |
230 | "'int A1::x' (JVA2 -> KV -> A1)" | |
231 | "'int A2::x' (JVA2 -> A2)" | |
a0b3c4fd JM |
232 | } |
233 | ||
234 | # JVA1V is derived from A1; A1 occurs as a virtual base in two | |
235 | # ancestors, and also as a virtual immediate base. Ambiguity must | |
236 | # not be reported. | |
87a37e5e | 237 | gdb_test "print jva1v.x" " = 1" |
a0b3c4fd JM |
238 | |
239 | # Now check for ambiguous bases. | |
240 | ||
241 | # J is derived from A1 twice; report ambiguity if a J is | |
242 | # cast to an A1. | |
87a37e5e | 243 | gdb_test "print (A1)j" "base class 'A1' is ambiguous in type 'J'" |
a0b3c4fd JM |
244 | |
245 | # JV is derived from A1 twice, but A1 is a virtual base; should | |
246 | # not report ambiguity when a JV is cast to an A1. | |
87a37e5e | 247 | gdb_test "print (A1)jv" " = {x = 1, y = 2}" |
a0b3c4fd JM |
248 | |
249 | # JVA1 is derived from A1; A1 is a virtual base and also a | |
250 | # non-virtual base. Must report ambiguity if a JVA1 is cast to an A1. | |
87a37e5e PA |
251 | gdb_test "print (A1)jva1" "base class 'A1' is ambiguous in type 'JVA1'" |
252 | ||
253 | # Add an intermediate cast to KV, and it should work. | |
254 | setup_kfail "c++/26550" *-*-* | |
255 | gdb_test "print (KV)jva1" " = \{<A1> = \{x = 3, y = 4\}, _vptr.KV = $hex <VTT for KV>, i = 6\}" | |
256 | setup_kfail "c++/26550" *-*-* | |
257 | gdb_test "print (A1)(KV)jva1" " = \{x = 3, y = 4\}" | |
a0b3c4fd JM |
258 | |
259 | # JVA1V is derived from A1; A1 is a virtual base indirectly | |
260 | # and also directly; must not report ambiguity when a JVA1V is cast to an A1. | |
87a37e5e | 261 | gdb_test "print (A1)jva1v" " = {x = 1, y = 2}" |
a41ad347 BL |
262 | |
263 | # C++20 introduced a way to have ambiguous fields with the same byte offset. | |
264 | # This class explicitly tests for that. | |
265 | # if this is tested with a compiler that can't handle [[no_unique_address]] | |
266 | # the code should still correctly identify the ambiguity because of | |
267 | # different byte offsets. | |
268 | test_ambiguous "je.x" "x" "JE" { | |
269 | "'int A1::x' (JE -> A1)" | |
270 | "'empty A4::x' (JE -> A4)" | |
271 | } |