1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
# Copyright 2002-2014 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file is part of the gdb testsuite
# Test casting, especially between class types or pointer-to-class
# types.
# This file is part of the gdb testsuite
#
# test running programs
#
if { [skip_cplus_tests] } { continue }
standard_testfile .cc
if [get_compiler_info "c++"] {
return -1
}
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
return -1
}
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
gdb_test "break [gdb_get_line_number "casts.exp: 1"]" \
"Breakpoint.*at.* file .*" \
""
gdb_test "continue" "Breakpoint .* at .*casts.cc.*" ""
# Casting a pointer to a base class to a pointer to a derived class
# should yield the entire derived class. Until August 2002, GDB got
# the enclosing type on `(B *) a' wrong: while the value's static type
# was `B *', as it should be, the enclosing type (which is supposed to
# be the dynamic type) was `A *'. It's senseless to have a static
# type derived from the dynamic type; it should be the other way
# 'round. Dereferencing this oddly typed pointer yielded a value in
# which only the base class's members were initialized, since GDB uses
# the enclosing type to decide how many bytes to read. Members from
# the derived class were garbage, from GDB's address space.
gdb_test "print * (B *) a" ".* = {<A> = {a = 42}, b = 1729}" \
"cast base class pointer to derived class pointer"
# Check also that we get the same results from letting the compiler do
# the dereference.
gdb_test "print * b" ".* = {<A> = {a = 42}, b = 1729}" \
"let compiler cast base class pointer to derived class pointer"
# Check upcasting (it is trivial but still).
gdb_test "print * (A *) b" ".* = {a = 42}" \
"cast derived class pointer to base class pointer"
# Casting References.
# Check upcasting.
gdb_test "print (A &) br" ".* = .A &.* {a = 42}" \
"cast derived class reference to base class reference"
# Check downcasting.
gdb_test "print (B &) ar" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
"cast base class reference to derived class reference"
# Check compiler casting
gdb_test "print br" ".* = .B.* {<A> = {a = 42}, b = 1729}" \
"let compiler cast base class reference to derived class reference"
# A few basic tests of "new" casts.
gdb_test "print const_cast<const B *> (b)" " = \\(const B \\*\\) $hex" \
"basic test of const_cast"
gdb_test "print const_cast<void *> (0)" " = \\(void \\*\\) 0x0" \
"const_cast of 0"
gdb_test "print static_cast<A *> (b)" " = \\(A \\*\\) $hex" \
"basic test of static_cast"
gdb_test "print static_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
"static_cast to reference type"
gdb_test "print reinterpret_cast<A *> (b)" " = \\(A \\*\\) $hex" \
"basic test of reinterpret_cast"
gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
"test invalid reinterpret_cast"
gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
"reinterpret_cast to reference type"
# Test that keyword shadowing works.
gdb_test "whatis decltype(5)" " = double"
# Basic tests using typeof.
foreach opname {__typeof__ __typeof __decltype} {
gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
"old-style cast using $opname"
gdb_test "print static_cast<${opname}(a)> (b)" " = \\(A \\*\\) $hex" \
"static_cast using $opname"
gdb_test "print reinterpret_cast<${opname}(a)> (b)" " = \\(A \\*\\) $hex" \
"reinterpret_cast using $opname"
}
gdb_test "whatis __decltype(*a)" "type = A \\&"
# Tests of dynamic_cast.
set nonzero_hex "0x\[0-9A-Fa-f\]\[0-9A-Fa-f\]+"
gdb_test "print dynamic_cast<void> (a)" \
".*must be a pointer or reference type" \
"invalid dynamic_cast"
gdb_test "print dynamic_cast<void *> (0)" \
" = \\(void \\*\\) 0x0" \
"dynamic_cast of 0 to void*"
gdb_test "print dynamic_cast<Alpha *> (&derived)" \
" = \\(Alpha \\*\\) $nonzero_hex" \
"dynamic_cast simple upcast"
gdb_test "print dynamic_cast<Alpha *> (&doublyderived)" \
" = \\(Alpha \\*\\) $nonzero_hex" \
"dynamic_cast upcast to unique base"
gdb_test "print dynamic_cast<Alpha &> (derived)" \
" = \\(Alpha \\&\\) @$nonzero_hex: {.* = ${nonzero_hex}( <vtable for Derived.*>)?}" \
"dynamic_cast simple upcast to reference"
gdb_test "print dynamic_cast<Derived *> (ad)" \
" = \\(Derived \\*\\) ${nonzero_hex}( <vtable for Derived.*>)?" \
"dynamic_cast simple downcast"
gdb_test "print dynamic_cast<VirtuallyDerived *> (add)" \
" = \\(VirtuallyDerived \\*\\) $nonzero_hex" \
"dynamic_cast simple downcast to intermediate class"
gdb_test "print dynamic_cast<VirtuallyDerived *> (ad)" \
" = \\(VirtuallyDerived \\*\\) 0x0" \
"dynamic_cast to non-existing base"
gdb_test "print dynamic_cast<VirtuallyDerived &> (*ad)" \
"dynamic_cast failed" \
"dynamic_cast to reference to non-existing base"
gdb_test "print dynamic_cast<DoublyDerived *> (add)" \
" = \\(DoublyDerived \\*\\) ${nonzero_hex}( <vtable for DoublyDerived.*>)?" \
"dynamic_cast unique downcast"
gdb_test "print dynamic_cast<Gamma *> (add)" \
" = \\(Gamma \\*\\) $nonzero_hex" \
"dynamic_cast to sibling"
|