* Re: [patch/rfc] Rewrite "structs" testcase
@ 2003-11-12 16:51 Michael Elizabeth Chastain
0 siblings, 0 replies; 18+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-12 16:51 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
I'm getting 508 PASS / 71 KFAIL with three configurations,
but I'm getting 504 PASS / 4 FAIL / 71 KFAIL with gcc 3.3.2 -gdwarf-2.
The FAILs are
# gcc 3.3.2, binutils 2.14, -gdwarf-2
p/c fun2()
$1 = {a = 97 'a', b = 0 '\0'}
(gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-tll
p/c L2
$2 = {a = 97 'a', b = 0 '\0'}
(gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-tll
p/c fun2()
$1 = {a = 97 'a', b = 0 '\0'}
(gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-td
p/c L2
$2 = {a = 97 'a', b = 0 '\0'}
(gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-td
Do these look like bugs in the script or bugs in gdb? If they are
bugs in gdb then the test script is doing a good job.
Michael C
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [patch/rfc] Rewrite "structs" testcase @ 2003-11-12 18:30 Michael Elizabeth Chastain 0 siblings, 0 replies; 18+ messages in thread From: Michael Elizabeth Chastain @ 2003-11-12 18:30 UTC (permalink / raw) To: ac131313, mec.gnu; +Cc: gdb-patches Err, I botched the URL for the test tarball. ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-10-structs.tar.gz Michael C ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase @ 2003-11-12 18:13 Michael Elizabeth Chastain 2003-11-13 16:11 ` Andrew Cagney 0 siblings, 1 reply; 18+ messages in thread From: Michael Elizabeth Chastain @ 2003-11-12 18:13 UTC (permalink / raw) To: ac131313; +Cc: gdb-patches Ah, I ran it again with my full spectrum of compilers. gcc 2.95.3 gcc 3.2-7-rh gcc 3.3.2 gcc gcc-3_3-branch gcc HEAD With dwarf-2: gcc 3.3.2 and gcc gcc-3_3-branch gave the four extra FAILs. gcc 2.95.3, gcc 3.2-7-rh, and gcc HEAD gave pure PASS+KFAIL. With stabs+ All compilers gave pure PASS+KFAIL. Since it PASSes with gcc HEAD I am more sanguine that the questionable tests (the tests that FAIL with some gcc's) are good tests. Tarball with executable files, gdb.log, et cetera at ftp://ftp.shout.net/~mec/gdb/2003-11-10-structs.tar.gz Michael C ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-12 18:13 Michael Elizabeth Chastain @ 2003-11-13 16:11 ` Andrew Cagney 2003-11-17 15:59 ` Andrew Cagney 0 siblings, 1 reply; 18+ messages in thread From: Andrew Cagney @ 2003-11-13 16:11 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: ac131313, gdb-patches [-- Attachment #1: Type: text/plain, Size: 1576 bytes --] > Ah, I ran it again with my full spectrum of compilers. > > gcc 2.95.3 > gcc 3.2-7-rh > gcc 3.3.2 > gcc gcc-3_3-branch > gcc HEAD > > With dwarf-2: > gcc 3.3.2 and gcc gcc-3_3-branch gave the four extra FAILs. > gcc 2.95.3, gcc 3.2-7-rh, and gcc HEAD gave pure PASS+KFAIL. > > With stabs+ > All compilers gave pure PASS+KFAIL. > > Since it PASSes with gcc HEAD I am more sanguine that the > questionable tests (the tests that FAIL with some gcc's) > are good tests. These? > # gcc 3.3.2, binutils 2.14, -gdwarf-2 > > p/c fun2() > $1 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-tll > > p/c L2 > $2 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-tll > > p/c fun2() > $1 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-td > > p/c L2 > $2 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-td They should _never_ fail. Failing indicates a bug in GCC, GDB, or both, and that the testsuite is doing a good job. All those KFAILs are similar (only I've gaged them :-/). > Tarball with executable files, gdb.log, et cetera at > > ftp://ftp.shout.net/~mec/gdb/2003-11-10-structs.tar.gz > > Michael C And here's todays version. Change is to report this problem: KFAIL: gdb.base/structs.exp: return and finish consistent; return 1 structs-tc (PRMS: gdb/1444) explicitly. It makes understanding the results easier. that's definitly it! Andrew [-- Attachment #2: structs.c --] [-- Type: text/plain, Size: 9987 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif #ifndef tR typedef tQ tR; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD d; }; struct struct5 {tA a; tB b; tC c; tD d; tE e; }; struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } struct struct18 fun18() { return foo18; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } #ifdef PROTOTYPES void Fun18(struct struct18 foo18) #else void Fun18(foo18) struct struct18 foo18; #endif { L18 = foo18; } zed () { L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; L15.o = L16.o = L17.o = L18.o = 'Z'; L16.p = L17.p = L18.p = 'Z'; L17.q = L18.q = 'Z'; L18.r = 'Z'; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif int i; Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); Fun18(foo18); /* An infinite loop that first clears all the variables and then calls each function. This "hack" is to make testing random functions easier - "advance funN" is guaranteed to have always been preceeded by a global variable clearing zed call. */ while (1) { zed (); L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); } return 0; } [-- Attachment #3: structs.exp --] [-- Type: text/plain, Size: 23296 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Compile a variant of structs.c using TYPES to specify the type of # the first N struct elements (the remaining elements take the type of # the last TYPES field). Run the compmiled program up to "main". # Also updates the global "testfile" to reflect the most recent build. proc start_structs_test { types } { global testfile global srcfile global binfile global objdir global subdir global srcdir global gdb_prompt # Create the additional flags set flags "debug" set testfile "structs" set n 0 for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append testfile "-" "$t" } set binfile ${objdir}/${subdir}/${testfile} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" \ "set print sevenbit-strings; ${testfile}" gdb_test "set print address off" "" \ "set print address off; ${testfile}" gdb_test "set width 0" "" \ "set width 0; ${testfile}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${types}] \{" for {set n 0} {$n<[llength ${types}]} {incr n} { append foo_t "\[\r\n \]+[lindex ${types} $n] [i2a $n];" } append foo_t "\[\r\n \]+\}" gdb_test "ptype foo[llength ${types}]" "${foo_t}" \ "ptype foo[llength ${types}]; ${testfile}" } # The expected value for fun${n}, L${n} and foo${n}. First element is # empty to make indexing easier. "foo" returns the modified value, # "zed" returns the invalid value. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc zed { n } { return [lindex { "{}" "{a = 90 'Z'}" "{a = 90 'Z', b = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z', q = 90 'Z'}" } $n] } # Given N (0..25), return the corresponding alphabetic letter in lower # or upper case. This is ment to be i18n proof. proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Use the tuples in FAILS to set up any needed KFAILs. proc setup_kfails { fails bug } { foreach f $fails { setup_kfail $f $bug } } # Test GDB's ability to make inferior function calls to functions # returning (or passing in a single structs. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # start_structs_test() will have previously built a program with a # specified combination of types for those elements. To ensure # robustness of the output, "p/c" is used. # This tests the code paths "which return-value convention?" and # "extract return-value from registers" called by "infcall.c". proc test_struct_calls { n fails } { global testfile global gdb_prompt # Check that GDB can always extract a struct-return value from an # inferior function call. Since GDB always knows the location of an # inferior function call's return value these should never fail # Implemented by calling the parameterless function "fun$N" and then # examining the return value printed by GDB. set tests "call $n ${testfile}" # Call fun${n}, checking the printed return-value. setup_kfails ${fails} gdb/1443 gdb_test "p/c fun${n}()" "[foo ${n}]" "p/c fun${n}(); ${tests}" # Check that GDB can always pass a structure to an inferior function. # This test can never fail. # Implemented by calling the one parameter function "Fun$N" which # stores its parameter in the global variable "L$N". GDB then # examining that global to confirm that the value is as expected. gdb_test "call Fun${n}(foo${n})" "" "call Fun${n}(foo${n}); ${tests}" setup_kfails ${fails} gdb/1443 gdb_test "p/c L${n}" [foo ${n}] "p/c L${n}; ${tests}" } # Test GDB's ability to both return a function (with "return" or # "finish") and correctly extract/store any corresponding # return-value. # Check that GDB can consistently extract/store structure return # values. There are two cases - returned in registers and returned in # memory. For the latter case, the return value can't be found and a # failure is "expected". However GDB must still both return the # function and display the final source and line information. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # This tests the code paths "which return-value convention?", "extract # return-value from registers", and "store return-value in registers". # Unlike "test struct calls", this test is expected to "fail" when the # return-value is in memory (GDB can't find the location). The test # is in three parts: test "return"; test "finish"; check that the two # are consistent. GDB can sometimes work for one command and not the # other. proc test_struct_returns { n fails } { global gdb_prompt global testfile set tests "return $n ${testfile}" # Check that "return" works. # GDB must always force the return of a function that has # a struct result. Dependant on the ABI, it may, or may not be # possible to store the return value in a register. # The relevant code looks like "L{n} = fun{n}()". The test forces # "fun{n}" to "return" with an explicit value. Since that code # snippet will store the the returned value in "L{n}" the return # is tested by examining "L{n}". This assumes that the # compiler implemented this as fun{n}(&L{n}) and hence that when # the value isn't stored "L{n}" remains unchanged. Also check for # consistency between this and the "finish" case. # Get into a call of fun${n} gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for return; ${tests}" # Check that the program invalidated the relevant global. if [string equal ${testfile} structs-tld] { setup_kfail i686-*-* gdb/1447 } gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for return; ${tests} .${testfile}." # Force the "return". This checks that the return is always # performed, and that GDB correctly reported this to the user. # GDB 6.0 and earlier, when the return-value's location wasn't # known, both failed to print a final "source and line" and misplaced # the frame ("No frame"). # The test is writen so that it only reports one FAIL/PASS for the # entire operation. The value returned is checked further down. # "return_value_known" records if GDB thinks that it managed to print # that final return value. send_gdb "return foo${n}\n" set test "return foo${n}; ${tests}" set return_value_known 1 gdb_expect { -re "The location" { # Ulgh, a struct return, remember this (still need prompt). set return_value_known 0 exp_continue } -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { pass "${test}" } timeout { fail "${test} (timeout 2)" } } } -re "${gdb_prompt} $" { fail "${test} (no query)" } timeout { fail "${test} (timeout 1)" } } # Check that the return-value is as expected. At this stage we're # just checking that GDB has returned a value consistent with # "return_value_known" set above. send_gdb "p/c L${n}\n" set test "value foo${n} returned; ${tests}" gdb_expect { -re " = [foo ${n}].*${gdb_prompt} $" { if $return_value_known { pass "${test}" } else { # This contradicts the above claim that GDB didn't # know the location of the return-value. setup_kfails ${fails} gdb/1444 fail "${test}" } } -re " = [zed ${n}].*${gdb_prompt} $" { if $return_value_known { # This contradicts the above claim that GDB knew # the location of the return-value. setup_kfails ${fails} gdb/1444 fail "${test}" } else { # The struct return case. Since any modification # would be by reference, and that can't happen, the # value should be unmodified and hence Z is expected. pass "${test}" } } -re "${gdb_prompt} $" { # Garbage returned, garbage printed setup_kfails $fails gdb/1444 fail "${test}" } timeout { fail "${test} (timeout)" } } # Check that a "finish" works. # This is almost but not quite the same as "call struct funcs". # Architectures can have subtle differences in the two code paths. # The relevant code snippet is "L{n} = fun{n}()". The program is # advanced into a call to "fun{n}" and then that function is # finished. The returned value that GDB prints, reformatted using # "p/c", is checked. # Get into "fun${n}()". gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for finish; ${tests}" # Check that the program invalidated the relevant global. if [string equal ${testfile} structs-tld] { setup_kfail i686-*-* gdb/1447 } gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for finish; ${tests}" # Finish the function, set 'finish_value_known" to indicate if the # return-value was found. send_gdb "finish\n" set test "finish foo${n}; ${tests}" set finish_value_known 1 gdb_expect { -re "Value returned is .*${gdb_prompt} $" { pass "${test}" } -re "Cannot determine contents.*${gdb_prompt} $" { # Expected bad value. For the moment this is ok. set finish_value_known 0 pass "${test}" } -re ".*${gdb_prompt} $" { # Garbage returned setup_kfails $fails gdb/1444 fail "${test}" } timeout { fail "${test} (timeout)" } } # Re-print the last (return-value) using the more robust # "p/c". If no return value was found, the 'Z' from the previous # check that the variable was cleared, is printed. send_gdb "p/c\n" set test "value foo${n} finished; ${tests}" gdb_expect { -re "[foo ${n}]\[\r\n\]+${gdb_prompt} $" { if $finish_value_known { pass "${test}" } else { # This contradicts the above claim that GDB didn't # know the location of the return-value. setup_kfails ${fails} gdb/1444 fail "${test}" } } -re "[zed ${n}]\[\r\n\]+${gdb_prompt} $" { # The value didn't get found. This is "expected". if $finish_value_known { # This contradicts the above claim that GDB did # know the location of the return-value. setup_kfails ${fails} gdb/1444 fail "${test}" } else { pass "${test}" } } -re ".*${gdb_prompt} $" { # Garbage returned setup_kfails ${fails} gdb/1444 fail "${test}" } timeout { fail "${test} (timeout)" } } # Finally, check that "return" and finish" have consistent # behavior. # Since both "return" and "finish" use equivalent "which # return-value convention" logic, both commands should have # identical can/can-not find return-value messages. # Note that since "call" and "finish" use common code paths, a # failure here is a strong indicator of problems with "store # return-value" code paths. Suggest looking at "return_value" # when investigating a fix. setup_kfails ${fails} gdb/1444 if {$finish_value_known == $return_value_known} { pass "return and finish consistent; ${tests}" } else { fail "return and finish consistent; ${tests}" } } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. But only a restricted # range of the other types. # NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized structs in memory. # d10v is weird. 5/6 byte structs go in memory. 2 or more char # structs go in memory. Everything else is in a register! # Test every single char struct from 1..17 in size. This is what the # original "structs" test was doing. start_structs_test { tc } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_calls 9 { } test_struct_calls 10 { } test_struct_calls 11 { } test_struct_calls 12 { } test_struct_calls 13 { } test_struct_calls 14 { } test_struct_calls 15 { } test_struct_calls 16 { } test_struct_calls 17 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } test_struct_returns 3 { i686-*-* } test_struct_returns 4 { i686-*-* } test_struct_returns 5 { i686-*-* } test_struct_returns 6 { i686-*-* } test_struct_returns 7 { i686-*-* } test_struct_returns 8 { i686-*-* } # Let the fun begin. # Assuming that any integer struct larger than 8 bytes goes in memory, # come up with many and varied combinations of a return struct. For # "struct calls" test just beyond that 8 byte boundary, for "struct # returns" test up to that boundary. # For floats, assumed that up to two struct elements can be stored in # floating point registers, regardless of their size. # The approx size of each structure it is computed assumed that tc=1, # ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are # naturally aligned. Padding being added where needed. Note that # these numbers are just approx, the d10v has ti=2, a 64-bit has has # tl=8. # Approx size: 2, 4, ... start_structs_test { ts } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } test_struct_returns 3 { i686-*-* } test_struct_returns 4 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { ti } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { tl } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 8, 16, ... start_structs_test { tll } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { tf } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 8, 16, ... start_structs_test { td } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { i686-*-* } # Approx size: 16, 32, ... start_structs_test { tld } test_struct_calls 1 { i686-*-* } test_struct_calls 2 { i686-*-* } test_struct_returns 1 { i686-*-* } # Approx size: 2+1=3, 4, ... start_structs_test { ts tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_returns 2 { i686-*-* } # Approx size: 4+1=5, 6, ... start_structs_test { ti tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 4+1=5, 6, ... start_structs_test { tl tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 8+1=9, 10, ... start_structs_test { tll tc } test_struct_calls 2 { } # Approx size: 4+1=5, 6, ... start_structs_test { tf tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 8+1=9, 10, ... start_structs_test { td tc } test_struct_calls 2 { } # Approx size: 16+1=17, 18, ... start_structs_test { tld tc } test_struct_calls 2 { i686-*-* } # Approx size: (1+1)+2=4, 6, ... start_structs_test { tc ts } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc ti } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tl } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc tll } test_struct_calls 2 { } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tf } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc td } test_struct_calls 2 { } # Approx size: (1+15)+16=32, 48, ... start_structs_test { tc tld } test_struct_calls 2 { i686-*-* } # Some float combinations # Approx size: 8+4=12, 16, ... # d10v: 4+4=8, 12, ... start_structs_test { td tf } test_struct_calls 2 { } test_struct_returns 2 { i686-*-* } # Approx size: (4+4)+8=16, 32, ... # d10v: 4+4=8, 12, ... start_structs_test { tf td } test_struct_calls 2 { } test_struct_returns 2 { i686-*-* } return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-13 16:11 ` Andrew Cagney @ 2003-11-17 15:59 ` Andrew Cagney 2003-11-20 17:17 ` Andrew Cagney 0 siblings, 1 reply; 18+ messages in thread From: Andrew Cagney @ 2003-11-17 15:59 UTC (permalink / raw) Cc: Michael Elizabeth Chastain, gdb-patches [-- Attachment #1: Type: text/plain, Size: 606 bytes --] > > # gcc 3.3.2, binutils 2.14, -gdwarf-2 > > p/c fun2() > $1 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-tll > > p/c L2 > $2 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-tll > > p/c fun2() > $1 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c fun2(); call 2 structs-tc-td > > p/c L2 > $2 = {a = 97 'a', b = 0 '\0'} > (gdb) FAIL: gdb.base/structs.exp: p/c L2; call 2 structs-tc-td The attached hopefully KFAILs these. It needs my other compiler tweak. Andrew [-- Attachment #2: structs.c --] [-- Type: text/plain, Size: 9987 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif #ifndef tR typedef tQ tR; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD d; }; struct struct5 {tA a; tB b; tC c; tD d; tE e; }; struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } struct struct18 fun18() { return foo18; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } #ifdef PROTOTYPES void Fun18(struct struct18 foo18) #else void Fun18(foo18) struct struct18 foo18; #endif { L18 = foo18; } zed () { L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; L15.o = L16.o = L17.o = L18.o = 'Z'; L16.p = L17.p = L18.p = 'Z'; L17.q = L18.q = 'Z'; L18.r = 'Z'; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif int i; Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); Fun18(foo18); /* An infinite loop that first clears all the variables and then calls each function. This "hack" is to make testing random functions easier - "advance funN" is guaranteed to have always been preceeded by a global variable clearing zed call. */ while (1) { zed (); L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); } return 0; } [-- Attachment #3: structs.exp --] [-- Type: text/plain, Size: 22838 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Compile a variant of structs.c using TYPES to specify the type of # the first N struct elements (the remaining elements take the type of # the last TYPES field). Run the compmiled program up to "main". # Also updates the global "testfile" to reflect the most recent build. proc start_structs_test { types } { global testfile global srcfile global binfile global objdir global subdir global srcdir global gdb_prompt # Create the additional flags set flags "debug" set testfile "structs" set n 0 for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append testfile "-" "$t" } set binfile ${objdir}/${subdir}/${testfile} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" \ "set print sevenbit-strings; ${testfile}" gdb_test "set print address off" "" \ "set print address off; ${testfile}" gdb_test "set width 0" "" \ "set width 0; ${testfile}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${types}] \{" for {set n 0} {$n<[llength ${types}]} {incr n} { append foo_t "\[\r\n \]+[lindex ${types} $n] [i2a $n];" } append foo_t "\[\r\n \]+\}" gdb_test "ptype foo[llength ${types}]" "${foo_t}" \ "ptype foo[llength ${types}]; ${testfile}" } # The expected value for fun${n}, L${n} and foo${n}. First element is # empty to make indexing easier. "foo" returns the modified value, # "zed" returns the invalid value. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc zed { n } { return [lindex { "{}" "{a = 90 'Z'}" "{a = 90 'Z', b = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z', q = 90 'Z'}" } $n] } # Given N (0..25), return the corresponding alphabetic letter in lower # or upper case. This is ment to be i18n proof. proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Use the file name, compiler and tuples to set up any needed KFAILs. proc setup_kfails { file tuples bug } { global testfile if [string match $file $testfile] { foreach f $tuples { setup_kfail $f $bug } } } proc setup_compiler_kfails { file compiler format tuples bug } { global testfile if {[string match $file $testfile] && [test_compiler_info $compiler] && [test_debug_format $format]} { foreach f $tuples { setup_kfail $f $bug } } } # Test GDB's ability to make inferior function calls to functions # returning (or passing in a single structs. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # start_structs_test() will have previously built a program with a # specified combination of types for those elements. To ensure # robustness of the output, "p/c" is used. # This tests the code paths "which return-value convention?" and # "extract return-value from registers" called by "infcall.c". proc test_struct_calls { n } { global testfile global gdb_prompt # Check that GDB can always extract a struct-return value from an # inferior function call. Since GDB always knows the location of an # inferior function call's return value these should never fail # Implemented by calling the parameterless function "fun$N" and then # examining the return value printed by GDB. set tests "call $n ${testfile}" # Call fun${n}, checking the printed return-value. setup_kfails structs-*tld* i686-*-* gdb/1447 setup_compiler_kfails structs-tc-* gcc-3-3 "DWARF 2" i686-*-* gdb/1455 gdb_test "p/c fun${n}()" "[foo ${n}]" "p/c fun<n>(); ${tests}" # Check that GDB can always pass a structure to an inferior function. # This test can never fail. # Implemented by calling the one parameter function "Fun$N" which # stores its parameter in the global variable "L$N". GDB then # examining that global to confirm that the value is as expected. gdb_test "call Fun${n}(foo${n})" "" "call Fun<n>(foo<n>); ${tests}" setup_kfails structs-*tld* i686-*-* gdb/1447 setup_compiler_kfails structs-tc-* gcc-3-3 "DWARF 2" i686-*-* gdb/1455 gdb_test "p/c L${n}" [foo ${n}] "p/c L<n>; ${tests}" } # Test GDB's ability to both return a function (with "return" or # "finish") and correctly extract/store any corresponding # return-value. # Check that GDB can consistently extract/store structure return # values. There are two cases - returned in registers and returned in # memory. For the latter case, the return value can't be found and a # failure is "expected". However GDB must still both return the # function and display the final source and line information. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # This tests the code paths "which return-value convention?", "extract # return-value from registers", and "store return-value in registers". # Unlike "test struct calls", this test is expected to "fail" when the # return-value is in memory (GDB can't find the location). The test # is in three parts: test "return"; test "finish"; check that the two # are consistent. GDB can sometimes work for one command and not the # other. proc test_struct_returns { n } { global gdb_prompt global testfile set tests "return $n ${testfile}" # Check that "return" works. # GDB must always force the return of a function that has # a struct result. Dependant on the ABI, it may, or may not be # possible to store the return value in a register. # The relevant code looks like "L{n} = fun{n}()". The test forces # "fun{n}" to "return" with an explicit value. Since that code # snippet will store the the returned value in "L{n}" the return # is tested by examining "L{n}". This assumes that the # compiler implemented this as fun{n}(&L{n}) and hence that when # the value isn't stored "L{n}" remains unchanged. Also check for # consistency between this and the "finish" case. # Get into a call of fun${n} gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun<n> for return; ${tests}" # Check that the program invalidated the relevant global. setup_kfails structs-tld i686-*-* gdb/1447 gdb_test "p/c L${n}" " = [zed $n]" "zed L<n> for return; ${tests} .${testfile}." # Force the "return". This checks that the return is always # performed, and that GDB correctly reported this to the user. # GDB 6.0 and earlier, when the return-value's location wasn't # known, both failed to print a final "source and line" and misplaced # the frame ("No frame"). # The test is writen so that it only reports one FAIL/PASS for the # entire operation. The value returned is checked further down. # "return_value_known" records if GDB thinks that it managed to print # that final return value. send_gdb "return foo${n}\n" set test "return foo<n>; ${tests}" set return_value_known 1 gdb_expect { -re "The location" { # Ulgh, a struct return, remember this (still need prompt). set return_value_known 0 exp_continue } -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { pass "${test}" } timeout { fail "${test} (timeout 2)" } } } -re "${gdb_prompt} $" { fail "${test} (no query)" } timeout { fail "${test} (timeout 1)" } } # Check that the return-value is as expected. At this stage we're # just checking that GDB has returned a value consistent with # "return_value_known" set above. send_gdb "p/c L${n}\n" set test "value foo<n> returned; ${tests}" setup_kfails structs-*tld* i686-*-* gdb/1447 gdb_expect { -re " = [foo ${n}].*${gdb_prompt} $" { if $return_value_known { pass "${test}" } else { # This contradicts the above claim that GDB didn't # know the location of the return-value. fail "${test}" } } -re " = [zed ${n}].*${gdb_prompt} $" { if $return_value_known { # This contradicts the above claim that GDB knew # the location of the return-value. fail "${test}" } else { # The struct return case. Since any modification # would be by reference, and that can't happen, the # value should be unmodified and hence Z is expected. pass "${test}" } } -re "${gdb_prompt} $" { # Garbage returned, garbage printed fail "${test}" } timeout { fail "${test} (timeout)" } } # Check that a "finish" works. # This is almost but not quite the same as "call struct funcs". # Architectures can have subtle differences in the two code paths. # The relevant code snippet is "L{n} = fun{n}()". The program is # advanced into a call to "fun{n}" and then that function is # finished. The returned value that GDB prints, reformatted using # "p/c", is checked. # Get into "fun${n}()". gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun<n> for finish; ${tests}" # Check that the program invalidated the relevant global. setup_kfails structs-tld i686-*-* gdb/1447 gdb_test "p/c L${n}" " = [zed $n]" "zed L<n> for finish; ${tests}" # Finish the function, set 'finish_value_known" to indicate if the # return-value was found. send_gdb "finish\n" set test "finish foo${n}; ${tests}" set finish_value_known 1 gdb_expect { -re "Value returned is .*${gdb_prompt} $" { pass "${test}" } -re "Cannot determine contents.*${gdb_prompt} $" { # Expected bad value. For the moment this is ok. set finish_value_known 0 pass "${test}" } -re ".*${gdb_prompt} $" { # Garbage returned fail "${test}" } timeout { fail "${test} (timeout)" } } # Re-print the last (return-value) using the more robust # "p/c". If no return value was found, the 'Z' from the previous # check that the variable was cleared, is printed. send_gdb "p/c\n" set test "value foo${n} finished; ${tests}" setup_kfails structs-*tld* i686-*-* gdb/1447 gdb_expect { -re "[foo ${n}]\[\r\n\]+${gdb_prompt} $" { if $finish_value_known { pass "${test}" } else { # This contradicts the above claim that GDB didn't # know the location of the return-value. fail "${test}" } } -re "[zed ${n}]\[\r\n\]+${gdb_prompt} $" { # The value didn't get found. This is "expected". if $finish_value_known { # This contradicts the above claim that GDB did # know the location of the return-value. fail "${test}" } else { pass "${test}" } } -re ".*${gdb_prompt} $" { # Garbage returned fail "${test}" } timeout { fail "${test} (timeout)" } } # Finally, check that "return" and finish" have consistent # behavior. # Since both "return" and "finish" use equivalent "which # return-value convention" logic, both commands should have # identical can/can-not find return-value messages. # Note that since "call" and "finish" use common code paths, a # failure here is a strong indicator of problems with "store # return-value" code paths. Suggest looking at "return_value" # when investigating a fix. setup_kfails structs-* i686-*-* gdb/1444 if {$finish_value_known == $return_value_known} { pass "return and finish consistent; ${tests}" } else { fail "return and finish consistent; ${tests}" } } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. But only a restricted # range of the other types. # NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized structs in memory. # d10v is weird. 5/6 byte structs go in memory. 2 or more char # structs go in memory. Everything else is in a register! # Test every single char struct from 1..17 in size. This is what the # original "structs" test was doing. start_structs_test { tc } test_struct_calls 1 test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_calls 7 test_struct_calls 8 test_struct_calls 9 test_struct_calls 10 test_struct_calls 11 test_struct_calls 12 test_struct_calls 13 test_struct_calls 14 test_struct_calls 15 test_struct_calls 16 test_struct_calls 17 test_struct_returns 1 test_struct_returns 2 test_struct_returns 3 test_struct_returns 4 test_struct_returns 5 test_struct_returns 6 test_struct_returns 7 test_struct_returns 8 # Let the fun begin. # Assuming that any integer struct larger than 8 bytes goes in memory, # come up with many and varied combinations of a return struct. For # "struct calls" test just beyond that 8 byte boundary, for "struct # returns" test up to that boundary. # For floats, assumed that up to two struct elements can be stored in # floating point registers, regardless of their size. # The approx size of each structure it is computed assumed that tc=1, # ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are # naturally aligned. Padding being added where needed. Note that # these numbers are just approx, the d10v has ti=2, a 64-bit has has # tl=8. # Approx size: 2, 4, ... start_structs_test { ts } test_struct_calls 1 test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_returns 1 test_struct_returns 2 test_struct_returns 3 test_struct_returns 4 # Approx size: 4, 8, ... start_structs_test { ti } test_struct_calls 1 test_struct_calls 2 test_struct_calls 3 test_struct_returns 1 test_struct_returns 2 # Approx size: 4, 8, ... start_structs_test { tl } test_struct_calls 1 test_struct_calls 2 test_struct_calls 3 test_struct_returns 1 test_struct_returns 2 # Approx size: 8, 16, ... start_structs_test { tll } test_struct_calls 1 test_struct_calls 2 test_struct_returns 1 # Approx size: 4, 8, ... start_structs_test { tf } test_struct_calls 1 test_struct_calls 2 test_struct_calls 3 test_struct_returns 1 test_struct_returns 2 # Approx size: 8, 16, ... start_structs_test { td } test_struct_calls 1 test_struct_calls 2 test_struct_returns 1 # Approx size: 16, 32, ... start_structs_test { tld } test_struct_calls 1 test_struct_calls 2 test_struct_returns 1 # Approx size: 2+1=3, 4, ... start_structs_test { ts tc } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_calls 7 test_struct_calls 8 test_struct_returns 2 # Approx size: 4+1=5, 6, ... start_structs_test { ti tc } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_returns 2 # Approx size: 4+1=5, 6, ... start_structs_test { tl tc } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_returns 2 # Approx size: 8+1=9, 10, ... start_structs_test { tll tc } test_struct_calls 2 # Approx size: 4+1=5, 6, ... start_structs_test { tf tc } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_returns 2 # Approx size: 8+1=9, 10, ... start_structs_test { td tc } test_struct_calls 2 # Approx size: 16+1=17, 18, ... start_structs_test { tld tc } test_struct_calls 2 # Approx size: (1+1)+2=4, 6, ... start_structs_test { tc ts } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_calls 5 test_struct_calls 6 test_struct_returns 2 # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc ti } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_returns 2 # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tl } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 test_struct_returns 2 # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc tll } test_struct_calls 2 # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tf } test_struct_calls 2 test_struct_calls 3 test_struct_calls 4 # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc td } test_struct_calls 2 # Approx size: (1+15)+16=32, 48, ... start_structs_test { tc tld } test_struct_calls 2 # Some float combinations # Approx size: 8+4=12, 16, ... # d10v: 4+4=8, 12, ... start_structs_test { td tf } test_struct_calls 2 test_struct_returns 2 # Approx size: (4+4)+8=16, 32, ... # d10v: 4+4=8, 12, ... start_structs_test { tf td } test_struct_calls 2 test_struct_returns 2 return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-17 15:59 ` Andrew Cagney @ 2003-11-20 17:17 ` Andrew Cagney 0 siblings, 0 replies; 18+ messages in thread From: Andrew Cagney @ 2003-11-20 17:17 UTC (permalink / raw) To: gdb-patches; +Cc: Michael Elizabeth Chastain [-- Attachment #1: Type: text/plain, Size: 232 bytes --] Time to bite the bullet. I've committed the attached. i386, ppc, and d10v should all see zero additional fails. However, the i386 does see a notable number of KFAILS as this test identifies a notable number of bugs :-/ Andrew [-- Attachment #2: diffs --] [-- Type: text/plain, Size: 40473 bytes --] 2003-11-20 Andrew Cagney <cagney@redhat.com> * gdb.base/structs.exp: Update copyright. Rewrite. * gdb.base/structs.c: Update copyright. Rewrite. Index: gdb.base/structs.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/structs.c,v retrieving revision 1.4 diff -u -r1.4 structs.c --- gdb.base/structs.c 17 Nov 2003 15:09:19 -0000 1.4 +++ gdb.base/structs.c 20 Nov 2003 17:10:52 -0000 @@ -1,4 +1,6 @@ -/* Copyright 1996, 1999 Free Software Foundation, Inc. +/* This testcase is part of GDB, the GNU debugger. + + Copyright 1996, 1999, 2003 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 @@ -17,37 +19,110 @@ Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ -struct struct1 { char a;}; -struct struct2 { char a, b;}; -struct struct3 { char a, b, c; }; -struct struct4 { char a, b, c, d; }; -struct struct5 { char a, b, c, d, e; }; -struct struct6 { char a, b, c, d, e, f; }; -struct struct7 { char a, b, c, d, e, f, g; }; -struct struct8 { char a, b, c, d, e, f, g, h; }; -struct struct9 { char a, b, c, d, e, f, g, h, i; }; -struct struct10 { char a, b, c, d, e, f, g, h, i, j; }; -struct struct11 { char a, b, c, d, e, f, g, h, i, j, k; }; -struct struct12 { char a, b, c, d, e, f, g, h, i, j, k, l; }; -struct struct16 { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; }; - -struct struct1 foo1 = {'1'}, L1; -struct struct2 foo2 = { 'a', 'b'}, L2; -struct struct3 foo3 = { 'A', 'B', 'C'}, L3; -struct struct4 foo4 = {'1', '2', '3', '4'}, L4; -struct struct5 foo5 = {'a', 'b', 'c', 'd', 'e'}, L5; -struct struct6 foo6 = {'A', 'B', 'C', 'D', 'E', 'F'}, L6; -struct struct7 foo7 = {'1', '2', '3', '4', '5', '6', '7'}, L7; -struct struct8 foo8 = {'1', '2', '3', '4', '5', '6', '7', '8'}, L8; -struct struct9 foo9 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, L9; -struct struct10 foo10 = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}, L10; -struct struct11 foo11 = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'}, L11; -struct struct12 foo12 = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}, L12; -struct struct16 foo16 = { - 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'}, L16; +/* Useful abreviations. */ +typedef void t; +typedef char tc; +typedef short ts; +typedef int ti; +typedef long tl; +typedef long long tll; +typedef float tf; +typedef double td; +typedef long double tld; + +/* Force the type of each field. */ +#ifndef tA +typedef t tA; +#endif +#ifndef tB +typedef tA tB; +#endif +#ifndef tC +typedef tB tC; +#endif +#ifndef tD +typedef tC tD; +#endif +#ifndef tE +typedef tD tE; +#endif +#ifndef tF +typedef tE tF; +#endif +#ifndef tG +typedef tF tG; +#endif +#ifndef tH +typedef tG tH; +#endif +#ifndef tI +typedef tH tI; +#endif +#ifndef tJ +typedef tI tJ; +#endif +#ifndef tK +typedef tJ tK; +#endif +#ifndef tL +typedef tK tL; +#endif +#ifndef tM +typedef tL tM; +#endif +#ifndef tN +typedef tM tN; +#endif +#ifndef tO +typedef tN tO; +#endif +#ifndef tP +typedef tO tP; +#endif +#ifndef tQ +typedef tP tQ; +#endif +#ifndef tR +typedef tQ tR; +#endif + +struct struct1 {tA a;}; +struct struct2 {tA a; tB b;}; +struct struct3 {tA a; tB b; tC c; }; +struct struct4 {tA a; tB b; tC c; tD d; }; +struct struct5 {tA a; tB b; tC c; tD d; tE e; }; +struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; +struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; +struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; +struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; +struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; +struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; +struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; +struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; +struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; +struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; +struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; +struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; +struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; + +struct struct1 foo1 = {'1'}, L1; +struct struct2 foo2 = {'a','2'}, L2; +struct struct3 foo3 = {'1','b','3'}, L3; +struct struct4 foo4 = {'a','2','c','4'}, L4; +struct struct5 foo5 = {'1','b','3','d','5'}, L5; +struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; +struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; +struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; +struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; +struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; +struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; +struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; +struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; +struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; +struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; +struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; +struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; +struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { @@ -97,10 +172,30 @@ { return foo12; } +struct struct13 fun13() +{ + return foo13; +} +struct struct14 fun14() +{ + return foo14; +} +struct struct15 fun15() +{ + return foo15; +} struct struct16 fun16() { return foo16; } +struct struct17 fun17() +{ + return foo17; +} +struct struct18 fun18() +{ + return foo18; +} #ifdef PROTOTYPES void Fun1(struct struct1 foo1) @@ -211,6 +306,33 @@ L12 = foo12; } #ifdef PROTOTYPES +void Fun13(struct struct13 foo13) +#else +void Fun13(foo13) + struct struct13 foo13; +#endif +{ + L13 = foo13; +} +#ifdef PROTOTYPES +void Fun14(struct struct14 foo14) +#else +void Fun14(foo14) + struct struct14 foo14; +#endif +{ + L14 = foo14; +} +#ifdef PROTOTYPES +void Fun15(struct struct15 foo15) +#else +void Fun15(foo15) + struct struct15 foo15; +#endif +{ + L15 = foo15; +} +#ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) @@ -219,6 +341,64 @@ { L16 = foo16; } +#ifdef PROTOTYPES +void Fun17(struct struct17 foo17) +#else +void Fun17(foo17) + struct struct17 foo17; +#endif +{ + L17 = foo17; +} +#ifdef PROTOTYPES +void Fun18(struct struct18 foo18) +#else +void Fun18(foo18) + struct struct18 foo18; +#endif +{ + L18 = foo18; +} + +zed () +{ + + L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; + + L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; + + L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; + + L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; + + L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; + + L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; + + L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; + + L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; + + L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; + + L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; + + L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; + + L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; + + L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; + + L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; + + L15.o = L16.o = L17.o = L18.o = 'Z'; + + L16.p = L17.p = L18.p = 'Z'; + + L17.q = L18.q = 'Z'; + + L18.r = 'Z'; +} int main() { @@ -226,24 +406,7 @@ set_debug_traps(); breakpoint(); #endif - - /* TEST C FUNCTIONS */ - L1 = fun1(); - L2 = fun2(); - L3 = fun3(); - L4 = fun4(); - L5 = fun5(); - L6 = fun6(); - L7 = fun7(); - L8 = fun8(); - L9 = fun9(); - L10 = fun10(); - L11 = fun11(); - L12 = fun12(); - L16 = fun16(); - - foo1.a = foo2.a = foo3.a = foo4.a = foo5.a = foo6.a = foo7.a = foo8.a = - foo9.a = foo10.a = foo11.a = foo12.a = foo16.a = '$'; + int i; Fun1(foo1); Fun2(foo2); @@ -257,7 +420,40 @@ Fun10(foo10); Fun11(foo11); Fun12(foo12); + Fun13(foo13); + Fun14(foo14); + Fun15(foo15); Fun16(foo16); + Fun17(foo17); + Fun18(foo18); + + /* An infinite loop that first clears all the variables and then + calls each function. This "hack" is to make testing random + functions easier - "advance funN" is guaranteed to have always + been preceeded by a global variable clearing zed call. */ + + while (1) + { + zed (); + L1 = fun1(); + L2 = fun2(); + L3 = fun3(); + L4 = fun4(); + L5 = fun5(); + L6 = fun6(); + L7 = fun7(); + L8 = fun8(); + L9 = fun9(); + L10 = fun10(); + L11 = fun11(); + L12 = fun12(); + L13 = fun13(); + L14 = fun14(); + L15 = fun15(); + L16 = fun16(); + L17 = fun17(); + L18 = fun18(); + } return 0; } Index: gdb.base/structs.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/structs.exp,v retrieving revision 1.7 diff -u -r1.7 structs.exp --- gdb.base/structs.exp 17 Nov 2003 15:09:19 -0000 1.7 +++ gdb.base/structs.exp 20 Nov 2003 17:10:52 -0000 @@ -1,4 +1,6 @@ -# Copyright 1996, 1997, 1999 Free Software Foundation, Inc. +# This testcase is part of GDB, the GNU debugger. + +# Copyright 1996, 1997, 1999, 2003 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 @@ -17,8 +19,6 @@ # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu -# This file was written by Jeff Law. (law@cygnus.com) - if $tracelevel then { strace $tracelevel } @@ -26,142 +26,664 @@ set prms_id 0 set bug_id 0 -set prototypes 1 +# Some targets can't call functions, so don't even bother with this +# test. + +if [target_info exists gdb,cannot_call_functions] { + setup_xfail "*-*-*" + fail "This target can not call functions" + continue +} + set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} -# build the first test case -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { - # built the second test case since we can't use prototypes - warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DNO_PROTOTYPES}] != "" } { - gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." - } - set prototypes 0 -} +# Create and source the file that provides information about the +# compiler used to compile the test case. -# Create and source the file that provides information about the compiler -# used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } +# Compile a variant of structs.c using TYPES to specify the type of +# the first N struct elements (the remaining elements take the type of +# the last TYPES field). Run the compmiled program up to "main". +# Also updates the global "testfile" to reflect the most recent build. + +proc start_structs_test { types } { + global testfile + global srcfile + global binfile + global objdir + global subdir + global srcdir + global gdb_prompt -# Some targets can't call functions, so don't even bother with this -# test. -if [target_info exists gdb,cannot_call_functions] { - setup_xfail "*-*-*" 2416 - fail "This target can not call functions" - continue + # Create the additional flags + set flags "debug" + set testfile "structs" + set n 0 + for {set n 0} {$n<[llength ${types}]} {incr n} { + set m [I2A ${n}] + set t [lindex ${types} $n] + lappend flags "additional_flags=-Dt${m}=${t}" + append testfile "-" "$t" + } + + set binfile ${objdir}/${subdir}/${testfile} + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { + # built the second test case since we can't use prototypes + warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." + } + } + + # Start with a fresh gdb. + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # Make certain that the output is consistent + gdb_test "set print sevenbit-strings" "" \ + "set print sevenbit-strings; ${testfile}" + gdb_test "set print address off" "" \ + "set print address off; ${testfile}" + gdb_test "set width 0" "" \ + "set width 0; ${testfile}" + + # Advance to main + if { ![runto_main] } then { + gdb_suppress_tests; + } + + # check that at the struct containing all the relevant types is correct + set foo_t "type = struct struct[llength ${types}] \{" + for {set n 0} {$n<[llength ${types}]} {incr n} { + append foo_t "\[\r\n \]+[lindex ${types} $n] [i2a $n];" + } + append foo_t "\[\r\n \]+\}" + gdb_test "ptype foo[llength ${types}]" "${foo_t}" \ + "ptype foo[llength ${types}]; ${testfile}" } +# The expected value for fun${n}, L${n} and foo${n}. First element is +# empty to make indexing easier. "foo" returns the modified value, +# "zed" returns the invalid value. + +proc foo { n } { + return [lindex { + "{}" + "{a = 49 '1'}" + "{a = 97 'a', b = 50 '2'}" + "{a = 49 '1', b = 98 'b', c = 51 '3'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" + "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" + "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" + } $n] +} -# Call FUNC with no arguments, and expect to see the regexp RESULT in -# the output. If we get back the error message "Function return value -# unknown", call that an unsupported test; on some architectures, it's -# impossible to find structs returned by value reliably. -proc call_struct_func { func result } { - global gdb_prompt - - set command "p ${func}()" - send_gdb "${command}\n" - gdb_expect { - -re "$result\[\r\n\]+$gdb_prompt $" { - pass "$command" - } - -re "Function return value unknown.\[\r\n\]+$gdb_prompt $" { - unsupported "$command" - } - -re "$gdb_prompt $" { - fail "$command" - } - timeout { - fail "$command (timeout)" - } +proc zed { n } { + return [lindex { + "{}" + "{a = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z'}" + "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z', q = 90 'Z'}" + } $n] +} + +# Given N (0..25), return the corresponding alphabetic letter in lower +# or upper case. This is ment to be i18n proof. + +proc i2a { n } { + return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] +} + +proc I2A { n } { + return [string toupper [i2a $n]] +} + + +# Use the file name, compiler and tuples to set up any needed KFAILs. + +proc setup_kfails { file tuples bug } { + global testfile + if [string match $file $testfile] { + foreach f $tuples { setup_kfail $f $bug } } } -# FIXME: Before calling this proc, we should probably verify that -# we can call inferior functions and get a valid integral value -# returned. -# Note that it is OK to check for 0 or 1 as the returned values, because C -# specifies that the numeric value of a relational or logical expression -# (computed in the inferior) is 1 for true and 0 for false. - -proc do_function_calls {} { - global prototypes - global gcc_compiled +proc setup_compiler_kfails { file compiler format tuples bug } { + global testfile + if {[string match $file $testfile] && [test_compiler_info $compiler] && [test_debug_format $format]} { + foreach f $tuples { setup_kfail $f $bug } + } +} + +# Test GDB's ability to make inferior function calls to functions +# returning (or passing in a single structs. + +# N identifies the number of elements in the struct that will be used +# for the test case. FAILS is a list of target tuples that will fail +# this test. + +# start_structs_test() will have previously built a program with a +# specified combination of types for those elements. To ensure +# robustness of the output, "p/c" is used. + +# This tests the code paths "which return-value convention?" and +# "extract return-value from registers" called by "infcall.c". + +proc test_struct_calls { n } { + global testfile global gdb_prompt - # First, call the "fun" functions and examine the value they return. - call_struct_func "fun1" " = {a = 49 '1'}" - call_struct_func "fun2" " = {a = 97 'a', b = 98 'b'}" - call_struct_func "fun3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}" - call_struct_func "fun4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}" - call_struct_func "fun5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}" - call_struct_func "fun6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}" - call_struct_func "fun7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}" - call_struct_func "fun8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}" - call_struct_func "fun9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}" - call_struct_func "fun10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}" - call_struct_func "fun11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}" - call_struct_func "fun12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}" - call_struct_func "fun16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}" - - # Now call the Fun functions to set the L* variables. This - # tests that gdb properly passes structures to functions. - gdb_test "p Fun1(foo1)" " = (void|0)" - gdb_test "p Fun2(foo2)" " = (void|0)" - gdb_test "p Fun3(foo3)" " = (void|0)" - gdb_test "p Fun4(foo4)" " = (void|0)" - gdb_test "p Fun5(foo5)" " = (void|0)" - gdb_test "p Fun6(foo6)" " = (void|0)" - gdb_test "p Fun7(foo7)" " = (void|0)" - gdb_test "p Fun8(foo8)" " = (void|0)" - gdb_test "p Fun9(foo9)" " = (void|0)" - gdb_test "p Fun10(foo10)" " = (void|0)" - gdb_test "p Fun11(foo11)" " = (void|0)" - gdb_test "p Fun12(foo12)" " = (void|0)" - gdb_test "p Fun16(foo16)" " = (void|0)" - - # Now print the L* variables and examine their values. - gdb_test "p L1" " = {a = 49 '1'}" - gdb_test "p L2" " = {a = 97 'a', b = 98 'b'}" - gdb_test "p L3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}" - gdb_test "p L4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}" - gdb_test "p L5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}" - gdb_test "p L6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}" - gdb_test "p L7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}" - gdb_test "p L8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}" - gdb_test "p L9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}" - gdb_test "p L10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}" - gdb_test "p L11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}" - gdb_test "p L12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}" - gdb_test "p L16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}" -} -# Start with a fresh gdb. - -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile} - -gdb_test "set print sevenbit-strings" "" -gdb_test "set print address off" "" -gdb_test "set width 0" "" + # Check that GDB can always extract a struct-return value from an + # inferior function call. Since GDB always knows the location of an + # inferior function call's return value these should never fail + + # Implemented by calling the parameterless function "fun$N" and then + # examining the return value printed by GDB. -if [target_info exists gdb,cannot_call_functions] { - setup_xfail "*-*-*" 2416 - fail "This target can not call functions" - return 0 -} + set tests "call $n ${testfile}" -if { ![runto_main] } then { - gdb_suppress_tests; + # Call fun${n}, checking the printed return-value. + setup_kfails structs-*tld* i686-*-* gdb/1447 + setup_compiler_kfails structs-tc-* gcc-3-3 "DWARF 2" i686-*-* gdb/1455 + gdb_test "p/c fun${n}()" "[foo ${n}]" "p/c fun<n>(); ${tests}" + + # Check that GDB can always pass a structure to an inferior function. + # This test can never fail. + + # Implemented by calling the one parameter function "Fun$N" which + # stores its parameter in the global variable "L$N". GDB then + # examining that global to confirm that the value is as expected. + + gdb_test "call Fun${n}(foo${n})" "" "call Fun<n>(foo<n>); ${tests}" + setup_kfails structs-*tld* i686-*-* gdb/1447 + setup_compiler_kfails structs-tc-* gcc-3-3 "DWARF 2" i686-*-* gdb/1455 + gdb_test "p/c L${n}" [foo ${n}] "p/c L<n>; ${tests}" } -do_function_calls; +# Test GDB's ability to both return a function (with "return" or +# "finish") and correctly extract/store any corresponding +# return-value. + +# Check that GDB can consistently extract/store structure return +# values. There are two cases - returned in registers and returned in +# memory. For the latter case, the return value can't be found and a +# failure is "expected". However GDB must still both return the +# function and display the final source and line information. + +# N identifies the number of elements in the struct that will be used +# for the test case. FAILS is a list of target tuples that will fail +# this test. + +# This tests the code paths "which return-value convention?", "extract +# return-value from registers", and "store return-value in registers". +# Unlike "test struct calls", this test is expected to "fail" when the +# return-value is in memory (GDB can't find the location). The test +# is in three parts: test "return"; test "finish"; check that the two +# are consistent. GDB can sometimes work for one command and not the +# other. + +proc test_struct_returns { n } { + global gdb_prompt + global testfile + + set tests "return $n ${testfile}" + + + # Check that "return" works. + + # GDB must always force the return of a function that has + # a struct result. Dependant on the ABI, it may, or may not be + # possible to store the return value in a register. + + # The relevant code looks like "L{n} = fun{n}()". The test forces + # "fun{n}" to "return" with an explicit value. Since that code + # snippet will store the the returned value in "L{n}" the return + # is tested by examining "L{n}". This assumes that the + # compiler implemented this as fun{n}(&L{n}) and hence that when + # the value isn't stored "L{n}" remains unchanged. Also check for + # consistency between this and the "finish" case. + + # Get into a call of fun${n} + gdb_test "advance fun${n}" \ + "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ + "advance to fun<n> for return; ${tests}" + + # Check that the program invalidated the relevant global. + setup_kfails structs-tld i686-*-* gdb/1447 + gdb_test "p/c L${n}" " = [zed $n]" "zed L<n> for return; ${tests} .${testfile}." + + # Force the "return". This checks that the return is always + # performed, and that GDB correctly reported this to the user. + # GDB 6.0 and earlier, when the return-value's location wasn't + # known, both failed to print a final "source and line" and misplaced + # the frame ("No frame"). + + # The test is writen so that it only reports one FAIL/PASS for the + # entire operation. The value returned is checked further down. + # "return_value_unknown", if non-empty, records why GDB realised + # that it didn't know where the return value was. + + send_gdb "return foo${n}\n" + set test "return foo<n>; ${tests}" + set return_value_unknown 0 + gdb_expect { + -re "The location" { + # Ulgh, a struct return, remember this (still need prompt). + set return_value_unknown 1 + exp_continue + } + -re "A structure or union" { + # Ulgh, a struct return, remember this (still need prompt). + # Set it to something unique so that it won't match a + # struct return convention value. + # set return_value_unknown -1 + set return_value_unknown 1 + exp_continue + } + -re "Make fun${n} return now.*y or n. $" { + send_gdb "y\n" + gdb_expect { + -re "L${n} *= fun${n}.*${gdb_prompt} $" { + # Need to step off the function call + gdb_test "next" "L.* *= fun.*" "${test}" + } + -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { + pass "${test}" + } + timeout { + fail "${test} (timeout 2)" + } + } + } + -re "${gdb_prompt} $" { + fail "${test} (no query)" + } + timeout { + fail "${test} (timeout 1)" + } + } + + # Check that the return-value is as expected. At this stage we're + # just checking that GDB has returned a value consistent with + # "return_value_unknown" set above. + + send_gdb "p/c L${n}\n" + set test "value foo<n> returned; ${tests}" + setup_kfails structs-*tld* i686-*-* gdb/1447 + gdb_expect { + -re " = [foo ${n}].*${gdb_prompt} $" { + if $return_value_unknown { + # This contradicts the above claim that GDB didn't + # know the location of the return-value. + fail "${test}" + } else { + pass "${test}" + } + } + -re " = [zed ${n}].*${gdb_prompt} $" { + if $return_value_unknown { + # The struct return case. Since any modification + # would be by reference, and that can't happen, the + # value should be unmodified and hence Z is expected. + # Is this a reasonable assumption? + pass "${test}" + } else { + # This contradicts the above claim that GDB knew + # the location of the return-value. + fail "${test}" + } + } + -re "${gdb_prompt} $" { + # Garbage returned, garbage printed + fail "${test}" + } + timeout { + fail "${test} (timeout)" + } + } + + # Check that a "finish" works. + + # This is almost but not quite the same as "call struct funcs". + # Architectures can have subtle differences in the two code paths. + + # The relevant code snippet is "L{n} = fun{n}()". The program is + # advanced into a call to "fun{n}" and then that function is + # finished. The returned value that GDB prints, reformatted using + # "p/c", is checked. + + # Get into "fun${n}()". + gdb_test "advance fun${n}" \ + "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ + "advance to fun<n> for finish; ${tests}" + + # Check that the program invalidated the relevant global. + setup_kfails structs-tld i686-*-* gdb/1447 + gdb_test "p/c L${n}" " = [zed $n]" "zed L<n> for finish; ${tests}" + + # Finish the function, set 'finish_value_unknown" to non-empty if the + # return-value was not found. + send_gdb "finish\n" + set test "finish foo${n}; ${tests}" + set finish_value_unknown 0 + gdb_expect { + -re "Value returned is .*${gdb_prompt} $" { + pass "${test}" + } + -re "Cannot determine contents.*${gdb_prompt} $" { + # Expected bad value. For the moment this is ok. + set finish_value_unknown 1 + pass "${test}" + } + -re ".*${gdb_prompt} $" { + # Garbage returned + fail "${test}" + } + timeout { + fail "${test} (timeout)" + } + } + + # Re-print the last (return-value) using the more robust + # "p/c". If no return value was found, the 'Z' from the previous + # check that the variable was cleared, is printed. + send_gdb "p/c\n" + set test "value foo${n} finished; ${tests}" + setup_kfails structs-*tld* i686-*-* gdb/1447 + gdb_expect { + -re "[foo ${n}]\[\r\n\]+${gdb_prompt} $" { + if $finish_value_unknown { + # This contradicts the above claim that GDB didn't + # know the location of the return-value. + fail "${test}" + } else { + pass "${test}" + } + } + -re "[zed ${n}]\[\r\n\]+${gdb_prompt} $" { + # The value didn't get found. This is "expected". + if $finish_value_unknown { + pass "${test}" + } else { + # This contradicts the above claim that GDB did + # know the location of the return-value. + fail "${test}" + } + } + -re ".*${gdb_prompt} $" { + # Garbage returned + fail "${test}" + } + timeout { + fail "${test} (timeout)" + } + } + + # Finally, check that "return" and finish" have consistent + # behavior. + + # Since both "return" and "finish" use equivalent "which + # return-value convention" logic, both commands should have + # identical can/can-not find return-value messages. + + # Note that since "call" and "finish" use common code paths, a + # failure here is a strong indicator of problems with "store + # return-value" code paths. Suggest looking at "return_value" + # when investigating a fix. + + set test "return and finish use same convention; ${tests}" + if {$finish_value_unknown == $return_value_unknown} { + pass "${test}" + } else { + kfail gdb/1444 "${test}" + } +} -gdb_stop_suppressing_tests; +# ABIs pass anything >8 or >16 bytes in memory but below that things +# randomly use register and/and structure conventions. Check all +# possible sized char structs in that range. But only a restricted +# range of the other types. + +# NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized structs in memory. + +# d10v is weird. 5/6 byte structs go in memory. 2 or more char +# structs go in memory. Everything else is in a register! + +# Test every single char struct from 1..17 in size. This is what the +# original "structs" test was doing. + +start_structs_test { tc } +test_struct_calls 1 +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_calls 7 +test_struct_calls 8 +test_struct_calls 9 +test_struct_calls 10 +test_struct_calls 11 +test_struct_calls 12 +test_struct_calls 13 +test_struct_calls 14 +test_struct_calls 15 +test_struct_calls 16 +test_struct_calls 17 +test_struct_returns 1 +test_struct_returns 2 +test_struct_returns 3 +test_struct_returns 4 +test_struct_returns 5 +test_struct_returns 6 +test_struct_returns 7 +test_struct_returns 8 + + +# Let the fun begin. + +# Assuming that any integer struct larger than 8 bytes goes in memory, +# come up with many and varied combinations of a return struct. For +# "struct calls" test just beyond that 8 byte boundary, for "struct +# returns" test up to that boundary. + +# For floats, assumed that up to two struct elements can be stored in +# floating point registers, regardless of their size. + +# The approx size of each structure it is computed assumed that tc=1, +# ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are +# naturally aligned. Padding being added where needed. Note that +# these numbers are just approx, the d10v has ti=2, a 64-bit has has +# tl=8. + +# Approx size: 2, 4, ... +start_structs_test { ts } +test_struct_calls 1 +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_returns 1 +test_struct_returns 2 +test_struct_returns 3 +test_struct_returns 4 + +# Approx size: 4, 8, ... +start_structs_test { ti } +test_struct_calls 1 +test_struct_calls 2 +test_struct_calls 3 +test_struct_returns 1 +test_struct_returns 2 + +# Approx size: 4, 8, ... +start_structs_test { tl } +test_struct_calls 1 +test_struct_calls 2 +test_struct_calls 3 +test_struct_returns 1 +test_struct_returns 2 + +# Approx size: 8, 16, ... +start_structs_test { tll } +test_struct_calls 1 +test_struct_calls 2 +test_struct_returns 1 + +# Approx size: 4, 8, ... +start_structs_test { tf } +test_struct_calls 1 +test_struct_calls 2 +test_struct_calls 3 +test_struct_returns 1 +test_struct_returns 2 + +# Approx size: 8, 16, ... +start_structs_test { td } +test_struct_calls 1 +test_struct_calls 2 +test_struct_returns 1 + +# Approx size: 16, 32, ... +start_structs_test { tld } +test_struct_calls 1 +test_struct_calls 2 +test_struct_returns 1 + +# Approx size: 2+1=3, 4, ... +start_structs_test { ts tc } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_calls 7 +test_struct_calls 8 +test_struct_returns 2 + +# Approx size: 4+1=5, 6, ... +start_structs_test { ti tc } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_returns 2 + +# Approx size: 4+1=5, 6, ... +start_structs_test { tl tc } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_returns 2 + +# Approx size: 8+1=9, 10, ... +start_structs_test { tll tc } +test_struct_calls 2 + +# Approx size: 4+1=5, 6, ... +start_structs_test { tf tc } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_returns 2 + +# Approx size: 8+1=9, 10, ... +start_structs_test { td tc } +test_struct_calls 2 + +# Approx size: 16+1=17, 18, ... +start_structs_test { tld tc } +test_struct_calls 2 + +# Approx size: (1+1)+2=4, 6, ... +start_structs_test { tc ts } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_calls 5 +test_struct_calls 6 +test_struct_returns 2 + +# Approx size: (1+3)+4=8, 12, ... +start_structs_test { tc ti } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_returns 2 + +# Approx size: (1+3)+4=8, 12, ... +start_structs_test { tc tl } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 +test_struct_returns 2 + +# Approx size: (1+7)+8=16, 24, ... +start_structs_test { tc tll } +test_struct_calls 2 + +# Approx size: (1+3)+4=8, 12, ... +start_structs_test { tc tf } +test_struct_calls 2 +test_struct_calls 3 +test_struct_calls 4 + +# Approx size: (1+7)+8=16, 24, ... +start_structs_test { tc td } +test_struct_calls 2 + +# Approx size: (1+15)+16=32, 48, ... +start_structs_test { tc tld } +test_struct_calls 2 + +# Some float combinations + +# Approx size: 8+4=12, 16, ... +# d10v: 4+4=8, 12, ... +start_structs_test { td tf } +test_struct_calls 2 +test_struct_returns 2 + +# Approx size: (4+4)+8=16, 32, ... +# d10v: 4+4=8, 12, ... +start_structs_test { tf td } +test_struct_calls 2 +test_struct_returns 2 return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase
@ 2003-11-08 1:05 Michael Elizabeth Chastain
2003-11-09 1:22 ` Andrew Cagney
0 siblings, 1 reply; 18+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-08 1:05 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
The results are:
PASS FAIL
gcc 2.95.3 -gdwarf-2 544 40
gcc 2.95.3 -gstabs+ 544 40
gcc 3.3.2 -gdwarf-2 540 44
gcc 3.3.2 -gstabs+ 544 40
The problem is in this code:
# Now force a return. Be careful to only produce one PASS/FAIL.
send_gdb "return foo${n}\n"
gdb_expect {
-re "Make fun${n} return now.*y or n. $" {
send_gdb "y\n"
gdb_expect {
-re "L${n} *= fun${n}.*${gdb_prompt} $" {
# Need to step off the function call
gdb_test "next" "L.* *= fun.*" "${test}"
}
-re "${gdb_prompt} $" {
pass "${test}"
}
timeout {
fail "${test} (timeout)"
}
}
}
}
First there are duplicate "${test}" names in the output,
and some of them PASS and some of them FAIL. Confusion!
The real problem is what to do when the notorious
"location at which to store the function's return value is unknown"
happens. If that message happens, perhaps it is a KFAIL because
gdb cannot do what the user asked. Or perhaps it is okay because
a message was printed. I'm leaning towards the KFAIL, myself.
But the next bit of code:
# Finally check that the value returned ended up in "L${n}".
setup_fails ${fails} gdb/1444
gdb_test "p/c L${n}" " = [foo ${n}]" "${test}"
If "location unknown" has occurred, then it's not even worthwhile
to execute this at all. Once gdb has informed the user about
"location unknown" then there should be no expectation on the
part of the user that the return value will get stored into memory.
Maybe gdb needs to print an additional message to make it
more clear to the user:
The location at which to store the function's return value is unknown.
If you continue, the return value that you specified will be ignored.
Make fun1 return now? (y or n) y
Then in the test script, if you get "location unknown", issue a KFAIL
(or do whatever) and skip a test or two.
I put up a tarball here:
ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-06.tar.gz
(The filename is lame because I made 2003-11-06-2 yesterday).
Michael C
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-08 1:05 Michael Elizabeth Chastain @ 2003-11-09 1:22 ` Andrew Cagney 2003-11-10 0:32 ` Michael Elizabeth Chastain 0 siblings, 1 reply; 18+ messages in thread From: Andrew Cagney @ 2003-11-09 1:22 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 2105 bytes --] > First there are duplicate "${test}" names in the output, > and some of them PASS and some of them FAIL. Confusion! Oops, they snuck back in :-( > The real problem is what to do when the notorious > "location at which to store the function's return value is unknown" > happens. If that message happens, perhaps it is a KFAIL because > gdb cannot do what the user asked. Or perhaps it is okay because > a message was printed. I'm leaning towards the KFAIL, myself. > > But the next bit of code: > > # Finally check that the value returned ended up in "L${n}". > setup_fails ${fails} gdb/1444 > gdb_test "p/c L${n}" " = [foo ${n}]" "${test}" > > If "location unknown" has occurred, then it's not even worthwhile > to execute this at all. Once gdb has informed the user about > "location unknown" then there should be no expectation on the > part of the user that the return value will get stored into memory. Checking my notes. There are two things being tested here: - that return/finish really did occure GDB 6.0 was doing something like this: (gdb) return foo1 Return from fun1? y Couldn't find location of return type (gdb) list No frame Even though the return was performed, GDB lost the current frame and forgot to print the new source and line. (I can't tell you exactly what it did because GDB 6.0 dies a death with this test case on PPC :-/). - the value was returned The test is actually pretty robust. For a struct return, the global won't be modified (still contains zeds). I've modified the testcase to detect/report this. > Maybe gdb needs to print an additional message to make it > more clear to the user: > > The location at which to store the function's return value is unknown. > If you continue, the return value that you specified will be ignored. > Make fun1 return now? (y or n) y Like it, yes definitly. > Then in the test script, if you get "location unknown", issue a KFAIL > (or do whatever) and skip a test or two. Attatched is todays version. I think the way the fails are listed is now "ok". Need to add more comments. Andrew [-- Attachment #2: structs.c --] [-- Type: text/plain, Size: 9987 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif #ifndef tR typedef tQ tR; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD d; }; struct struct5 {tA a; tB b; tC c; tD d; tE e; }; struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } struct struct18 fun18() { return foo18; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } #ifdef PROTOTYPES void Fun18(struct struct18 foo18) #else void Fun18(foo18) struct struct18 foo18; #endif { L18 = foo18; } zed () { L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; L15.o = L16.o = L17.o = L18.o = 'Z'; L16.p = L17.p = L18.p = 'Z'; L17.q = L18.q = 'Z'; L18.r = 'Z'; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif int i; Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); Fun18(foo18); /* An infinite loop that first clears all the variables and then calls each function. This "hack" is to make testing random functions easier - "advance funN" is guaranteed to have always been preceeded by a global variable clearing zed call. */ while (1) { zed (); L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); } return 0; } [-- Attachment #3: structs.exp --] [-- Type: text/plain, Size: 18972 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" 2416 fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Global variable that contains the list of types for the most recent # build/start. Types are encoded as two or three letter accronyms # vis: tc or char, ts for short, tld for long double. The full list # is found in structs.c. set struct_types {} # Compile a variant of structs.c using TYPES to specify the type of # the first N struct elements (the remaining elements take the type of # the last TYPES field). Run the compmiled program up to "main". # Also updates the global "struct_types" to reflect the most recent # build. proc start_structs_test { types } { global testfile global srcfile global binfile global objdir global subdir global srcdir global gdb_prompt # Set that global to the current set of structs global struct_types set struct_types $types # Create the additional flags set flags "debug" set name "" set n 0 for {set n 0} {$n<[llength ${struct_types}]} {incr n} { set m [I2A ${n}] set t [lindex ${struct_types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append name "-" "$t" } set binfile ${objdir}/${subdir}/${testfile}${name} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" \ "set print sevenbit-strings; ${struct_types}" gdb_test "set print address off" "" \ "set print address off; ${struct_types}" gdb_test "set width 0" "" \ "set width 0; ${struct_types}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${struct_types}] \{" for {set n 0} {$n<[llength ${struct_types}]} {incr n} { append foo_t "\[\r\n \]+[lindex ${struct_types} $n] [i2a $n];" } append foo_t "\[\r\n \]+\}" gdb_test "ptype foo[llength ${struct_types}]" "${foo_t}" \ "ptype foo[llength ${struct_types}]; ${struct_types}" } # The expected value for fun${n}, L${n} and foo${n}. First element is # empty to make indexing easier. "foo" returns the modified value, # "zed" returns the invalid value. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc zed { n } { return [lindex { "{}" "{a = 90 'Z'}" "{a = 90 'Z', b = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z', q = 90 'Z'}" } $n] } # Given N (0..25), return the corresponding alphabetic letter. This # is i18n proof. proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Report the test result. Use the tuples in FAILS to mark up any # expected xfail/kfail based on that result. For instance, if the # result is a XPASS, any tuple in the FAILS list gets reported as an # XPASS. Or for a KFAIL, any FAILS become KFAILS. proc report { expected test fails bug } { switch $expected { xpass { foreach f $fails { setup_xfail $f $bug } pass $test } kpass { foreach f $fails { setup_kfail $f $bug } pass $test } xfail { foreach f $fails { setup_xfail $f $bug } fail $test } kfail { foreach f $fails { setup_kfail $f $bug } fail $test } default { perror "Bad expected report $expected" } } } # Check GDB's ability to call inferior functions involving structs. proc test_struct_calls { n fails } { global struct_types global gdb_prompt # Check that GDB can always extract a struct-return value from an # inferior function call. Since GDB always knows the location of an # inferior function call's return value these should never fail # Implemented by calling the parameterless function "fun$N" and then # examining the return value printed by GDB. set tests "call ${struct_types}" # Call fun${n}, checking the printed return value. send_gdb "p/c fun${n}()\n" set test "p/c fun${n}(); ${tests}" gdb_expect { -re "[foo ${n}]\[\r\n\]+$gdb_prompt $" { report kpass "${test}" ${fails} gdb/1443 } -re "$gdb_prompt $" { # "Return value of a struct return function lost" report kfail "${test}" ${fails} gdb/1443 } timeout { fail "${test} (timeout)" } } # Check that GDB can always pass a structure to an inferior function. # This test can never fail. # Implemented by calling the one parameter function "Fun$N" which # stores its parameter in the global variable "L$N". GDB then # examining that global to confirm that the value is as expected. gdb_test "call Fun${n}(foo${n})" "" "call Fun${n}(foo${n}); ${tests}" gdb_test "p/c L${n}" [foo ${n}] "p/c L${n}; ${tests}" } proc test_struct_returns { n fails } { global gdb_prompt global struct_types set tests "return ${struct_types}" # Remember if the test involves "struct return convention". If it # does, the fail is expected - GDB can't handle the edge case. set struct_return 0 # Check that GDB can correctly force the return of a function that has # a struct result. Dependant on the ABI, it may, or may not be # possible to make this work. # The relevant code looks like "L{n} = fun{n}()". The test forces # "fun{n}" to "return" with an explicit value. Since that code # snippet will store the the returned value in "L{n}", its possible to # confirm that things work by examining "L{n}". # Get into a call of fun${n} gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for return; ${tests}" # Check that the program invalidated the relevant global. gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for return; ${tests}" # Now test a forced return. This code is checking that GDB does # not leave the user dangling and that the final resting place of # the return is clear (GDB 6.0 sometimes forgot to print the # "source and line" information leaving the user with "No frame". send_gdb "return foo${n}\n" set test "return foo${n}; ${tests}" gdb_expect { -re "The location" { # Ulgh, a struct return, remember this (still need prompt). set struct_return 1 exp_continue } -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { pass "${test}" } timeout { fail "${test} (timeout 2)" } } } -re "${gdb_prompt} $" { fail "${test} (no query)" } timeout { fail "${test} (timeout 1)" } } # Check that the retun value is as expected. As noted below, # there are two expected outcomes. send_gdb "p/c L${n}\n" set test "value foo${n} returned; ${tests}" gdb_expect { -re " = [foo ${n}].*${gdb_prompt} $" { # The value was returned and stored in the global. Can't be # the struct return case. if $struct_return { report kfail "${test}" ${fails} gdb/1444 } else { report kpass "${test}" ${fails} gdb/1444 } } -re " = [zed ${n}].*${gdb_prompt} $" { # The struct return case. Since any modification would be # by reference, and that can't happen, the value should # be unmodified and hence Z is expected. I guess this assumes # that the compiled code pass a reference to the L variable # and not something on the stack. Reasonable? if $struct_return { # expected report xfail "${test}" ${fails} gdb/1444 } else { # unexpected report kfail "${test}" ${fails} gdb/1444 } } -re "${gdb_prompt} $" { # Garbage returned, garbage printed report kfail "${test}" ${fails} gdb/1444 } timeout { fail "${test} (timeout)" } } # Check that GDB can always finish a struct-return function. # Dependant on the ABI GDB may or may not be able to find the value # returned by that function. # The relevant code snippet is "L{n} = fun{n}()". The program is # allowed to get into a call to "fun{n}" and that function is then # finished. The returned value that GDB prints is then checked. # Get into "fun${n}()". gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for finish; ${tests}" # Check that the program invalidated the relevant global. gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for finish; ${tests}" # Finish that function, this should put the return value in a # convenience variable. gdb_test "finish" "" "finish fun$n; ${tests}" # Reprint that last value but using a more robust format. # If the finish didn't display a value, the earlier ZED is displayed. send_gdb "p/c\n" set test "value foo${n} finished; ${tests}" gdb_expect { -re "[foo ${n}]\[\r\n\]+${gdb_prompt} $" { report kpass "${test}" ${fails} gdb/1444 } -re "[zed ${n}]\[\r\n\]+${gdb_prompt} $" { # Value lost, assume struct return. The return test # will have checked this. If struct return wasn't expected # its a bug. if $struct_return { report xfail "${test}" ${fails} gdb/1444 } else { report kfail "${test}" ${fails} gdb/1444 } } -re ".*${gdb_prompt} $" { # Garbage returned report kfail "${test}" ${fails} gdb/1444 } timeout { fail "${test} (timeout)" } } } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. But only a restricted # range of the other types. # On NetBSD, "unnatural" sized structs get returned in memory. start_structs_test { tc } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_calls 9 { } test_struct_calls 10 { } test_struct_calls 11 { } test_struct_calls 12 { } test_struct_calls 13 { } test_struct_calls 14 { } test_struct_calls 15 { } test_struct_calls 16 { } test_struct_calls 17 { } test_struct_returns 1 { } test_struct_returns 2 { } test_struct_returns 3 { powerpc-*-netbsd* } test_struct_returns 4 { } test_struct_returns 5 { powerpc-*-netbsd* } test_struct_returns 6 { powerpc-*-netbsd* } test_struct_returns 7 { powerpc-*-netbsd* } test_struct_returns 8 { } start_structs_test { ts} test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_returns 1 { } test_struct_returns 2 { } test_struct_returns 3 { powerpc-*-netbsd* } test_struct_returns 4 { } start_structs_test { ti } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { } test_struct_returns 2 { } start_structs_test { tl } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { } test_struct_returns 2 { } start_structs_test { tll } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { } start_structs_test { tf } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { } test_struct_returns 2 { } start_structs_test { td } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { } start_structs_test { tld } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { } start_structs_test { ts tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_returns 2 { } start_structs_test { ti tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { } start_structs_test { tl tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { } start_structs_test { tll tc } test_struct_calls 2 { } start_structs_test { tf tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { } start_structs_test { td tc } test_struct_calls 2 { } start_structs_test { tld tc } test_struct_calls 2 { } start_structs_test { tc ts } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { } start_structs_test { tc ti } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { } start_structs_test { tc tl } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { } start_structs_test { tc tll } test_struct_calls 2 { } start_structs_test { tc tf } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } start_structs_test { tc td } test_struct_calls 2 { } start_structs_test { tc tld } test_struct_calls 2 { } return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-09 1:22 ` Andrew Cagney @ 2003-11-10 0:32 ` Michael Elizabeth Chastain 2003-11-11 22:28 ` Andrew Cagney 0 siblings, 1 reply; 18+ messages in thread From: Michael Elizabeth Chastain @ 2003-11-10 0:32 UTC (permalink / raw) To: Andrew Cagney; +Cc: gdb-patches On Sat, Nov 08, 2003 at 04:50:46PM -0500, Andrew Cagney wrote: > Attatched is todays version. I think the way the fails are listed is > now "ok". Need to add more comments. Today's results: no duplicate test names, but still 39 FAILs in most configurations and 43 FAILS with gcc 3.3.2 -gdwarf-2. Tarball is at: ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-09.tar.gz Michael C [New mail address, new mail setup, feedback appreciated] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-10 0:32 ` Michael Elizabeth Chastain @ 2003-11-11 22:28 ` Andrew Cagney 0 siblings, 0 replies; 18+ messages in thread From: Andrew Cagney @ 2003-11-11 22:28 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 258 bytes --] I think we've got there. For i686 I see: === gdb Summary === # of expected passes 508 # of known failures 71 cagney@tomago$ gcc --version gcc (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-14) for d10v and ppc32 I see only passes. Andrew [-- Attachment #2: structs.c --] [-- Type: text/plain, Size: 9987 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif #ifndef tR typedef tQ tR; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD d; }; struct struct5 {tA a; tB b; tC c; tD d; tE e; }; struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } struct struct18 fun18() { return foo18; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } #ifdef PROTOTYPES void Fun18(struct struct18 foo18) #else void Fun18(foo18) struct struct18 foo18; #endif { L18 = foo18; } zed () { L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; L15.o = L16.o = L17.o = L18.o = 'Z'; L16.p = L17.p = L18.p = 'Z'; L17.q = L18.q = 'Z'; L18.r = 'Z'; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif int i; Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); Fun18(foo18); /* An infinite loop that first clears all the variables and then calls each function. This "hack" is to make testing random functions easier - "advance funN" is guaranteed to have always been preceeded by a global variable clearing zed call. */ while (1) { zed (); L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); } return 0; } [-- Attachment #3: structs.exp --] [-- Type: text/plain, Size: 22880 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Compile a variant of structs.c using TYPES to specify the type of # the first N struct elements (the remaining elements take the type of # the last TYPES field). Run the compmiled program up to "main". # Also updates the global "testfile" to reflect the most recent build. proc start_structs_test { types } { global testfile global srcfile global binfile global objdir global subdir global srcdir global gdb_prompt # Create the additional flags set flags "debug" set testfile "structs" set n 0 for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append testfile "-" "$t" } set binfile ${objdir}/${subdir}/${testfile} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" \ "set print sevenbit-strings; ${testfile}" gdb_test "set print address off" "" \ "set print address off; ${testfile}" gdb_test "set width 0" "" \ "set width 0; ${testfile}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${types}] \{" for {set n 0} {$n<[llength ${types}]} {incr n} { append foo_t "\[\r\n \]+[lindex ${types} $n] [i2a $n];" } append foo_t "\[\r\n \]+\}" gdb_test "ptype foo[llength ${types}]" "${foo_t}" \ "ptype foo[llength ${types}]; ${testfile}" } # The expected value for fun${n}, L${n} and foo${n}. First element is # empty to make indexing easier. "foo" returns the modified value, # "zed" returns the invalid value. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc zed { n } { return [lindex { "{}" "{a = 90 'Z'}" "{a = 90 'Z', b = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z'}" "{a = 90 'Z', b = 90 'Z', c = 90 'Z', d = 90 'Z', e = 90 'Z', f = 90 'Z', g = 90 'Z', h = 90 'Z', i = 90 'Z', j = 90 'Z', k = 90 'Z', l = 90 'Z', m = 90 'Z', n = 90 'Z', o = 90 'Z', p = 90 'Z', q = 90 'Z'}" } $n] } # Given N (0..25), return the corresponding alphabetic letter in lower # or upper case. This is ment to be i18n proof. proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Use the tuples in FAILS to set up any needed KFAILs. proc setup_kfails { fails bug } { foreach f $fails { setup_kfail $f $bug } } # Test GDB's ability to make inferior function calls to functions # returning (or passing in a single structs. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # start_structs_test() will have previously built a program with a # specified combination of types for those elements. To ensure # robustness of the output, "p/c" is used. # This tests the code paths "which return-value convention?" and # "extract return-value from registers" called by "infcall.c". proc test_struct_calls { n fails } { global testfile global gdb_prompt # Check that GDB can always extract a struct-return value from an # inferior function call. Since GDB always knows the location of an # inferior function call's return value these should never fail # Implemented by calling the parameterless function "fun$N" and then # examining the return value printed by GDB. set tests "call $n ${testfile}" # Call fun${n}, checking the printed return-value. setup_kfails ${fails} gdb/1443 gdb_test "p/c fun${n}()" "[foo ${n}]" "p/c fun${n}(); ${tests}" # Check that GDB can always pass a structure to an inferior function. # This test can never fail. # Implemented by calling the one parameter function "Fun$N" which # stores its parameter in the global variable "L$N". GDB then # examining that global to confirm that the value is as expected. gdb_test "call Fun${n}(foo${n})" "" "call Fun${n}(foo${n}); ${tests}" setup_kfails ${fails} gdb/1443 gdb_test "p/c L${n}" [foo ${n}] "p/c L${n}; ${tests}" } # Test GDB's ability to both return a function (with "return" or # "finish") and correctly extract/store any corresponding # return-value. # Check that GDB can consistently extract/store structure return # values. There are two cases - returned in registers and returned in # memory. For the latter case, the return value can't be found and a # failure is "expected". However GDB must still both return the # function and display the final source and line information. # N identifies the number of elements in the struct that will be used # for the test case. FAILS is a list of target tuples that will fail # this test. # This tests the code paths "which return-value convention?", "extract # return-value from registers", and "store return-value in registers". # Unlike "test struct calls", this test is expected to "fail" when the # return-value is in memory (GDB can't find the location). proc test_struct_returns { n fails } { global gdb_prompt global testfile set tests "return $n ${testfile}" # Check that "return" works. # GDB must always force the return of a function that has # a struct result. Dependant on the ABI, it may, or may not be # possible to store the return value in a register. # The relevant code looks like "L{n} = fun{n}()". The test forces # "fun{n}" to "return" with an explicit value. Since that code # snippet will store the the returned value in "L{n}" the return # is tested by examining "L{n}". This assumes that the # compiler implemented this as fun{n}(&L{n}) and hence that when # the value isn't stored "L{n}" remains unchanged. Also check for # consistency between this and the "finish" case. # Get into a call of fun${n} gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for return; ${tests}" # Check that the program invalidated the relevant global. if [string equal ${testfile} structs-tld] { setup_kfail i686-*-* gdb/1447 } gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for return; ${tests} .${testfile}." # Force the "return". This code is checking that GDB does # not leave the user dangling (did GDB really return?) and # that the final resting place of the return is clear (GDB 6.0 # sometimes forgot to print the "source and line" information # leaving the user with "No frame". Notice how it is careful # to give only one *PASS/FAIL. send_gdb "return foo${n}\n" set test "return foo${n}; ${tests}" set struct_return 0 gdb_expect { -re "The location" { # Ulgh, a struct return, remember this (still need prompt). set struct_return 1 exp_continue } -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { pass "${test}" } timeout { fail "${test} (timeout 2)" } } } -re "${gdb_prompt} $" { fail "${test} (no query)" } timeout { fail "${test} (timeout 1)" } } # Check that the return value is as expected. As noted below, # there are two expected outcomes. At this stage we're just # checking that GDB has returned a value consistent with # "struct_return" set above so only gag (kfail) failures. send_gdb "p/c L${n}\n" set test "value foo${n} returned; ${tests}" gdb_expect { -re " = [foo ${n}].*${gdb_prompt} $" { if $struct_return { # There's a contradiction between reading and writing # a struct-return value. "return" indicated that the # value couldn't be found, yet GDB then went and found # it. Gag this fail if possible. setup_kfails ${fails} gdb/1444 fail "${test}" } else { pass "${test}" } } -re " = [zed ${n}].*${gdb_prompt} $" { if $struct_return { # The struct return case. Since any modification # would be by reference, and that can't happen, the # value should be unmodified and hence Z is expected. pass "${test}" } else { # There's a contradiction between reading and writing # struct-return values. "return" indicated that this # value could be found, yet the value extracted is wrong. # Gag this fail if possible. setup_kfails ${fails} gdb/1444 fail "${test}" } } -re "${gdb_prompt} $" { # Garbage returned, garbage printed setup_kfails $fails gdb/1444 fail "${test}" } timeout { fail "${test} (timeout)" } } # Check that a "finish" works. # This is almost but not quite the same as "call struct funcs". # Architectures have subtle differences in the two code paths. # The relevant code snippet is "L{n} = fun{n}()". The program is # advanced into a call to "fun{n}" and then that function is # finished. The returned value that GDB prints is then checked. # Get into "fun${n}()". gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance to fun${n} for finish; ${tests}" # Check that the program invalidated the relevant global. if [string equal ${testfile} structs-tld] { setup_kfail i686-*-* gdb/1447 } gdb_test "p/c L${n}" " = [zed $n]" "zed L${n} for finish; ${tests}" # Finish that function, examine the result, remember a struct-return. send_gdb "finish\n" set test "finish foo${n}; ${tests}" # KFAIL all possible paths. Here a KFAILED PASS is a # contradiction and should be reported. setup_kfails $fails gdb/1444 gdb_expect { -re "Value returned is .*${gdb_prompt} $" { if $struct_return { # There's a contradiction between "finish" and # "return". One is managing to handle a return-value # in register, yet the other is not. fail "${test}" } else { pass "${test}" } } -re "Cannot determine contents.*${gdb_prompt} $" { if $struct_return { # Expected bad value. For the moment this is ok. pass "${test}" } else { # There's a contradiction between "finish" and # "return". One is managing to handle a return-value # in register, yet the other is not. fail "${test}" } } -re ".*${gdb_prompt} $" { # Garbage returned fail "${test}" } timeout { fail "${test} (timeout)" } } # Re-print the last (return-value) using the more robust # "p/c". If no return value was found, zed is seen. send_gdb "p/c\n" set test "value foo${n} finished; ${tests}" setup_kfails ${fails} gdb/1444 gdb_expect { -re "[foo ${n}]\[\r\n\]+${gdb_prompt} $" { if $struct_return { # There's a contradiction between "finish" and # "return". One is managing to handle a return-value # in register, yet the other is not. fail "${test}" } else { pass "${test}" } } -re "[zed ${n}]\[\r\n\]+${gdb_prompt} $" { # The value didn't get found. This is "expected". if $struct_return { pass "${test}" } else { # There's a contradiction between "finish" and # "return". One is managing to handle a return-value # in register, yet the other is not. fail "${test}" } } -re ".*${gdb_prompt} $" { # Garbage returned fail "${test}" } timeout { fail "${test} (timeout)" } } } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. But only a restricted # range of the other types. # NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized structs in memory. # d10v is weird. 5/6 byte structs go in memory. 2 or more char # structs go in memory. Everything else is in a register! # Test every single char struct from 1..17 in size. This is what the # original "structs" test was doing. start_structs_test { tc } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_calls 9 { } test_struct_calls 10 { } test_struct_calls 11 { } test_struct_calls 12 { } test_struct_calls 13 { } test_struct_calls 14 { } test_struct_calls 15 { } test_struct_calls 16 { } test_struct_calls 17 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } test_struct_returns 3 { i686-*-* } test_struct_returns 4 { i686-*-* } test_struct_returns 5 { i686-*-* } test_struct_returns 6 { i686-*-* } test_struct_returns 7 { i686-*-* } test_struct_returns 8 { i686-*-* } # Let the fun begin. # Assuming that any integer struct larger than 8 bytes goes in memory, # come up with many and varied combinations of a return struct. For # "struct calls" test just beyond that 8 byte boundary, for "struct # returns" test up to that boundary. # For floats, assumed that up to two struct elements can be stored in # floating point registers, regardless of their size. # The approx size of each structure it is computed assumed that tc=1, # ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are # naturally aligned. Padding being added where needed. Note that # these numbers are just approx, the d10v has ti=2, a 64-bit has has # tl=8. # Approx size: 2, 4, ... start_structs_test { ts } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } test_struct_returns 3 { i686-*-* } test_struct_returns 4 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { ti } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { tl } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 8, 16, ... start_structs_test { tll } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { i686-*-* } # Approx size: 4, 8, ... start_structs_test { tf } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_returns 1 { i686-*-* } test_struct_returns 2 { i686-*-* } # Approx size: 8, 16, ... start_structs_test { td } test_struct_calls 1 { } test_struct_calls 2 { } test_struct_returns 1 { i686-*-* } # Approx size: 16, 32, ... start_structs_test { tld } test_struct_calls 1 { i686-*-* } test_struct_calls 2 { i686-*-* } test_struct_returns 1 { i686-*-* } # Approx size: 2+1=3, 4, ... start_structs_test { ts tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_calls 7 { } test_struct_calls 8 { } test_struct_returns 2 { i686-*-* } # Approx size: 4+1=5, 6, ... start_structs_test { ti tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 4+1=5, 6, ... start_structs_test { tl tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 8+1=9, 10, ... start_structs_test { tll tc } test_struct_calls 2 { } # Approx size: 4+1=5, 6, ... start_structs_test { tf tc } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: 8+1=9, 10, ... start_structs_test { td tc } test_struct_calls 2 { } # Approx size: 16+1=17, 18, ... start_structs_test { tld tc } test_struct_calls 2 { i686-*-* } # Approx size: (1+1)+2=4, 6, ... start_structs_test { tc ts } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_calls 5 { } test_struct_calls 6 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc ti } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tl } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } test_struct_returns 2 { i686-*-* } # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc tll } test_struct_calls 2 { } # Approx size: (1+3)+4=8, 12, ... start_structs_test { tc tf } test_struct_calls 2 { } test_struct_calls 3 { } test_struct_calls 4 { } # Approx size: (1+7)+8=16, 24, ... start_structs_test { tc td } test_struct_calls 2 { } # Approx size: (1+15)+16=32, 48, ... start_structs_test { tc tld } test_struct_calls 2 { i686-*-* } # Some float combinations # Approx size: 8+4=12, 16, ... # d10v: 4+4=8, 12, ... start_structs_test { td tf } test_struct_calls 2 { } test_struct_returns 2 { i686-*-* } # Approx size: (4+4)+8=16, 32, ... # d10v: 4+4=8, 12, ... start_structs_test { tf td } test_struct_calls 2 { } test_struct_returns 2 { i686-*-* } return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase
@ 2003-11-06 20:44 Michael Elizabeth Chastain
2003-11-07 20:35 ` Andrew Cagney
0 siblings, 1 reply; 18+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-06 20:44 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Ah, this version is much beter.
The results are:
PASS FAIL
gcc 2.95.3 -gdwarf-2 290 3
gcc 2.95.3 -gstabs+ 290 3
gcc 3.3.2 -gdwarf-2 290 3
gcc 3.3.2 -gstabs+ 290 3
The three FAIL results are:
p/c fun1()^M
$1 = {a = 0x08044004c400000000000000}^M
(gdb) FAIL: gdb.base/structs.exp: p/c fun1() for call-tld 1
p/c L1^M
$3 = {a = 0x00004004c400000000000000}^M
(gdb) FAIL: gdb.base/structs.exp: p/c L1 for call-tld 1
p/c L1^M
$1 = {a = 0 '\0'}^M
(gdb) FAIL: gdb.base/structs.exp: p/c L1 for return-tc
All the test names are unique.
Michael C
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-06 20:44 Michael Elizabeth Chastain @ 2003-11-07 20:35 ` Andrew Cagney 0 siblings, 0 replies; 18+ messages in thread From: Andrew Cagney @ 2003-11-07 20:35 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 983 bytes --] > Ah, this version is much beter. > > The results are: > > PASS FAIL > gcc 2.95.3 -gdwarf-2 290 3 > gcc 2.95.3 -gstabs+ 290 3 > gcc 3.3.2 -gdwarf-2 290 3 > gcc 3.3.2 -gstabs+ 290 3 > > The three FAIL results are: > > p/c fun1()^M > $1 = {a = 0x08044004c400000000000000}^M > (gdb) FAIL: gdb.base/structs.exp: p/c fun1() for call-tld 1 > > p/c L1^M > $3 = {a = 0x00004004c400000000000000}^M > (gdb) FAIL: gdb.base/structs.exp: p/c L1 for call-tld 1 > > p/c L1^M > $1 = {a = 0 '\0'}^M > (gdb) FAIL: gdb.base/structs.exp: p/c L1 for return-tc > > All the test names are unique. Here's today's version (...). The big change is that I've managed to reduce the number of different programs being built - each variant is now only built/run once - should help with remote testing. As for how xfail/kfail are specified, it isn't pretty but it appears to work :-( See if I can think of a simplification. Andrew [-- Attachment #2: structs.c --] [-- Type: text/plain, Size: 9968 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif #ifndef tR typedef tQ tR; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD d; }; struct struct5 {tA a; tB b; tC c; tD d; tE e; }; struct struct6 {tA a; tB b; tC c; tD d; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct18 {tA a; tB b; tC c; tD d; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; tR r; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct18 foo18 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G','q','I'}, L18; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } struct struct18 fun18() { return foo18; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } #ifdef PROTOTYPES void Fun18(struct struct18 foo18) #else void Fun18(foo18) struct struct18 foo18; #endif { L18 = foo18; } zed () { L1.a = L2.a = L3.a = L4.a = L5.a = L6.a = L7.a = L8.a = L9.a = L10.a = L11.a = L12.a = L13.a = L14.a = L15.a = L16.a = L17.a = L18.a = 'Z'; L2.b = L3.b = L4.b = L5.b = L6.b = L7.b = L8.b = L9.b = L10.b = L11.b = L12.b = L13.b = L14.b = L15.b = L16.b = L17.b = L18.b = 'Z'; L3.c = L4.c = L5.c = L6.c = L7.c = L8.c = L9.c = L10.c = L11.c = L12.c = L13.c = L14.c = L15.c = L16.c = L17.c = L18.c = 'Z'; L4.d = L5.d = L6.d = L7.d = L8.d = L9.d = L10.d = L11.d = L12.d = L13.d = L14.d = L15.d = L16.d = L17.d = L18.d = 'Z'; L5.e = L6.e = L7.e = L8.e = L9.e = L10.e = L11.e = L12.e = L13.e = L14.e = L15.e = L16.e = L17.e = L18.e = 'Z'; L6.f = L7.f = L8.f = L9.f = L10.f = L11.f = L12.f = L13.f = L14.f = L15.f = L16.f = L17.f = L18.f = 'Z'; L7.g = L8.g = L9.g = L10.g = L11.g = L12.g = L13.g = L14.g = L15.g = L16.g = L17.g = L18.g = 'Z'; L8.h = L9.h = L10.h = L11.h = L12.h = L13.h = L14.h = L15.h = L16.h = L17.h = L18.h = 'Z'; L9.i = L10.i = L11.i = L12.i = L13.i = L14.i = L15.i = L16.i = L17.i = L18.i = 'Z'; L10.j = L11.j = L12.j = L13.j = L14.j = L15.j = L16.j = L17.j = L18.j = 'Z'; L11.k = L12.k = L13.k = L14.k = L15.k = L16.k = L17.k = L18.k = 'Z'; L12.l = L13.l = L14.l = L15.l = L16.l = L17.l = L18.l = 'Z'; L13.m = L14.m = L15.m = L16.m = L17.m = L18.m = 'Z'; L14.n = L15.n = L16.n = L17.n = L18.n = 'Z'; L15.o = L16.o = L17.o = L18.o = 'Z'; L16.p = L17.p = L18.p = 'Z'; L17.q = L18.q = 'Z'; L18.r = 'Z'; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif /* TEST C FUNCTIONS # 1 */ L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); /* TEST C FUNCTIONS # 2 */ L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); L18 = fun18(); Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); Fun18(foo18); return 0; } [-- Attachment #3: structs.exp --] [-- Type: text/plain, Size: 13135 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" 2416 fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Compile a variant of structs.c with TYPES specifying the type of # each of the first [llength $types] elements of all structures. proc start_structs_test { types } { global testfile global srcfile global binfile global objdir global subdir global srcdir # Create the additional flags set flags "debug" set name "" set n 0 for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" append name "-" "$t" } set binfile ${objdir}/${subdir}/${testfile}${name} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" "set print sevenbit-strings - ${types}" gdb_test "set print address off" "" "set print address off - ${types}" gdb_test "set width 0" "" "set width 0 - ${types}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${types}] {" for {set n 0} {$n<[llength ${types}]} {incr n} { append foo_t {[\r\n ]+} [lindex ${types} $n] " " [i2a $n] ";" } append foo_t {[\r\n ]+} "}" gdb_test "ptype foo[llength ${types}]" "${foo_t}" "${foo_t} - ${types}" } # The expected value for funN, LN and fooN. First element is empty to # make indexing easier. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', d = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', d = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Mark the listed tuples as known failures. It expects strings of the # form <tuple>[/[xk]fail]. proc setup_fails { fails bug } { foreach f $fails { set tuple [split $f /] switch [lindex $tuple 1] { kfail { setup_kfail [lindex $tuple 0] $bug } xfail { setup_xfail [lindex $tuple 0] $bug } default { setup_kfail [lindex $tuple 0] $bug } } } } # Check that GDB can always extract a struct-return value from an # inferior function call. Since GDB always knows the location of an # inferior function call's return value these should never fail # Implemented by calling the parameterless function "fun$N" and then # examining the return value printed by GDB. proc call_struct_func { types n fails } { global gdb_prompt set test "call fun${n} - ${types}" set result [foo ${n}] # Call fun${n}, checking the printed return value. send_gdb "p/c fun${n}()\n" gdb_expect { -re "$result\[\r\n\]+$gdb_prompt $" { pass "${test}" } -re "$gdb_prompt $" { # "Return value of a struct return function lost" setup_fails $fails gdb/1443 fail "${test}" } timeout { fail "${test} (timeout)" } } } # Check that GDB can always pass a structure to an inferior function. # This test can never fail. # Implemented by calling the one parameter function "Fun$N" which # stores its parameter in the global variable "L$N". GDB then # examining that global to confirm that the value is as expected. proc pass_struct_func { types n fails } { set test "pass foo${n} - ${types}" gdb_test "call Fun${n}(foo${n})" "" "call Fun${n}(foo${n}); ${test}" # "Return value of a struct return function lost" setup_fails $fails gdb/1443 gdb_test "p/c L${n}" [foo ${n}] "p/c L${n}; ${test}" } # Check that GDB can correctly force the return of a function that has # a struct result. Dependant on the ABI, it may, or may not be # possible to make this work. # The relevant code looks like "L{n} = fun{n}()". The test forces # "fun{n}" to "return" with an explicit value. Since that code # snippet will store the the returned value in "L{n}", its possible to # confirm that things work by examining "L{n}". proc return_struct_func { types n fails } { global gdb_prompt set test "return in fun${n} - ${types}" # Get into a call of fun${n} gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance fun${n}; ${test}" # Now force a return. Be careful to only produce one PASS/FAIL. send_gdb "return foo${n}\n" gdb_expect { -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "${gdb_prompt} $" { pass "${test}" } timeout { fail "${test} (timeout)" } } } } # Finally check that the value returned ended up in "L${n}". setup_fails ${fails} gdb/1444 gdb_test "p/c L${n}" " = [foo ${n}]" "${test}" } # Check that GDB can always finish a struct-return function. # Dependant on the ABI GDB may or may not be able to find the value # returned by that function. # The relevant code snippet is "L{n} = fun{n}()". The program is # allowed to get into a call to "fun{n}" and that function is then # finished. The returned value that GDB prints is then checked. proc finish_struct_func { types n fails } { set test "finish in fun${n} - ${types}" # Get into "fun${n}()". gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance fun${n}; ${test}" # Finish that function, this puts the return value in a # convenience variable. gdb_test "finish" "" "finish; ${test}" # Finally, print the convenience variable in a consistent way. # "$" is the most recent history variable. setup_fails ${fails} gdb/1444 gdb_test {print/c $} [foo ${n}] "${test}" } # Test GDB's struct-return code. # TYPES lists the type of the first N elements of each struct variant # that is to be tested. TYPES also determines the number of elements # in the first struct variant that will be tested. # Structures with an increasing number of elements (the number of # variants determined by CALLS (inferior function calls) and RETURNS # (return command, finish command) are then tested. proc test_structs { types calls returns } { # Now compile, start and run-to-main the program. start_structs_test ${types} # Check that GDB can call a function that returns a structure. for {set n 0} {$n<[llength $calls]} {incr n} { set fails [lindex $calls $n] set elements [expr [llength $types] + $n] call_struct_func ${types} $elements ${fails} pass_struct_func ${types} $elements ${fails} } # Check that GDB can correctly find a struct return value when a # function either finishes, or is explicitly returned. Due to ABI # restrictions, it isn't always possible to exercise this test. # The above will have modified the L* globals, get # around this by calling zed which "Z" everything. gdb_test "call zed()" "" "zed return - ${types}" gdb_test "p/c L1" " = {a = 90 'Z'}" "zed return ok - ${types}" # Check that GDB can return a struct func for {set n 0} {$n<[llength $returns]} {incr n} { return_struct_func ${types} [expr [llength $types] + $n] [lindex $returns $n] } # The above will have modified the L* globals, get # around this by calling zed which "Z" everything. gdb_test "call zed()" "" "zed finish - ${types}" gdb_test "p/c L1" " = {a = 90 'Z'}" "zed finish ok - ${types}" # Check as many functions as possible for {set n 0} {$n<[llength $returns]} {incr n} { finish_struct_func ${types} [expr [llength $types] + $n] [lindex $returns $n] } gdb_stop_suppressing_tests; } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. But only a restricted # range of the other types. # On NetBSD, "unnatural" sized structs get returned in memory. test_structs { tc } \ { {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} } \ { {} {} { powerpc-*-netbsd*/xfail } {} { powerpc-*-netbsd*/xfail } { powerpc-*-netbsd*/xfail } { powerpc-*-netbsd*/xfail } {} } test_structs { ts } \ { {} {} {} {} {} } \ { {} {} { powerpc-*-netbsd*/xfail } {} } test_structs { ti } \ { {} {} {} } \ { {} {} } test_structs { tl } \ { {} {} {} } \ { {} {} } test_structs { tll } \ { {} {} } \ { {} } test_structs { tf } \ { {} {} {} } \ { {} {} } test_structs { td } \ { {} {} } \ { {} } test_structs { tld } \ { {} } \ { {} } test_structs { ts tc } \ { {} {} {} {} {} {} {} } \ { {} } test_structs { ti tc } \ { {} {} {} {} {} } \ { {} } test_structs { tl tc } \ { {} {} {} {} {} } \ { {} } test_structs { tll tc } \ { {} } \ { } test_structs { tf tc } \ { {} {} {} {} {} } \ { {} } test_structs { td tc } \ { {} } \ { } test_structs { tld tc } \ { {} } \ { } test_structs { tc ts } \ { {} {} {} {} {} } \ { {} } test_structs { tc ti } \ { {} {} {} } \ { {} } test_structs { tc tl } \ { {} {} {} } \ { {} } test_structs { tc tll } \ { {} } \ { } test_structs { tc tf } \ { {} {} {} } \ { {} } test_structs { tc td } \ { {} } \ { } test_structs { tc tld } \ { {} } \ { } return 0 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase
@ 2003-11-06 19:10 Michael Elizabeth Chastain
2003-11-06 20:22 ` Andrew Cagney
0 siblings, 1 reply; 18+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-06 19:10 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
mec> # And rewritten by Andrew Cagney (cagney@redhat.com)
ac> I'll just drop that.
Okay by me.
mec> There are a lot of duplicate test names too. It would be good
mec> to uniquify them.
ac> Yes, working on it. I can't see a way to fix things like "run_to_main"
ac> though.
If you can get the low-hanging fruit then that is good enough
for now.
ac> Some debug info prints "long double", some prints "tld". I've changed
ac> whats printed to hopefully be something more robust ...
Sounds good.
ac> (gdb) FAIL: gdb.base/structs.exp: ptype foo1.a for 1tld
ac> p/c fun1()
ac> $1 = {a = 0x08044004c400000000000000}
ac>
ac> Seems GDB and GCC disagree over how the i386 returns floating-point
ac> values. My "this will always work" test has found a bug in GDB - cool.
ac> Note that the tests do all pass for PPC.
That's the kind of test I like to see!
Can you file a PR and then make the test KFAIL for i386,
with reference to the bug report. My recollection of the
policy is: new PASS is good, new KFAIL is really good,
new FAIL is bad.
I'll keep the test bed warm.
Michael C
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-06 19:10 Michael Elizabeth Chastain @ 2003-11-06 20:22 ` Andrew Cagney 0 siblings, 0 replies; 18+ messages in thread From: Andrew Cagney @ 2003-11-06 20:22 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 836 bytes --] > Can you file a PR and then make the test KFAIL for i386, > with reference to the bug report. My recollection of the > policy is: new PASS is good, new KFAIL is really good, > new FAIL is bad. By necessity, there is a great deal of flexability here. While it is reasonable to expect the new tests to be fully resolved for one specific architecture, that expectation really doesn't extend be extended to other architectures - otherwize we'd never get new tests :-) Anyway, I'll try to make the mechanism of adding the KFAILs easier, at present it is a bit messy (as in almost impossible :-) :-( I've attached a more current work-in-progress. Note that for PPC, you'll want to apply this unapproved patch: http://sources.redhat.com/ml/gdb-patches/2003-10/msg00626.html as otherwize the test trips over PPC GDB bugs. Andrew [-- Attachment #2: structs.exp --] [-- Type: text/plain, Size: 10762 bytes --] # This testcase is part of GDB, the GNU debugger. # Copyright 1996, 1997, 1999, 2003 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu if $tracelevel then { strace $tracelevel } set prms_id 0 set bug_id 0 # Some targets can't call functions, so don't even bother with this # test. if [target_info exists gdb,cannot_call_functions] { setup_xfail "*-*-*" 2416 fail "This target can not call functions" continue } set testfile "structs" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} # Create and source the file that provides information about the # compiler used to compile the test case. if [get_compiler_info ${binfile}] { return -1; } # Build a testcase with the specified set of types proc start_structs_test { name types } { global testfile global srcfile global binfile global objdir global subdir global srcdir # Create the additional flags set flags "debug" set n 0 for {set n 0} {$n<[llength ${types}]} {incr n} { set m [I2A ${n}] set t [lindex ${types} $n] lappend flags "additional_flags=-Dt${m}=${t}" } set binfile ${objdir}/${subdir}/${testfile}-${name} if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } { # built the second test case since we can't use prototypes warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES" if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } { gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." } } # Start with a fresh gdb. gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Make certain that the output is consistent gdb_test "set print sevenbit-strings" "" "set print sevenbit-strings for ${name}" gdb_test "set print address off" "" "set print address off for ${name}" gdb_test "set width 0" "" "set width 0 for ${name}" # Advance to main if { ![runto_main] } then { gdb_suppress_tests; } # check that at the struct containing all the relevant types is correct set foo_t "type = struct struct[llength ${types}] {" for {set n 0} {$n<[llength ${types}]} {incr n} { append foo_t {[\r\n ]+} [lindex ${types} $n] " " [i2a $n] ";" } append foo_t {[\r\n ]+} "}" gdb_test "ptype foo[llength ${types}]" "${foo_t}" "${foo_t} for ${name}" } # The value of each fooN structure. First element is empty to make # indexing easier. proc foo { n } { return [lindex { "{}" "{a = 49 '1'}" "{a = 97 'a', b = 50 '2'}" "{a = 49 '1', b = 98 'b', c = 51 '3'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}" "{a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}" "{a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}" } $n] } proc i2a { n } { return [string range "abcdefghijklmnopqrstuvwxyz" $n $n] } proc I2A { n } { return [string toupper [i2a $n]] } # Call FUNC with no arguments, and expect to see the regexp RESULT in # the output. Since GDB called the function, GDB always knows where # the return value is. These tests should never fail. Use a char # formatted print so that, regardless of the type of each struct # element, the printed value are always the same. proc call_struct_func { name n } { global gdb_prompt set command "p/c fun${n}()" set result [foo ${n}] send_gdb "${command}\n" gdb_expect { -re "$result\[\r\n\]+$gdb_prompt $" { pass "$command for ${name} ${n}" } -re "$gdb_prompt $" { fail "$command for ${name} ${n}" } timeout { fail "$command for ${name} ${n} (timeout)" } } } proc call_void_func { name n } { set command "p Fun${n}(foo${n})" gdb_test "${command}" " = (void|0)" "${command} for ${name} ${n}" } proc print_struct { name n } { set command "p/c L${n}" set result [foo ${n}] gdb_test "${command}" ${result} "${command} for ${name} ${n}" } proc test_function_call { name n } { # First, call the "fun" functions and examine the value they # return. This checks that GDB can correctly, and always, extract # the return value from an inferior function call. call_struct_func ${name} $n # Now call the Fun functions to set the L* variables. This # tests that gdb properly passes structures to functions (by # checking that the function stored the correct value in a global # variable). call_void_func ${name} $n print_struct ${name} $n } # Simple test - all elements are the same size proc struct_call_test { types last } { # Create the name set name "call-" foreach t $types { append name "$t" } # Now compile and run the program start_structs_test ${name} ${types} # Test all relevant functions. Skip those that don't at least # contain all the specified types, and stop at the upper bound. for {set test [llength ${types}]} {$test<=$last} {incr test} { test_function_call ${name} $test } gdb_stop_suppressing_tests; } # ABIs pass anything >8 or >16 bytes in memory but below that things # randomly use register and/and structure conventions. Check all # possible sized char structs in that range. struct_call_test { tc } 17 # Now do the same for other typed structs but this time limit things # to roughly 8 bytes. struct_call_test { ts } 5 struct_call_test { ti } 3 struct_call_test { tl } 3 struct_call_test { tll } 2 struct_call_test { tf } 3 struct_call_test { td } 2 struct_call_test { tld } 1 struct_call_test { ts tc } 7 struct_call_test { ti tc } 5 struct_call_test { tl tc } 5 struct_call_test { tll tc } 1 struct_call_test { tf tc } 5 struct_call_test { td tc } 1 struct_call_test { tld tc } 1 struct_call_test { tc ts } 5 struct_call_test { tc ti } 3 struct_call_test { tc tl } 3 struct_call_test { tc tll } 1 struct_call_test { tc tf } 3 struct_call_test { tc td } 1 struct_call_test { tc tld } 1 # Check that GDB can force a struct return value. This tests the # "return_value" write path. # Advance to parameterless FUNC and force its return. proc return_struct_func { name n } { global gdb_prompt gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance fun${n} for ${name}" # Be careful to only produce one PASS/FAIL. send_gdb "return foo${n}\n" gdb_expect { -re "Make fun${n} return now.*y or n. $" { send_gdb "y\n" gdb_expect { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "return foo${n} for ${name}" } -re "${gdb_prompt} $" { pass "return foo${n} for ${name}" } timeout { fail "return foo${n} for ${name} (timeout)" } } } } # Check that the returned value really was returned. gdb_test "p/c L${n}" " = [foo ${n}]" "p/c L${n} for ${name}" } proc struct_return_test { types last } { set n [llength ${types}] # Create the name set name "return-" foreach t $types { append name "$t" } # Now compile and run the program start_structs_test ${name} ${types} # Check as many functions as possible for {set test [llength ${types}]} {$test<=$last} {incr test} { return_struct_func ${name} ${test} } gdb_stop_suppressing_tests; } struct_return_test { tc } 1 # Check that GDB can do a finish. This checks the struct return read # path. # Advance to parameterless FUNC and force its return. proc finish_struct_func { name n } { gdb_test "advance fun${n}" \ "fun${n} .*\[\r\n\]+\[0-9\].*return foo${n}.*" \ "advance fun${n} for ${name}" gdb_test "finish" "[foo ${n}]" "finish for ${name} ${n}" } proc struct_finish_test { types last } { # Create the name set name "finish-" foreach t $types { append name "$t" } # Now compile and run the program start_structs_test ${name} ${types} # Check as many functions as possible for {set test [llength ${types}]} {$test<=$last} {incr test} { finish_struct_func ${name} ${test} } gdb_stop_suppressing_tests; } struct_finish_test { tc } 1 return 0 [-- Attachment #3: structs.c --] [-- Type: text/plain, Size: 7852 bytes --] /* This testcase is part of GDB, the GNU debugger. Copyright 1996, 1999, 2003 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please email any bugs, comments, and/or additions to this file to: bug-gdb@prep.ai.mit.edu */ /* Useful abreviations. */ typedef void t; typedef char tc; typedef short ts; typedef int ti; typedef long tl; typedef long long tll; typedef float tf; typedef double td; typedef long double tld; /* Force the type of each field. */ #ifndef tA typedef t tA; #endif #ifndef tB typedef tA tB; #endif #ifndef tC typedef tB tC; #endif #ifndef tD typedef tC tD; #endif #ifndef tE typedef tD tE; #endif #ifndef tF typedef tE tF; #endif #ifndef tG typedef tF tG; #endif #ifndef tH typedef tG tH; #endif #ifndef tI typedef tH tI; #endif #ifndef tJ typedef tI tJ; #endif #ifndef tK typedef tJ tK; #endif #ifndef tL typedef tK tL; #endif #ifndef tM typedef tL tM; #endif #ifndef tN typedef tM tN; #endif #ifndef tO typedef tN tO; #endif #ifndef tP typedef tO tP; #endif #ifndef tQ typedef tP tQ; #endif struct struct1 {tA a;}; struct struct2 {tA a; tB b;}; struct struct3 {tA a; tB b; tC c; }; struct struct4 {tA a; tB b; tC c; tD D; }; struct struct5 {tA a; tB b; tC c; tD D; tE e; }; struct struct6 {tA a; tB b; tC c; tD D; tE e; tF f; }; struct struct7 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; }; struct struct8 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; }; struct struct9 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; }; struct struct10 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; }; struct struct11 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; }; struct struct12 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; }; struct struct13 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; }; struct struct14 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; }; struct struct15 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; }; struct struct16 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; }; struct struct17 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; }; struct struct1 foo1 = {'1'}, L1; struct struct2 foo2 = {'a','2'}, L2; struct struct3 foo3 = {'1','b','3'}, L3; struct struct4 foo4 = {'a','2','c','4'}, L4; struct struct5 foo5 = {'1','b','3','d','5'}, L5; struct struct6 foo6 = {'a','2','c','4','e','6'}, L6; struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7; struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8; struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9; struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10; struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11; struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12; struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13; struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14; struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15; struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16; struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17; struct struct1 fun1() { return foo1; } struct struct2 fun2() { return foo2; } struct struct3 fun3() { return foo3; } struct struct4 fun4() { return foo4; } struct struct5 fun5() { return foo5; } struct struct6 fun6() { return foo6; } struct struct7 fun7() { return foo7; } struct struct8 fun8() { return foo8; } struct struct9 fun9() { return foo9; } struct struct10 fun10() { return foo10; } struct struct11 fun11() { return foo11; } struct struct12 fun12() { return foo12; } struct struct13 fun13() { return foo13; } struct struct14 fun14() { return foo14; } struct struct15 fun15() { return foo15; } struct struct16 fun16() { return foo16; } struct struct17 fun17() { return foo17; } #ifdef PROTOTYPES void Fun1(struct struct1 foo1) #else void Fun1(foo1) struct struct1 foo1; #endif { L1 = foo1; } #ifdef PROTOTYPES void Fun2(struct struct2 foo2) #else void Fun2(foo2) struct struct2 foo2; #endif { L2 = foo2; } #ifdef PROTOTYPES void Fun3(struct struct3 foo3) #else void Fun3(foo3) struct struct3 foo3; #endif { L3 = foo3; } #ifdef PROTOTYPES void Fun4(struct struct4 foo4) #else void Fun4(foo4) struct struct4 foo4; #endif { L4 = foo4; } #ifdef PROTOTYPES void Fun5(struct struct5 foo5) #else void Fun5(foo5) struct struct5 foo5; #endif { L5 = foo5; } #ifdef PROTOTYPES void Fun6(struct struct6 foo6) #else void Fun6(foo6) struct struct6 foo6; #endif { L6 = foo6; } #ifdef PROTOTYPES void Fun7(struct struct7 foo7) #else void Fun7(foo7) struct struct7 foo7; #endif { L7 = foo7; } #ifdef PROTOTYPES void Fun8(struct struct8 foo8) #else void Fun8(foo8) struct struct8 foo8; #endif { L8 = foo8; } #ifdef PROTOTYPES void Fun9(struct struct9 foo9) #else void Fun9(foo9) struct struct9 foo9; #endif { L9 = foo9; } #ifdef PROTOTYPES void Fun10(struct struct10 foo10) #else void Fun10(foo10) struct struct10 foo10; #endif { L10 = foo10; } #ifdef PROTOTYPES void Fun11(struct struct11 foo11) #else void Fun11(foo11) struct struct11 foo11; #endif { L11 = foo11; } #ifdef PROTOTYPES void Fun12(struct struct12 foo12) #else void Fun12(foo12) struct struct12 foo12; #endif { L12 = foo12; } #ifdef PROTOTYPES void Fun13(struct struct13 foo13) #else void Fun13(foo13) struct struct13 foo13; #endif { L13 = foo13; } #ifdef PROTOTYPES void Fun14(struct struct14 foo14) #else void Fun14(foo14) struct struct14 foo14; #endif { L14 = foo14; } #ifdef PROTOTYPES void Fun15(struct struct15 foo15) #else void Fun15(foo15) struct struct15 foo15; #endif { L15 = foo15; } #ifdef PROTOTYPES void Fun16(struct struct16 foo16) #else void Fun16(foo16) struct struct16 foo16; #endif { L16 = foo16; } #ifdef PROTOTYPES void Fun17(struct struct17 foo17) #else void Fun17(foo17) struct struct17 foo17; #endif { L17 = foo17; } int main() { #ifdef usestubs set_debug_traps(); breakpoint(); #endif /* TEST C FUNCTIONS */ L1 = fun1(); L2 = fun2(); L3 = fun3(); L4 = fun4(); L5 = fun5(); L6 = fun6(); L7 = fun7(); L8 = fun8(); L9 = fun9(); L10 = fun10(); L11 = fun11(); L12 = fun12(); L13 = fun13(); L14 = fun14(); L15 = fun15(); L16 = fun16(); L17 = fun17(); foo1.a = foo2.a = foo3.a = foo4.a = foo5.a = foo6.a = foo7.a = foo8.a = foo9.a = foo10.a = foo11.a = foo12.a = foo13.a = foo14.a = foo15.a = foo16.a = foo17.a = '$'; Fun1(foo1); Fun2(foo2); Fun3(foo3); Fun4(foo4); Fun5(foo5); Fun6(foo6); Fun7(foo7); Fun8(foo8); Fun9(foo9); Fun10(foo10); Fun11(foo11); Fun12(foo12); Fun13(foo13); Fun14(foo14); Fun15(foo15); Fun16(foo16); Fun17(foo17); return 0; } ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase
@ 2003-11-06 17:33 Michael Elizabeth Chastain
2003-11-06 18:49 ` Andrew Cagney
2003-11-06 21:38 ` Michael Snyder
0 siblings, 2 replies; 18+ messages in thread
From: Michael Elizabeth Chastain @ 2003-11-06 17:33 UTC (permalink / raw)
To: ac131313, gdb-patches
I'm concerned about the use of "long long" in a test program.
What if someone uses a non-gcc Ansi C compiler?
But this doesn't look any worse than other tests, so okay.
In structs.exp, line 22:
# This file was written by Jeff Law. (law@cygnus.com)
Add something like:
# And rewritten by Andrew Cagney (cagney@redhat.com)
I got a lot of FAILS with the new tests.
native i686-pc-linux-gnu, gdb HEAD, binutils 2.14.
PASS FAIL
gcc 2.95.3 -gdwarf-2 1086 138
gcc 2.95.3 -gstabs+ 1122 102
gcc 3.3.2 -gdwarf-2 1122 102
gcc 3.3.2 -gstabs+ 1122 102
I have put up a tarball:
ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-06-2.tar.gz
There are a lot of duplicate test names too. It would be good
to uniquify them.
Not proofread yet because of so many FAIL results.
Michael C
2003-11-05 Andrew Cagney <cagney@redhat.com>
* gdb.base/structs.exp: Update copyright. Rewrite.
* gdb.base/structs.c: Update copyright. Rewrite.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-06 17:33 Michael Elizabeth Chastain @ 2003-11-06 18:49 ` Andrew Cagney 2003-11-06 21:38 ` Michael Snyder 1 sibling, 0 replies; 18+ messages in thread From: Andrew Cagney @ 2003-11-06 18:49 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: gdb-patches > I'm concerned about the use of "long long" in a test program. > What if someone uses a non-gcc Ansi C compiler? > But this doesn't look any worse than other tests, so okay. > > In structs.exp, line 22: > > # This file was written by Jeff Law. (law@cygnus.com) > > Add something like: > > # And rewritten by Andrew Cagney (cagney@redhat.com) I'll just drop that. > I got a lot of FAILS with the new tests. > native i686-pc-linux-gnu, gdb HEAD, binutils 2.14. > > PASS FAIL > gcc 2.95.3 -gdwarf-2 1086 138 > gcc 2.95.3 -gstabs+ 1122 102 > gcc 3.3.2 -gdwarf-2 1122 102 > gcc 3.3.2 -gstabs+ 1122 102 > > I have put up a tarball: > > ftp://ftp.shout.net/pub/users/mec/gdb/2003-11-06-2.tar.gz > > There are a lot of duplicate test names too. It would be good > to uniquify them. Yes, working on it. I can't see a way to fix things like "run_to_main" though. > Not proofread yet because of so many FAIL results. Looks like two problems: (gdb) ptype foo1.a type = tld (gdb) FAIL: gdb.base/structs.exp: ptype foo1.a for 1tld Some debug info prints "long double", some prints "tld". I've changed whats printed to hopefully be something more robust ... (gdb) FAIL: gdb.base/structs.exp: ptype foo1.a for 1tld p/c fun1() $1 = {a = 0x08044004c400000000000000} Seems GDB and GCC disagree over how the i386 returns floating-point values. My "this will always work" test has found a bug in GDB - cool. Note that the tests do all pass for PPC. I've also trimmed back the number of tests so that they are more focused. I'll post a revision later today. thanks, Andrew ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [patch/rfc] Rewrite "structs" testcase 2003-11-06 17:33 Michael Elizabeth Chastain 2003-11-06 18:49 ` Andrew Cagney @ 2003-11-06 21:38 ` Michael Snyder 1 sibling, 0 replies; 18+ messages in thread From: Michael Snyder @ 2003-11-06 21:38 UTC (permalink / raw) To: Michael Elizabeth Chastain; +Cc: ac131313, gdb-patches Michael Elizabeth Chastain wrote: > I'm concerned about the use of "long long" in a test program. > What if someone uses a non-gcc Ansi C compiler? > But this doesn't look any worse than other tests, so okay. > > In structs.exp, line 22: > > # This file was written by Jeff Law. (law@cygnus.com) Huh! I dont understand. This file was definitely written by Michael Snyder. Ah, well, looks as if it's been extensively re-written since then... ^ permalink raw reply [flat|nested] 18+ messages in thread
* [patch/rfc] Rewrite "structs" testcase
@ 2003-11-05 22:17 Andrew Cagney
0 siblings, 0 replies; 18+ messages in thread
From: Andrew Cagney @ 2003-11-05 22:17 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 578 bytes --]
Hello,
The attached rewrites the "structs" testcase, greatly increasing its
coverage of struct return inferior function call edge cases. Of note
the patch:
- hacks structs.c so that it can be built to test almost any scalar
struct return construct
- rewrites structs.exp to build structs.c / test structs.c with several
combinations of char, short, int, long, long long, float, double, and
long double.
- since the bug that stopped GDB finding inferior function call struct
return values has been fixed, it expects all tests to pass
Look ok? Tested on PPC.
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 25147 bytes --]
2003-11-05 Andrew Cagney <cagney@redhat.com>
* gdb.base/structs.exp: Update copyright. Rewrite.
* gdb.base/structs.c: Update copyright. Rewrite.
Index: gdb.base/structs.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/structs.c,v
retrieving revision 1.2
diff -u -r1.2 structs.c
--- gdb.base/structs.c 6 Mar 2001 08:21:51 -0000 1.2
+++ gdb.base/structs.c 5 Nov 2003 22:02:58 -0000
@@ -1,4 +1,6 @@
-/* Copyright 1996, 1999 Free Software Foundation, Inc.
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 1996, 1999, 2003 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
@@ -17,37 +19,105 @@
Please email any bugs, comments, and/or additions to this file to:
bug-gdb@prep.ai.mit.edu */
-struct struct1 { char a;};
-struct struct2 { char a, b;};
-struct struct3 { char a, b, c; };
-struct struct4 { char a, b, c, d; };
-struct struct5 { char a, b, c, d, e; };
-struct struct6 { char a, b, c, d, e, f; };
-struct struct7 { char a, b, c, d, e, f, g; };
-struct struct8 { char a, b, c, d, e, f, g, h; };
-struct struct9 { char a, b, c, d, e, f, g, h, i; };
-struct struct10 { char a, b, c, d, e, f, g, h, i, j; };
-struct struct11 { char a, b, c, d, e, f, g, h, i, j, k; };
-struct struct12 { char a, b, c, d, e, f, g, h, i, j, k, l; };
-struct struct16 { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; };
-
-struct struct1 foo1 = {'1'}, L1;
-struct struct2 foo2 = { 'a', 'b'}, L2;
-struct struct3 foo3 = { 'A', 'B', 'C'}, L3;
-struct struct4 foo4 = {'1', '2', '3', '4'}, L4;
-struct struct5 foo5 = {'a', 'b', 'c', 'd', 'e'}, L5;
-struct struct6 foo6 = {'A', 'B', 'C', 'D', 'E', 'F'}, L6;
-struct struct7 foo7 = {'1', '2', '3', '4', '5', '6', '7'}, L7;
-struct struct8 foo8 = {'1', '2', '3', '4', '5', '6', '7', '8'}, L8;
-struct struct9 foo9 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, L9;
-struct struct10 foo10 = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}, L10;
-struct struct11 foo11 = {
- '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'}, L11;
-struct struct12 foo12 = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}, L12;
-struct struct16 foo16 = {
- 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'}, L16;
+/* Useful abreviations. */
+typedef void t;
+typedef char tc;
+typedef short ts;
+typedef int ti;
+typedef long tl;
+typedef long long tll;
+typedef float tf;
+typedef double td;
+typedef long double tld;
+
+/* Force the type of each field. */
+#ifndef tA
+typedef t tA;
+#endif
+#ifndef tB
+typedef tA tB;
+#endif
+#ifndef tC
+typedef tB tC;
+#endif
+#ifndef tD
+typedef tC tD;
+#endif
+#ifndef tE
+typedef tD tE;
+#endif
+#ifndef tF
+typedef tE tF;
+#endif
+#ifndef tG
+typedef tF tG;
+#endif
+#ifndef tH
+typedef tG tH;
+#endif
+#ifndef tI
+typedef tH tI;
+#endif
+#ifndef tJ
+typedef tI tJ;
+#endif
+#ifndef tK
+typedef tJ tK;
+#endif
+#ifndef tL
+typedef tK tL;
+#endif
+#ifndef tM
+typedef tL tM;
+#endif
+#ifndef tN
+typedef tM tN;
+#endif
+#ifndef tO
+typedef tN tO;
+#endif
+#ifndef tP
+typedef tO tP;
+#endif
+#ifndef tQ
+typedef tP tQ;
+#endif
+
+struct struct1 {tA a;};
+struct struct2 {tA a; tB b;};
+struct struct3 {tA a; tB b; tC c; };
+struct struct4 {tA a; tB b; tC c; tD D; };
+struct struct5 {tA a; tB b; tC c; tD D; tE e; };
+struct struct6 {tA a; tB b; tC c; tD D; tE e; tF f; };
+struct struct7 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; };
+struct struct8 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; };
+struct struct9 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; };
+struct struct10 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; };
+struct struct11 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; };
+struct struct12 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; };
+struct struct13 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; };
+struct struct14 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; };
+struct struct15 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; };
+struct struct16 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; };
+struct struct17 {tA a; tB b; tC c; tD D; tE e; tF f; tG g; tH h; tI i; tJ j; tK k; tL l; tM m; tN n; tO o; tP p; tQ q; };
+
+struct struct1 foo1 = {'1'}, L1;
+struct struct2 foo2 = {'a','2'}, L2;
+struct struct3 foo3 = {'1','b','3'}, L3;
+struct struct4 foo4 = {'a','2','c','4'}, L4;
+struct struct5 foo5 = {'1','b','3','d','5'}, L5;
+struct struct6 foo6 = {'a','2','c','4','e','6'}, L6;
+struct struct7 foo7 = {'1','b','3','d','5','f','7'}, L7;
+struct struct8 foo8 = {'a','2','c','4','e','6','g','8'}, L8;
+struct struct9 foo9 = {'1','b','3','d','5','f','7','h','9'}, L9;
+struct struct10 foo10 = {'a','2','c','4','e','6','g','8','i','A'}, L10;
+struct struct11 foo11 = {'1','b','3','d','5','f','7','h','9','j','B'}, L11;
+struct struct12 foo12 = {'a','2','c','4','e','6','g','8','i','A','k','C'}, L12;
+struct struct13 foo13 = {'1','b','3','d','5','f','7','h','9','j','B','l','D'}, L13;
+struct struct14 foo14 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E'}, L14;
+struct struct15 foo15 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F'}, L15;
+struct struct16 foo16 = {'a','2','c','4','e','6','g','8','i','A','k','C','m','E','o','G'}, L16;
+struct struct17 foo17 = {'1','b','3','d','5','f','7','h','9','j','B','l','D','n','F','p','H'}, L17;
struct struct1 fun1()
{
@@ -97,10 +167,26 @@
{
return foo12;
}
+struct struct13 fun13()
+{
+ return foo13;
+}
+struct struct14 fun14()
+{
+ return foo14;
+}
+struct struct15 fun15()
+{
+ return foo15;
+}
struct struct16 fun16()
{
return foo16;
}
+struct struct17 fun17()
+{
+ return foo17;
+}
#ifdef PROTOTYPES
void Fun1(struct struct1 foo1)
@@ -211,6 +297,33 @@
L12 = foo12;
}
#ifdef PROTOTYPES
+void Fun13(struct struct13 foo13)
+#else
+void Fun13(foo13)
+ struct struct13 foo13;
+#endif
+{
+ L13 = foo13;
+}
+#ifdef PROTOTYPES
+void Fun14(struct struct14 foo14)
+#else
+void Fun14(foo14)
+ struct struct14 foo14;
+#endif
+{
+ L14 = foo14;
+}
+#ifdef PROTOTYPES
+void Fun15(struct struct15 foo15)
+#else
+void Fun15(foo15)
+ struct struct15 foo15;
+#endif
+{
+ L15 = foo15;
+}
+#ifdef PROTOTYPES
void Fun16(struct struct16 foo16)
#else
void Fun16(foo16)
@@ -219,6 +332,15 @@
{
L16 = foo16;
}
+#ifdef PROTOTYPES
+void Fun17(struct struct17 foo17)
+#else
+void Fun17(foo17)
+ struct struct17 foo17;
+#endif
+{
+ L17 = foo17;
+}
int main()
{
@@ -240,10 +362,15 @@
L10 = fun10();
L11 = fun11();
L12 = fun12();
+ L13 = fun13();
+ L14 = fun14();
+ L15 = fun15();
L16 = fun16();
+ L17 = fun17();
foo1.a = foo2.a = foo3.a = foo4.a = foo5.a = foo6.a = foo7.a = foo8.a =
- foo9.a = foo10.a = foo11.a = foo12.a = foo16.a = '$';
+ foo9.a = foo10.a = foo11.a = foo12.a = foo13.a = foo14.a = foo15.a =
+ foo16.a = foo17.a = '$';
Fun1(foo1);
Fun2(foo2);
@@ -257,7 +384,11 @@
Fun10(foo10);
Fun11(foo11);
Fun12(foo12);
+ Fun13(foo13);
+ Fun14(foo14);
+ Fun15(foo15);
Fun16(foo16);
+ Fun17(foo17);
return 0;
}
Index: gdb.base/structs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/structs.exp,v
retrieving revision 1.5
diff -u -r1.5 structs.exp
--- gdb.base/structs.exp 7 Jan 2002 19:20:09 -0000 1.5
+++ gdb.base/structs.exp 5 Nov 2003 22:02:58 -0000
@@ -1,4 +1,6 @@
-# Copyright 1996, 1997, 1999 Free Software Foundation, Inc.
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 1996, 1997, 1999, 2003 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
@@ -26,142 +28,241 @@
set prms_id 0
set bug_id 0
-set prototypes 1
+# Some targets can't call functions, so don't even bother with this
+# test.
+
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+# Build a variant of the testcase.
+
set testfile "structs"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
-# build the first test case
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
- # built the second test case since we can't use prototypes
- warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DNO_PROTOTYPES}] != "" } {
- gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+proc start_structs_test { suffix defs } {
+ global testfile
+ global srcfile
+ global binfile
+ global objdir
+ global subdir
+ global srcdir
+ set binfile ${objdir}/${subdir}/${testfile}-${suffix}
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug ${defs}"] != "" } {
+ # built the second test case since we can't use prototypes
+ warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug ${defs} additional_flags=-DNO_PROTOTYPES"] != "" } {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
}
- set prototypes 0
-}
-# Create and source the file that provides information about the compiler
-# used to compile the test case.
-if [get_compiler_info ${binfile}] {
- return -1;
+ # Start with a fresh gdb.
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ # Make certain that the output is consistent
+ gdb_test "set print sevenbit-strings" "" "set print sevenbit-strings for ${suffix}"
+ gdb_test "set print address off" "" "set print address off for ${suffix}"
+ gdb_test "set width 0" "" "set width 0 for ${suffix}"
}
-# Some targets can't call functions, so don't even bother with this
-# test.
-if [target_info exists gdb,cannot_call_functions] {
- setup_xfail "*-*-*" 2416
- fail "This target can not call functions"
- continue
-}
+# Create and source the file that provides information about the
+# compiler used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
# Call FUNC with no arguments, and expect to see the regexp RESULT in
-# the output. If we get back the error message "Function return value
-# unknown", call that an unsupported test; on some architectures, it's
-# impossible to find structs returned by value reliably.
-proc call_struct_func { func result } {
+# the output. Since GDB called the function, GDB always knows where
+# the return value is. These tests should never fail. Use a char
+# formatted print so that, regardless of the type of each struct
+# element, the printed value are always the same.
+
+proc call_struct_func { name n result } {
global gdb_prompt
- set command "p ${func}()"
+ set command "p/c fun${n}()"
send_gdb "${command}\n"
gdb_expect {
-re "$result\[\r\n\]+$gdb_prompt $" {
- pass "$command"
- }
- -re "Function return value unknown.\[\r\n\]+$gdb_prompt $" {
- unsupported "$command"
+ pass "$command for ${name}"
}
-re "$gdb_prompt $" {
- fail "$command"
+ fail "$command for ${name}"
}
timeout {
- fail "$command (timeout)"
+ fail "$command for ${name} (timeout)"
}
}
}
-# FIXME: Before calling this proc, we should probably verify that
-# we can call inferior functions and get a valid integral value
-# returned.
+proc call_void_func { name n } {
+ set command "p Fun${n}(foo${n})"
+ gdb_test "${command}" " = (void|0)" "${command} for ${n}"
+}
+
+proc print_struct { name n result } {
+ set command "p/c L${n}"
+ gdb_test "${command}" ${result} "${command} for ${name}"
+}
+
# Note that it is OK to check for 0 or 1 as the returned values, because C
# specifies that the numeric value of a relational or logical expression
# (computed in the inferior) is 1 for true and 0 for false.
-proc do_function_calls {} {
+proc do_function_calls { name } {
global prototypes
global gcc_compiled
global gdb_prompt
- # First, call the "fun" functions and examine the value they return.
- call_struct_func "fun1" " = {a = 49 '1'}"
- call_struct_func "fun2" " = {a = 97 'a', b = 98 'b'}"
- call_struct_func "fun3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
- call_struct_func "fun4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
- call_struct_func "fun5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
- call_struct_func "fun6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
- call_struct_func "fun7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
- call_struct_func "fun8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
- call_struct_func "fun9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
- call_struct_func "fun10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
- call_struct_func "fun11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
- call_struct_func "fun12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
- call_struct_func "fun16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
+ # First, call the "fun" functions and examine the value they
+ # return. This checks that GDB can correctly, and always, extract
+ # the return value from an inferior function call.
+
+ call_struct_func ${name} 1 " = {a = 49 '1'}"
+ call_struct_func ${name} 2 " = {a = 97 'a', b = 50 '2'}"
+ call_struct_func ${name} 3 " = {a = 49 '1', b = 98 'b', c = 51 '3'}"
+ call_struct_func ${name} 4 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4'}"
+ call_struct_func ${name} 5 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5'}"
+ call_struct_func ${name} 6 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6'}"
+ call_struct_func ${name} 7 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}"
+ call_struct_func ${name} 8 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}"
+ call_struct_func ${name} 9 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}"
+ call_struct_func ${name} 10 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}"
+ call_struct_func ${name} 11 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}"
+ call_struct_func ${name} 12 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}"
+ call_struct_func ${name} 13 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}"
+ call_struct_func ${name} 14 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}"
+ call_struct_func ${name} 15 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}"
+ call_struct_func ${name} 16 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}"
+ call_struct_func ${name} 17 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}"
# Now call the Fun functions to set the L* variables. This
# tests that gdb properly passes structures to functions.
- gdb_test "p Fun1(foo1)" " = (void|0)"
- gdb_test "p Fun2(foo2)" " = (void|0)"
- gdb_test "p Fun3(foo3)" " = (void|0)"
- gdb_test "p Fun4(foo4)" " = (void|0)"
- gdb_test "p Fun5(foo5)" " = (void|0)"
- gdb_test "p Fun6(foo6)" " = (void|0)"
- gdb_test "p Fun7(foo7)" " = (void|0)"
- gdb_test "p Fun8(foo8)" " = (void|0)"
- gdb_test "p Fun9(foo9)" " = (void|0)"
- gdb_test "p Fun10(foo10)" " = (void|0)"
- gdb_test "p Fun11(foo11)" " = (void|0)"
- gdb_test "p Fun12(foo12)" " = (void|0)"
- gdb_test "p Fun16(foo16)" " = (void|0)"
+
+ call_void_func ${name} 1
+ call_void_func ${name} 2
+ call_void_func ${name} 3
+ call_void_func ${name} 4
+ call_void_func ${name} 5
+ call_void_func ${name} 6
+ call_void_func ${name} 7
+ call_void_func ${name} 8
+ call_void_func ${name} 9
+ call_void_func ${name} 10
+ call_void_func ${name} 11
+ call_void_func ${name} 12
+ call_void_func ${name} 13
+ call_void_func ${name} 14
+ call_void_func ${name} 15
+ call_void_func ${name} 16
+ call_void_func ${name} 17
# Now print the L* variables and examine their values.
- gdb_test "p L1" " = {a = 49 '1'}"
- gdb_test "p L2" " = {a = 97 'a', b = 98 'b'}"
- gdb_test "p L3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
- gdb_test "p L4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
- gdb_test "p L5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
- gdb_test "p L6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
- gdb_test "p L7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
- gdb_test "p L8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
- gdb_test "p L9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
- gdb_test "p L10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
- gdb_test "p L11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
- gdb_test "p L12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
- gdb_test "p L16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
-}
-# Start with a fresh gdb.
-
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
-
-gdb_test "set print sevenbit-strings" ""
-gdb_test "set print address off" ""
-gdb_test "set width 0" ""
+ print_struct ${name} 1 " = {a = 49 '1'}"
+ print_struct ${name} 2 " = {a = 97 'a', b = 50 '2'}"
+ print_struct ${name} 3 " = {a = 49 '1', b = 98 'b', c = 51 '3'}"
+ print_struct ${name} 4 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4'}"
+ print_struct ${name} 5 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5'}"
+ print_struct ${name} 6 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6'}"
+ print_struct ${name} 7 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7'}"
+ print_struct ${name} 8 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8'}"
+ print_struct ${name} 9 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9'}"
+ print_struct ${name} 10 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A'}"
+ print_struct ${name} 11 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B'}"
+ print_struct ${name} 12 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C'}"
+ print_struct ${name} 13 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D'}"
+ print_struct ${name} 14 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E'}"
+ print_struct ${name} 15 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F'}"
+ print_struct ${name} 16 " = {a = 97 'a', b = 50 '2', c = 99 'c', D = 52 '4', e = 101 'e', f = 54 '6', g = 103 'g', h = 56 '8', i = 105 'i', j = 65 'A', k = 107 'k', l = 67 'C', m = 109 'm', n = 69 'E', o = 111 'o', p = 71 'G'}"
+ print_struct ${name} 17 " = {a = 49 '1', b = 98 'b', c = 51 '3', D = 100 'd', e = 53 '5', f = 102 'f', g = 55 '7', h = 104 'h', i = 57 '9', j = 106 'j', k = 66 'B', l = 108 'l', m = 68 'D', n = 110 'n', o = 70 'F', p = 112 'p', q = 72 'H'}"
+}
-if [target_info exists gdb,cannot_call_functions] {
- setup_xfail "*-*-*" 2416
- fail "This target can not call functions"
- return 0
+# Simple test - all elements are the same size
+
+proc run_struct1_test { suffix type } {
+ global ws
+ start_structs_test 1${suffix} "additional_flags=-DtA=${suffix}"
+
+ if { ![runto_main] } then {
+ gdb_suppress_tests;
+ }
+
+ # check that the type is correct
+ gdb_test "ptype foo1.a" "type = ${type}" "ptype foo1.a for 1${suffix}"
+
+ do_function_calls 2${suffix};
+
+ gdb_stop_suppressing_tests;
}
-if { ![runto_main] } then {
- gdb_suppress_tests;
+run_struct1_test tc "char"
+run_struct1_test ts "short int"
+run_struct1_test ti "int"
+run_struct1_test tl "long int"
+run_struct1_test tll "long long int"
+run_struct1_test tf "float"
+run_struct1_test td "double"
+run_struct1_test tld "long double"
+
+# First element is something strange, rest are char
+
+proc run_struct2_test { suffix type } {
+ global ws
+ start_structs_test 2${suffix} "additional_flags=-DtA=${suffix} additional_flags=-DtB=tc"
+
+ if { ![runto_main] } then {
+ gdb_suppress_tests;
+ }
+
+ # check that the types are correct
+ gdb_test "ptype foo2.a" "type = ${type}" "ptype foo2.a for 2${suffix}"
+ gdb_test "ptype foo2.b" "type = char" "ptype foo2.b for 2${suffix}"
+
+ do_function_calls 2${suffix};
+
+ gdb_stop_suppressing_tests;
}
-do_function_calls;
+run_struct2_test ts "short int"
+run_struct2_test ti "int"
+run_struct2_test tl "long int"
+run_struct2_test tll "long long int"
+run_struct2_test tf "float"
+run_struct2_test td "double"
+run_struct2_test tld "long double"
+
+# First element is char, rest are something strange
+
+proc run_struct3_test { suffix type } {
+ global ws
+ start_structs_test 3${suffix} "additional_flags=-DtA=tc additional_flags=-DtB=${suffix}"
+
+ if { ![runto_main] } then {
+ gdb_suppress_tests;
+ }
+
+ # check that the types are correct
+ gdb_test "ptype foo3.a" "type = char" "ptype foo2.a for 3${suffix}"
+ gdb_test "ptype foo3.b" "type = ${type}" "ptype foo2.b for 3${suffix}"
+
+ do_function_calls 3${suffix};
+
+ gdb_stop_suppressing_tests;
+}
-gdb_stop_suppressing_tests;
+run_struct2_test ts "short int"
+run_struct2_test ti "int"
+run_struct2_test tl "long int"
+run_struct2_test tll "long long int"
+run_struct2_test tf "float"
+run_struct2_test td "double"
+run_struct2_test tld "long double"
return 0
^ permalink raw reply [flat|nested] 18+ messages in threadend of thread, other threads:[~2003-11-20 17:17 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-11-12 16:51 [patch/rfc] Rewrite "structs" testcase Michael Elizabeth Chastain -- strict thread matches above, loose matches on Subject: below -- 2003-11-12 18:30 Michael Elizabeth Chastain 2003-11-12 18:13 Michael Elizabeth Chastain 2003-11-13 16:11 ` Andrew Cagney 2003-11-17 15:59 ` Andrew Cagney 2003-11-20 17:17 ` Andrew Cagney 2003-11-08 1:05 Michael Elizabeth Chastain 2003-11-09 1:22 ` Andrew Cagney 2003-11-10 0:32 ` Michael Elizabeth Chastain 2003-11-11 22:28 ` Andrew Cagney 2003-11-06 20:44 Michael Elizabeth Chastain 2003-11-07 20:35 ` Andrew Cagney 2003-11-06 19:10 Michael Elizabeth Chastain 2003-11-06 20:22 ` Andrew Cagney 2003-11-06 17:33 Michael Elizabeth Chastain 2003-11-06 18:49 ` Andrew Cagney 2003-11-06 21:38 ` Michael Snyder 2003-11-05 22:17 Andrew Cagney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox