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