]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp
Update copyright year range in all GDB files
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / whatis-ptype-typedefs.exp
CommitLineData
e2882c85 1# Copyright 2017-2018 Free Software Foundation, Inc.
c973d0aa
PA
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 3 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, see <http://www.gnu.org/licenses/>.
15
16# Test "whatis"/"ptype" of different typedef types, and of expressions
17# involving casts to/from different typedefs.
18#
19# Particularly, when "whatis" is given a type name directly, it should
20# strip one (and only one) typedef level. Otherwise, it should not
21# strip any typedef at all. GDB used to incorrectly strip typedefs of
22# expressions involving casts to typedef types. E.g., (gdb) print
23# (int_typedef)0" shall result in a value of type "int_typedef", not
24# "int".
25
26standard_testfile
27
28# Prepare for testing in language LANG. Lang can be "c" or "c++".
29
30proc prepare {lang} {
31 global srcfile testfile
32
33 if [target_info exists no_long_long] {
34 set options [list debug additional_flags=-DNO_LONG_LONG]
35 } else {
36 set options [list debug]
37 }
38
39 if {$lang == "c++"} {
40 lappend options c++
41 set out $testfile-cxx
42 } else {
43 set out $testfile-c
44 }
45
46 if { [prepare_for_testing "failed to prepare" \
47 ${out} [list $srcfile] $options] } {
48 return -1
49 }
50
51 if ![runto_main] then {
52 fail "can't run to main"
53 return 0
54 }
55}
56
57# The following list is layed out as a table. It is composed by
58# sub-lists (lines), with each line representing one whatis/ptype
59# test. The sub-list (line) elements (columns) are (in order):
60#
61# EXP - The user expression passed to whatis/ptype.
62#
63# WHATIS - What "whatis" should print.
64#
65# If the EXP column is a type name, then this will be the same type,
66# with one (and only one) typedef level removed. Otherwise, this is
67# the type of the expression on the first column, with all typedefs
68# preserved.
69#
70# PTYPE - What "ptype" should print.
71#
72# This is always the type of the input type/expression stripped from
73# all typedefs.
74#
75# LANGUAGE - If the line is language-specific, which language.
76#
77# This can be "c" or "c++".
78#
79# Columns in the table represent:
80 # EXP # whatis # ptype # language
81set table {
82 {"void_typedef" "void" "void"}
83 {"void_typedef2" "void_typedef" "void"}
84
85 {"int_typedef" "int" "int"}
86 {"int_typedef2" "int_typedef" "int"}
87 {"v_int_typedef" "int_typedef" "int"}
88 {"v_int_typedef2" "int_typedef2" "int"}
89
90 {"float_typedef" "float" "float"}
91 {"float_typedef2" "float_typedef" "float"}
92 {"v_float_typedef" "float_typedef" "float"}
93 {"v_float_typedef2" "float_typedef2" "float"}
94
73fcf641
PA
95 {"double_typedef" "double" "double"}
96 {"double_typedef2" "double_typedef" "double"}
97 {"v_double_typedef" "double_typedef" "double"}
98 {"v_double_typedef2" "double_typedef2" "double"}
99
100 {"long_double_typedef" "long double" "long double"}
101 {"long_double_typedef2" "long_double_typedef" "long double"}
102 {"v_long_double_typedef" "long_double_typedef" "long double"}
103 {"v_long_double_typedef2" "long_double_typedef2" "long double"}
104
c973d0aa
PA
105 {"colors_typedef" "(enum )?colors" "enum colors( : unsigned int)? {red, green, blue}"}
106 {"colors_typedef2" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
107 {"v_colors_typedef" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
108 {"v_colors_typedef2" "colors_typedef2" "enum colors( : unsigned int)? {red, green, blue}"}
109
110 {"func_ftype" "void \\(void\\)" "void \\(void\\)"}
111 {"func_ftype2" "func_ftype" "void \\(void\\)"}
112
113 {"func_ftype *" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
114 {"func_ftype2 *" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
115 {"v_func_ftype" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
116 {"v_func_ftype2" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
117
118 {"v_t_struct_typedef" "t_struct_typedef" "struct t_struct {.* member;.*}"}
119 {"v_t_struct_typedef2" "t_struct_typedef2" "struct t_struct {.* member;.*}"}
120 {"v_t_struct_union_wrapper_typedef" "t_struct_union_wrapper_typedef" "union t_struct_union_wrapper {.*base;.*}"}
121 {"v_t_struct_union_wrapper_typedef2" "t_struct_union_wrapper_typedef2" "union t_struct_union_wrapper {.*base;.*}"}
122 {"v_uchar_array_t_struct_typedef" "uchar_array_t_struct_typedef" "unsigned char \\[.*\\]"}
123 {"v_uchar_array_t_struct_typedef2" "uchar_array_t_struct_typedef2" "unsigned char \\[.*\\]"}
124
125 {"v_ns_Struct_typedef" "ns_Struct_typedef" "struct ns::Struct {.* method.*}" "c++"}
126
127 {"ns_method_ptr_typedef"
128 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
129 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
130 "c++"}
131
132 {"ns::method_ptr_typedef"
133 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
134 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
135 "c++"}
136
137 {"ns_method_ptr_typedef2"
138 "ns_method_ptr_typedef"
139 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
140 "c++"}
141
142 {"ns::method_ptr_typedef2"
143 "ns::method_ptr_typedef"
144 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
145 "c++"}
146
147 {"ns::Struct::method"
148 "void \\(ns::Struct \\* const\\)"
149 "void \\(ns::Struct \\* const\\)"
150 "c++"}
151}
152
153# The 4th column above is optional. If present, it indicates that the
154# line should only be tested in the specified language. This is a
155# helper function that checks whether LINE's language matches LANG.
156proc line_lang_match {line lang} {
157 if {[llength $line] <= 3} {
158 return true
159 }
160
161 set line_lang [lindex $line 3]
162 if {$line_lang == "" || $lang == $line_lang} {
163 return true
164 }
165
166 return false
167}
168
169# Run tests in language LANG.
170
171proc run_tests {lang} {
172 global table
173 global gdb_prompt
174
175 # Test passing all EXP in the list/table above to whatis/ptype,
176 # and check what comes out.
177 with_test_prefix "whatis/ptype" {
178 foreach line $table {
179 set type [lindex $line 0]
180 set whatis [lindex $line 1]
181 set ptype [lindex $line 2]
182
183 if {![line_lang_match $line $lang]} {
184 continue
185 }
186
187 # GCC doesn't record the target type of "typedef of
188 # typedef of void" types in the DWARF. See
189 # <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81267>.
190 # Handle that case manually in order to be able to xfail
191 # it.
192 if {$type == "void_typedef2"} {
193 set test "whatis $type"
194 gdb_test_multiple $test $test {
195 -re "type = void\r\n$gdb_prompt $" {
196 # gcc/81267.
197 setup_xfail "*-*-*"
198 fail "$test (void)"
199 }
200 -re "type = void_typedef\r\n$gdb_prompt $" {
201 pass $test
202 }
203 }
204 } else {
205 gdb_test "whatis $type" "type = $whatis"
206 }
207
208 gdb_test "ptype $type" "type = $ptype"
209 }
210 }
211
73fcf641
PA
212 # If floats and pointers have the same size on this architecture,
213 # then casting from array/function to float works, because
214 # arrays/functions first decay to pointers, and then GDB's cast is
215 # more general than a C cast and accepts any two types of the same
216 # length.
217 set float_ptr_same_size \
218 [get_integer_valueof "sizeof (float) == sizeof (void *)" -1]
219
220 # Ditto double.
221 set double_ptr_same_size \
222 [get_integer_valueof "sizeof (double) == sizeof (void *)" -1]
223
224 # Ditto long double.
225 set long_double_ptr_same_size \
226 [get_integer_valueof "sizeof (long double) == sizeof (void *)" -1]
227
c973d0aa
PA
228 # Test converting/casting all variables in the first column of the
229 # table to all types (found in the first column of the table).
230 # The aggregates are all defined to be the same size so that
231 # casting actually works. (GDB's casting operator is more general
232 # than a C cast.)
233 #
234 # The main idea here is testing all the different paths in the
235 # value casting code in GDB (value_cast), making sure typedefs are
236 # preserved.
237 with_test_prefix "cast" {
238 foreach line1 $table {
239 set from [lindex $line1 0]
240
241 if {![line_lang_match $line1 $lang]} {
242 continue
243 }
244
245 foreach line2 $table {
246 set to [lindex $line2 0]
247 set whatis [lindex $line2 1]
248 set ptype [lindex $line2 2]
249
250 if {![line_lang_match $line2 $lang]} {
251 continue
252 }
253
254 # We try all combinations, even those that don't
255 # parse, or are invalid, to catch the case of a
256 # regression making them inadvertently valid. For
257 # example, these convertions are invalid:
258 #
73fcf641 259 # float <-> array [iff sizeof pointer != sizeof float]
c973d0aa
PA
260 # array -> function (not function pointer)
261 # array -> member_ptr
262 #
263 # while these are invalid syntax:
264 #
265 # (anything) type
266 # (var) anything
267 # (method) anything [not method pointer]
268 # (float) method
269 #
270 if {([string match "v_*" $to]
271 || (![string match "v_*" $from] && ![string match "*method" $from])
272 || [string match "*method" $to])} {
273 gdb_test "whatis ($to) $from" "syntax error.*" "whatis ($to) $from (syntax)"
274 gdb_test "ptype ($to) $from" "syntax error.*" "ptype ($to) $from (syntax)"
275 } elseif {([string match "*float*" $from] && [string match "*array*" $to])
73fcf641
PA
276 || (!$float_ptr_same_size
277 && ([string match "float*" $to] && [string match "*array*" $from]
278 || [string match "float*" $to] && [string match "*method" $from]))
279 || (!$double_ptr_same_size
280 && ([string match "double*" $to] && [string match "*array*" $from]
281 || [string match "double*" $to] && [string match "*method" $from]))
282 || (!$long_double_ptr_same_size
283 && ([string match "long_double*" $to] && [string match "*array*" $from]
284 || [string match "long_double*" $to] && [string match "*method" $from]))
c973d0aa
PA
285 || ([string match "*ftype" $to] && [string match "*array*" $from])
286 || ([string match "*ftype2" $to] && [string match "*array*" $from])
287 || ([string match "*ftype" $to] && [string match "*method" $from])
288 || ([string match "*ftype2" $to] && [string match "*method" $from])
289 || ([string match "*method_ptr*" $to] && [string match "*method" $from])
290 || ([string match "*method_ptr*" $to] && [string match "*array*" $from])} {
291 gdb_test "whatis ($to) $from" "Invalid cast." "whatis ($to) $from (invalid)"
292 gdb_test "ptype ($to) $from" "Invalid cast." "ptype ($to) $from (invalid)"
293 } else {
294 gdb_test "whatis ($to) $from" "type = [string_to_regexp $to]"
295 gdb_test "ptype ($to) $from" "type = $ptype"
296 }
297 }
298 }
299 }
300}
301
302foreach_with_prefix lang {"c" "c++"} {
303 prepare $lang
304 run_tests $lang
305}