]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/testsuite/gdb.cp/ambiguous.exp
Reject ambiguous C++ field accesses (PR exp/26602)
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.cp / ambiguous.exp
index 4d01c108f302eaf8dbc5ef699a2e8ddb05cfeb40..b7fec1b2bb3d9bb523ea4203d745ace2ca4841f2 100644 (file)
 
 # This file is part of the gdb testsuite
 
-# tests relating to ambiguous class members
-# Written by Satish Pai <pai@apollo.hp.com> 1997-07-28
-
-# This file is part of the gdb testsuite
-
-#
-# test running programs
-#
-
+# Print out various class objects' members and check that the error
+# about the field or baseclass being ambiguous is emitted at the right
+# times.
 
 if { [skip_cplus_tests] } { continue }
 
@@ -47,187 +41,226 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
     return -1
 }
 
-#
-# set it up at a breakpoint so we can play with the variable values
-#
 if ![runto_main] then {
     perror "couldn't run to breakpoint"
     continue
 }
 
-send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
-    send_gdb "cont\n"
-    gdb_expect {
-        -re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
-            send_gdb "up\n"
-            gdb_expect {
-                -re ".*$gdb_prompt $" { pass "up from marker1" }
-                timeout { fail "up from marker1" }
-            }
-        }
-        -re "$gdb_prompt $" { fail "continue to marker1"  }
-        timeout { fail "(timeout) continue to marker1"  }
+# Run to a breakpoint after the variables have been initialized so we
+# can play with the variable values.
+
+set lineno [gdb_get_line_number "set breakpoint here"]
+
+gdb_breakpoint $lineno
+gdb_continue_to_breakpoint "breakpoint here"
+
+set number -?$decimal
+
+with_test_prefix "all vars" {
+    gdb_test "print a1" \
+       " = \{x = 1, y = 2\}"
+
+    gdb_test "print a2" \
+       " = \{x = 1, y = 2\}"
+
+    gdb_test "print a3" \
+       " = \{x = 1, y = 2\}"
+
+    gdb_test "print x" \
+       " = \{<A1> = \{x = 1, y = 2\}, <A2> = \{x = 3, y = 4\}, z = 5\}"
+
+    gdb_test "print l" \
+       " = \{<A1> = \{x = 1, y = 2\}, z = 3\}"
+
+    gdb_test "print m" \
+       " = \{<A2> = \{x = 1, y = 2\}, w = 3\}"
+
+    gdb_test "print n" \
+       " = \{<L> = \{<A1> = \{x = 1, y = 2\}, z = 7\}, <M> = \{<A2> = \{x = 3, y = 4\}, w = 5\}, r = 6\}"
+
+    gdb_test "print k" \
+       " = \{<A1> = \{x = 1, y = 2\}, i = 3\}"
+
+    gdb_test "print j" \
+       " = {<K> = {<A1> = {x = 1, y = 2}, i = 5}, <L> = {<A1> = {x = 3, y = 4}, z = 6}, j = 7}"
+
+    gdb_test "print jv" \
+       " = \{<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\}"
+
+    # No way to initialize one of the A1's, so just take any number there.
+    gdb_test "print jva1" \
+       " = \{<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\}"
+
+    gdb_test "print jva2" \
+       " = \{<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\}"
+
+    gdb_test "print jva1v" \
+       " = \{<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\}"
+}
+
+# Check that we can access all the fields correctly, using the same
+# syntax as used in the .cc file.  Keep the order here in sync with
+# the .cc file.
+with_test_prefix "all fields" {
+    gdb_test "print a1.x" " = 1"
+    gdb_test "print a1.y" " = 2"
+
+    gdb_test "print a2.x" " = 1"
+    gdb_test "print a2.y" " = 2"
+
+    gdb_test "print a3.x" " = 1"
+    gdb_test "print a3.y" " = 2"
+
+    gdb_test "print x.A1::x" " = 1"
+    gdb_test "print x.A1::y" " = 2"
+    gdb_test "print x.A2::x" " = 3"
+    gdb_test "print x.A2::y" " = 4"
+    gdb_test "print x.z" " = 5"
+
+    gdb_test "print l.x" " = 1"
+    gdb_test "print l.y" " = 2"
+    gdb_test "print l.z" " = 3"
+
+    gdb_test "print m.x" " = 1"
+    gdb_test "print m.y" " = 2"
+    gdb_test "print m.w" " = 3"
+
+    gdb_test "print n.A1::x" " = 1"
+    gdb_test "print n.A1::y" " = 2"
+    gdb_test "print n.A2::x" " = 3"
+    gdb_test "print n.A2::y" " = 4"
+    gdb_test "print n.w" " = 5"
+    gdb_test "print n.r" " = 6"
+    gdb_test "print n.z" " = 7"
+
+    gdb_test "print k.x" " = 1"
+    gdb_test "print k.y" " = 2"
+    gdb_test "print k.i" " = 3"
+
+    gdb_test "print j.K::x" " = 1"
+    gdb_test "print j.K::y" " = 2"
+    gdb_test "print j.L::x" " = 3"
+    gdb_test "print j.L::y" " = 4"
+    gdb_test "print j.i" " = 5"
+    gdb_test "print j.z" " = 6"
+    gdb_test "print j.j" " = 7"
+
+    gdb_test "print jv.x" " = 1"
+    gdb_test "print jv.y" " = 2"
+    gdb_test "print jv.i" " = 3"
+    gdb_test "print jv.z" " = 4"
+    gdb_test "print jv.jv" " = 5"
+
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva1.KV::x" " = 1"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva1.KV::y" " = 2"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva1.LV::x" " = 3"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva1.LV::y" " = 4"
+    gdb_test "print jva1.z" " = 5"
+    gdb_test "print jva1.i" " = 6"
+    gdb_test "print jva1.jva1" "= 7"
+
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva2.KV::x" " = 1"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva2.KV::y" " = 2"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva2.LV::x" " = 3"
+    setup_kfail "c++/26550" *-*-*
+    gdb_test "print jva2.LV::y" " = 4"
+    gdb_test "print jva2.A2::x" " = 5"
+    gdb_test "print jva2.A2::y" " = 6"
+    gdb_test "print jva2.z" " = 7"
+    gdb_test "print jva2.i" " = 8"
+    gdb_test "print jva2.jva2" "= 9"
+
+    gdb_test "print jva1v.x" " = 1"
+    gdb_test "print jva1v.y" " = 2"
+    gdb_test "print jva1v.z" " = 3"
+    gdb_test "print jva1v.i" " = 4"
+    gdb_test "print jva1v.jva1v" " = 5"
+}
+
+# Test that printing WHAT reports an error about FIELD being ambiguous
+# in TYPE, and that the candidates are CANDIDATES.
+proc test_ambiguous {what field type candidates} {
+    set msg "Request for member '$field' is ambiguous in type '$type'. Candidates are:"
+
+    foreach c $candidates {
+       set c_re [string_to_regexp $c]
+       append msg "\r\n  $c_re"
     }
 
-# print out various class objects' members.  The values aren't
-# important, just check that the warning is emitted at the
-# right times. 
+    gdb_test "print $what" $msg
+}
 
 # X is derived from A1 and A2; both A1 and A2 have a member 'x'
-setup_kfail gdb/26602 *-*-*
-send_gdb "print x.x\n"
-gdb_expect {
-   -re "warning: x ambiguous; using X::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print x.x"
-   }
-   -re "warning: x ambiguous; using X::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print x.x"
-   }
-   -re ".*$gdb_prompt $" { fail "print x.x" }
-   timeout { fail "(timeout) print x.x" }
+test_ambiguous "x.x" "x" "X" {
+    "'int A1::x' (X -> A1)"
+    "'int A2::x' (X -> A2)"
 }
 
-
 # N is derived from A1 and A2, but not immediately -- two steps
 # up in the hierarchy. Both A1 and A2 have a member 'x'.
-setup_kfail gdb/26602 *-*-*
-send_gdb "print n.x\n"
-gdb_expect {
-   -re "warning: x ambiguous; using N::M::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print n.x"
-   }
-   -re "warning: x ambiguous; using N::L::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print n.x"
-   }
-   -re ".*$gdb_prompt $" { fail "print n.x" }
-   timeout { fail "(timeout) print n.x" }
+test_ambiguous "n.x" "x" "N" {
+    "'int A1::x' (N -> L -> A1)"
+    "'int A2::x' (N -> M -> A2)"
 }
 
-# J is derived from A1 twice.  A1 has a member x. 
-setup_kfail gdb/26602 *-*-*
-send_gdb "print j.x\n"
-gdb_expect {
-   -re "warning: x ambiguous; using J::L::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print j.x"
-   }
-   -re "warning: x ambiguous; using J::K::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print j.x"
-   }
-   -re ".*$gdb_prompt $" { fail "print j.x" }
-   timeout { fail "(timeout) print j.x" }
+# J is derived from A1 twice.  A1 has a member x.
+test_ambiguous "j.x" "x" "J" {
+    "'int A1::x' (J -> K -> A1)"
+    "'int A1::x' (J -> L -> A1)"
 }
 
 # JV is derived from A1 but A1 is a virtual base. Should not
-# report an ambiguity in this case. 
-send_gdb "print jv.x\n"
-gdb_expect {
-   -re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       fail "print jv.x (ambiguity reported)"
-   }
-   -re "\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print jv.x" }
-   -re ".*$gdb_prompt $" { fail "print jv.x (??)" }
-   timeout { fail "(timeout) print jv.x" }
-}
+# report an ambiguity in this case.
+gdb_test "print jv.x" " = 1"
 
 # JVA1 is derived from A1; A1 occurs as a virtual base in two
 # ancestors, and as a non-virtual immediate base. Ambiguity must
-# be reported. 
-setup_kfail gdb/26602 *-*-*
-send_gdb "print jva1.x\n"
-gdb_expect {
-   -re "warning: x ambiguous; using JVA1::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print jva1.x"
-   }
-   -re "warning: x ambiguous; using JVA1::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print jva1.x"
-   }
-   -re ".*$gdb_prompt $" { fail "print jva1.x" }
-   timeout { fail "(timeout) print jva1.x" }
+# be reported.
+test_ambiguous "jva1.x" "x" "JVA1" {
+    "'int A1::x' (JVA1 -> KV -> A1)"
+    "'int A1::x' (JVA1 -> A1)"
 }
 
 # JVA2 is derived from A1 & A2; A1 occurs as a virtual base in two
 # ancestors, and A2 is a non-virtual immediate base. Ambiguity must
 # be reported as A1 and A2 both have a member 'x'.
-setup_kfail gdb/26602 *-*-*
-send_gdb "print jva2.x\n"
-gdb_expect {
-   -re "warning: x ambiguous; using JVA2::A2::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print jva2.x"
-   }
-   -re "warning: x ambiguous; using JVA2::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       pass "print jva2.x"
-   }
-   -re ".*$gdb_prompt $" { fail "print jva2.x" }
-   timeout { fail "(timeout) print jva2.x" }
+test_ambiguous "jva2.x" "x" "JVA2" {
+    "'int A1::x' (JVA2 -> KV -> A1)"
+    "'int A2::x' (JVA2 -> A2)"
 }
 
 # JVA1V is derived from A1; A1 occurs as a virtual base in two
 # ancestors, and also as a virtual immediate base. Ambiguity must
 # not be reported.
-send_gdb "print jva1v.x\n"
-gdb_expect {
-   -re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" {
-       fail "print jva1v.x (ambiguity reported)"
-   }
-   -re "\\$\[0-9\]* = \[-\]*\[0-9\]*\r\n$gdb_prompt $" { pass "print jva1v.x" }
-   -re ".*$gdb_prompt $" { fail "print jva1v.x (??)" }
-   timeout { fail "(timeout) print jva1v.x" }
-}
+gdb_test "print jva1v.x" " = 1"
 
 # Now check for ambiguous bases.
 
 # J is derived from A1 twice; report ambiguity if a J is
 # cast to an A1.
-setup_kfail gdb/26602 *-*-*
-send_gdb "print (A1)j\n"
-gdb_expect {
-   -re "warning: A1 ambiguous; using J::L::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       pass "print (A1)j"
-   }
-   -re "warning: A1 ambiguous; using J::K::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       pass "print (A1)j"
-   }
-   -re ".*$gdb_prompt $" { fail "print (A1)j" }
-   timeout { fail "(timeout) print (A1)j" }
-}
+gdb_test "print (A1)j" "base class 'A1' is ambiguous in type 'J'"
 
 # JV is derived from A1 twice, but A1 is a virtual base; should
 # not report ambiguity when a JV is cast to an A1.
-send_gdb "print (A1)jv\n"
-gdb_expect {
-   -re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       fail "print (A1)jv (ambiguity reported)"
-   }
-   -re "\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" { pass "print (A1)jv" }
-   -re ".*$gdb_prompt $" { fail "print (A1)jv (??)" }
-   timeout { fail "(timeout) print (A1)jv" }
-}
+gdb_test "print (A1)jv" " = {x = 1, y = 2}"
 
 # JVA1 is derived from A1; A1 is a virtual base and also a
 # non-virtual base.  Must report ambiguity if a JVA1 is cast to an A1.
-setup_kfail gdb/26602 *-*-*
-send_gdb "print (A1)jva1\n"
-gdb_expect {
-   -re "warning: A1 ambiguous; using JVA1::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       pass "print (A1)jva1"
-   }
-   -re "warning: A1 ambiguous; using JVA1::KV::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       pass "print (A1)jva1"
-   }
-   -re ".*$gdb_prompt $" { fail "print (A1)jva1" }
-   timeout { fail "(timeout) print (A1)jva1" }
-}
+gdb_test "print (A1)jva1" "base class 'A1' is ambiguous in type 'JVA1'"
+
+# Add an intermediate cast to KV, and it should work.
+setup_kfail "c++/26550" *-*-*
+gdb_test "print (KV)jva1" " = \{<A1> = \{x = 3, y = 4\}, _vptr.KV = $hex <VTT for KV>, i = 6\}"
+setup_kfail "c++/26550" *-*-*
+gdb_test "print (A1)(KV)jva1" " = \{x = 3, y = 4\}"
 
 # JVA1V is derived from A1; A1 is a virtual base indirectly
 # and also directly; must not report ambiguity when a JVA1V is cast to an A1.
-send_gdb "print (A1)jva1v\n"
-gdb_expect {
-   -re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" {
-       fail "print (A1)jva1v (ambiguity reported)"
-   }
-   -re "\\$\[0-9\]* = \{x = \[-\]*\[0-9\]*, y = \[-\]*\[0-9\]*\}\r\n$gdb_prompt $" { pass "print (A1)jva1v"
-   }
-   -re ".*$gdb_prompt $" { fail "print (A1)jva1v (??)" }
-   timeout { fail "(timeout) print (A1)jva1v" }
-}
-
+gdb_test "print (A1)jva1v" " = {x = 1, y = 2}"