Add guality [p]type test.

Add a new type:var variant to the guality.exp testsuite to check that
gdb gets the correct type for a variable or function. To use it in a
guality test add something like:

/* { dg-final { gdb-test 50 "type:main" "int (int, char **)" } } */

Which will put a breakpoint at line 50 and check that the type of "main"
equals "int (int, char **)" according to gdb. The test harness will make
sure to squash all extra whitespace/newlines that gdb might use to make
comparisons of large structs easy.

gcc/testsuite/ChangeLog

	* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
	matching. Catch '<unknown type in ' to recognize older gdb versions.
	* gcc.dg/guality/const-volatile.c: New test.

From-SVN: r214139
This commit is contained in:
Mark Wielaard 2014-08-19 10:30:07 +00:00 committed by Mark Wielaard
parent 4f9b1c116e
commit a6dad7b658
3 changed files with 132 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2014-07-03 Mark Wielaard <mjw@redhat.com>
* lib/gcc-gdb-test.exp (gdb-test): Handle type:var for gdb ptype
matching. Catch '<unknown type in ' to recognize older gdb versions.
* gcc.dg/guality/const-volatile.c: New test.
2014-08-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/debug/dwarf2/nested-4.C: XFAIL on *-*-solaris2.1[1-9]* &&

View File

@ -0,0 +1,83 @@
/* debuginfo tests for combinations of const and volatile type qualifiers. */
/* { dg-do run } */
/* { dg-options "-g" } */
int i;
const int ci;
volatile int vi;
const volatile int cvi;
int *pi;
const int *pci;
volatile int *pvi;
const volatile int *pcvi;
int * const cip;
int * volatile vip;
int * const volatile cvip;
volatile struct
{
const long cli;
const signed char csc;
} vs;
struct foo
{
const long cli;
const signed char csc;
};
struct foo foo;
const struct foo cfoo;
volatile struct foo vfoo;
const volatile struct foo cvfoo;
typedef volatile signed char score;
score s;
const score cs;
static __attribute__((noclone, noinline)) int
f (const char *progname, volatile struct foo *dummy, const score s)
{
return progname == 0 || dummy == 0 || dummy->csc == s;
}
int
main (int argc, char **argv)
{
score as = argc;
struct foo dummy = { 1, 1 };
return f (argv[0], &dummy, as) - 1;
}
/* { dg-final { gdb-test 50 "type:main" "int (int, char **)" } } */
/* { dg-final { gdb-test 50 "type:i" "int" } } */
/* { dg-final { gdb-test 50 "type:ci" "const int" } } */
/* { dg-final { gdb-test 50 "type:vi" "volatile int" } } */
/* { dg-final { gdb-test 50 "type:cvi" "const volatile int" } } */
/* { dg-final { gdb-test 50 "type:pi" "int *" } } */
/* { dg-final { gdb-test 50 "type:pci" "const int *" } } */
/* { dg-final { gdb-test 50 "type:pvi" "volatile int *" } } */
/* { dg-final { gdb-test 50 "type:pcvi" "const volatile int *" } } */
/* { dg-final { gdb-test 50 "type:cip" "int * const" } } */
/* { dg-final { gdb-test 50 "type:vip" "int * volatile" } } */
/* { dg-final { gdb-test 50 "type:cvip" "int * const volatile" } } */
/* { dg-final { gdb-test 50 "type:vs" "volatile struct { const long cli; const signed char csc; }" } } */
/* { dg-final { gdb-test 50 "type:cvip" "int * const volatile" } } */
/* { dg-final { gdb-test 50 "type:foo" "struct foo { const long cli; const signed char csc; }" } } */
/* { dg-final { gdb-test 50 "type:cfoo" "const struct foo { const long cli; const signed char csc; }" } } */
/* { dg-final { gdb-test 50 "type:vfoo" "volatile struct foo { const long cli; const signed char csc; }" } } */
/* { dg-final { gdb-test 50 "type:cvfoo" "const volatile struct foo { const long cli; const signed char csc; }" } } */
/* { dg-final { gdb-test 58 "type:s" "volatile signed char" } } */
/* { dg-final { gdb-test 50 "type:cs" "const volatile signed char" } } */
/* { dg-final { gdb-test 50 "type:f" "int (const char *, volatile struct foo *, const score)" } } */

View File

@ -19,7 +19,12 @@
#
# Argument 0 is the line number on which to put a breakpoint
# Argument 1 is the name of the variable to be checked
# Argument 2 is the expected value of the variable
# possibly prefixed with type: to get the type of the variable
# instead of the value of the variable (the default).
# Argument 2 is the expected value (or type) of the variable
# When asking for the value, the expected value is produced
# calling print on it in gdb. When asking for the type it is
# the literal string with extra whitespace removed.
# Argument 3 handles expected failures and the like
proc gdb-test { args } {
if { ![isnative] || [is_remote target] } { return }
@ -39,6 +44,16 @@ proc gdb-test { args } {
upvar 2 name testcase
upvar 2 prog prog
# The command to run on the variable
set arg1 [lindex $args 1]
if { [string equal -length 5 "type:" $arg1] == 1 } {
set command "ptype"
set var [string range $arg1 5 end]
} else {
set command "print"
set var $arg1
}
set gdb_name $::env(GUALITY_GDB_NAME)
set testname "$testcase line [lindex $args 0] [lindex $args 1] == [lindex $args 2]"
set output_file "[file rootname [file tail $prog]].exe"
@ -47,8 +62,14 @@ proc gdb-test { args } {
set fd [open $cmd_file "w"]
puts $fd "break [lindex $args 0]"
puts $fd "run"
puts $fd "print [lindex $args 1]"
puts $fd "print [lindex $args 2]"
puts $fd "$command $var"
if { $command == "print" } {
# For values, let gdb interpret them by printing them.
puts $fd "print [lindex $args 2]"
} else {
# Since types can span multiple lines, we need an end marker.
puts $fd "echo TYPE_END\\n"
}
puts $fd "quit"
close $fd
@ -62,12 +83,13 @@ proc gdb-test { args } {
remote_expect target [timeout_value] {
# Too old GDB
-re "Unhandled dwarf expression|Error in sourced command file" {
-re "Unhandled dwarf expression|Error in sourced command file|<unknown type in " {
unsupported "$testname"
remote_close target
file delete $cmd_file
return
}
# print var; print expected
-re {[\n\r]\$1 = ([^\n\r]*)[\n\r]+\$2 = ([^\n\r]*)[\n\r]} {
set first $expect_out(1,string)
set second $expect_out(2,string)
@ -83,6 +105,23 @@ proc gdb-test { args } {
file delete $cmd_file
return
}
# ptype var;
-re {[\n\r]type = (.*)[\n\r][\n\r]TYPE_END[\n\r]} {
set type $expect_out(1,string)
# Squash all extra whitespace/newlines that gdb might use for
# "pretty printing" into one so result is just one line.
regsub -all {[\n\r\t ]+} $type " " type
set expected [lindex $args 2]
if { $type == $expected } {
pass "$testname"
} else {
send_log -- "$type != $expected\n"
fail "$testname"
}
remote_close target
file delete $cmd_file
return
}
timeout {
unsupported "$testname"
remote_close target