1 # Copyright 2017-2019 Free Software Foundation, Inc.
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.
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.
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/>.
16 # Test "whatis"/"ptype" of different typedef types, and of expressions
17 # involving casts to/from different typedefs.
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
28 # Prepare for testing in language LANG. Lang can be "c" or "c++".
31 global srcfile testfile
33 if [target_info exists no_long_long] {
34 set options [list debug additional_flags=-DNO_LONG_LONG]
36 set options [list debug]
46 if { [prepare_for_testing "failed to prepare" \
47 ${out} [list $srcfile] $options] } {
51 if ![runto_main] then {
52 fail "can't run to main"
59 # The following list is layed out as a table. It is composed by
60 # sub-lists (lines), with each line representing one whatis/ptype
61 # test. The sub-list (line) elements (columns) are (in order):
63 # EXP - The user expression passed to whatis/ptype.
65 # WHATIS - What "whatis" should print.
67 # If the EXP column is a type name, then this will be the same type,
68 # with one (and only one) typedef level removed. Otherwise, this is
69 # the type of the expression on the first column, with all typedefs
72 # PTYPE - What "ptype" should print.
74 # This is always the type of the input type/expression stripped from
77 # LANGUAGE - If the line is language-specific, which language.
79 # This can be "c" or "c++".
81 # Columns in the table represent:
82 # EXP # whatis # ptype # language
84 {"void_typedef" "void" "void"}
85 {"void_typedef2" "void_typedef" "void"}
87 {"int_typedef" "int" "int"}
88 {"int_typedef2" "int_typedef" "int"}
89 {"v_int_typedef" "int_typedef" "int"}
90 {"v_int_typedef2" "int_typedef2" "int"}
92 {"float_typedef" "float" "float"}
93 {"float_typedef2" "float_typedef" "float"}
94 {"v_float_typedef" "float_typedef" "float"}
95 {"v_float_typedef2" "float_typedef2" "float"}
97 {"double_typedef" "double" "double"}
98 {"double_typedef2" "double_typedef" "double"}
99 {"v_double_typedef" "double_typedef" "double"}
100 {"v_double_typedef2" "double_typedef2" "double"}
102 {"long_double_typedef" "long double" "long double"}
103 {"long_double_typedef2" "long_double_typedef" "long double"}
104 {"v_long_double_typedef" "long_double_typedef" "long double"}
105 {"v_long_double_typedef2" "long_double_typedef2" "long double"}
107 {"colors_typedef" "(enum )?colors" "enum colors( : unsigned int)? {red, green, blue}"}
108 {"colors_typedef2" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
109 {"v_colors_typedef" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
110 {"v_colors_typedef2" "colors_typedef2" "enum colors( : unsigned int)? {red, green, blue}"}
112 {"func_ftype" "void \\(void\\)" "void \\(void\\)"}
113 {"func_ftype2" "func_ftype" "void \\(void\\)"}
115 {"func_ftype *" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
116 {"func_ftype2 *" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
117 {"v_func_ftype" "func_ftype \\*" "void \\(\\*\\)\\(void\\)"}
118 {"v_func_ftype2" "func_ftype2 \\*" "void \\(\\*\\)\\(void\\)"}
120 {"v_t_struct_typedef" "t_struct_typedef" "struct t_struct {.* member;.*}"}
121 {"v_t_struct_typedef2" "t_struct_typedef2" "struct t_struct {.* member;.*}"}
122 {"v_t_struct_union_wrapper_typedef" "t_struct_union_wrapper_typedef" "union t_struct_union_wrapper {.*base;.*}"}
123 {"v_t_struct_union_wrapper_typedef2" "t_struct_union_wrapper_typedef2" "union t_struct_union_wrapper {.*base;.*}"}
124 {"v_uchar_array_t_struct_typedef" "uchar_array_t_struct_typedef" "unsigned char \\[.*\\]"}
125 {"v_uchar_array_t_struct_typedef2" "uchar_array_t_struct_typedef2" "unsigned char \\[.*\\]"}
127 {"v_ns_Struct_typedef" "ns_Struct_typedef" "struct ns::Struct {.* method.*}" "c++"}
129 {"ns_method_ptr_typedef"
130 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
131 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
134 {"ns::method_ptr_typedef"
135 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
136 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
139 {"ns_method_ptr_typedef2"
140 "ns_method_ptr_typedef"
141 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
144 {"ns::method_ptr_typedef2"
145 "ns::method_ptr_typedef"
146 "void \\(ns::Struct::\\*\\)\\(ns::Struct \\* const\\)"
149 {"ns::Struct::method"
150 "void \\(ns::Struct \\* const\\)"
151 "void \\(ns::Struct \\* const\\)"
155 # The 4th column above is optional. If present, it indicates that the
156 # line should only be tested in the specified language. This is a
157 # helper function that checks whether LINE's language matches LANG.
158 proc line_lang_match {line lang} {
159 if {[llength $line] <= 3} {
163 set line_lang [lindex $line 3]
164 if {$line_lang == "" || $lang == $line_lang} {
171 # Run tests in language LANG.
173 proc run_tests {lang} {
177 # Test passing all EXP in the list/table above to whatis/ptype,
178 # and check what comes out.
179 with_test_prefix "whatis/ptype" {
180 foreach line $table {
181 set type [lindex $line 0]
182 set whatis [lindex $line 1]
183 set ptype [lindex $line 2]
185 if {![line_lang_match $line $lang]} {
189 # GCC doesn't record the target type of "typedef of
190 # typedef of void" types in the DWARF. See
191 # <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81267>.
192 # Handle that case manually in order to be able to xfail
194 if {$type == "void_typedef2"} {
195 set test "whatis $type"
196 gdb_test_multiple $test $test {
197 -re "type = void\r\n$gdb_prompt $" {
202 -re "type = void_typedef\r\n$gdb_prompt $" {
207 gdb_test "whatis $type" "type = $whatis"
210 gdb_test "ptype $type" "type = $ptype"
214 # If floats and pointers have the same size on this architecture,
215 # then casting from array/function to float works, because
216 # arrays/functions first decay to pointers, and then GDB's cast is
217 # more general than a C cast and accepts any two types of the same
219 set float_ptr_same_size \
220 [get_integer_valueof "sizeof (float) == sizeof (void *)" -1]
223 set double_ptr_same_size \
224 [get_integer_valueof "sizeof (double) == sizeof (void *)" -1]
227 set long_double_ptr_same_size \
228 [get_integer_valueof "sizeof (long double) == sizeof (void *)" -1]
230 # Test converting/casting all variables in the first column of the
231 # table to all types (found in the first column of the table).
232 # The aggregates are all defined to be the same size so that
233 # casting actually works. (GDB's casting operator is more general
236 # The main idea here is testing all the different paths in the
237 # value casting code in GDB (value_cast), making sure typedefs are
239 with_test_prefix "cast" {
240 foreach line1 $table {
241 set from [lindex $line1 0]
243 if {![line_lang_match $line1 $lang]} {
247 foreach line2 $table {
248 set to [lindex $line2 0]
249 set whatis [lindex $line2 1]
250 set ptype [lindex $line2 2]
252 if {![line_lang_match $line2 $lang]} {
256 # We try all combinations, even those that don't
257 # parse, or are invalid, to catch the case of a
258 # regression making them inadvertently valid. For
259 # example, these convertions are invalid:
261 # float <-> array [iff sizeof pointer != sizeof float]
262 # array -> function (not function pointer)
263 # array -> member_ptr
265 # while these are invalid syntax:
269 # (method) anything [not method pointer]
272 if {([string match "v_*" $to]
273 || (![string match "v_*" $from] && ![string match "*method" $from])
274 || [string match "*method" $to])} {
275 gdb_test "whatis ($to) $from" "syntax error.*" "whatis ($to) $from (syntax)"
276 gdb_test "ptype ($to) $from" "syntax error.*" "ptype ($to) $from (syntax)"
277 } elseif {([string match "*float*" $from] && [string match "*array*" $to])
278 || (!$float_ptr_same_size
279 && ([string match "float*" $to] && [string match "*array*" $from]
280 || [string match "float*" $to] && [string match "*method" $from]))
281 || (!$double_ptr_same_size
282 && ([string match "double*" $to] && [string match "*array*" $from]
283 || [string match "double*" $to] && [string match "*method" $from]))
284 || (!$long_double_ptr_same_size
285 && ([string match "long_double*" $to] && [string match "*array*" $from]
286 || [string match "long_double*" $to] && [string match "*method" $from]))
287 || ([string match "*ftype" $to] && [string match "*array*" $from])
288 || ([string match "*ftype2" $to] && [string match "*array*" $from])
289 || ([string match "*ftype" $to] && [string match "*method" $from])
290 || ([string match "*ftype2" $to] && [string match "*method" $from])
291 || ([string match "*method_ptr*" $to] && [string match "*method" $from])
292 || ([string match "*method_ptr*" $to] && [string match "*array*" $from])} {
293 gdb_test "whatis ($to) $from" "Invalid cast." "whatis ($to) $from (invalid)"
294 gdb_test "ptype ($to) $from" "Invalid cast." "ptype ($to) $from (invalid)"
296 gdb_test "whatis ($to) $from" "type = [string_to_regexp $to]"
297 gdb_test "ptype ($to) $from" "type = $ptype"
304 foreach_with_prefix lang {"c" "c++"} {
305 if { [prepare $lang] } then {