mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 11:24:59 +08:00
re PR target/5755 (-mregparm=3 and -fomit-frame-pointer corrupt esp register)
PR target/5755 * config/i386/i386.c (ix86_return_pops_args): Only pop fake structure return argument if it was passed on the stack. * gcc.dg/20020224-1.c: New test. From-SVN: r50028
This commit is contained in:
parent
6728279090
commit
232b8f528b
@ -1,3 +1,9 @@
|
||||
2002-02-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/5755
|
||||
* config/i386/i386.c (ix86_return_pops_args): Only pop
|
||||
fake structure return argument if it was passed on the stack.
|
||||
|
||||
2002-02-25 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* attribs.c (decl_attributes): Also re-layout PARM_DECL and
|
||||
|
@ -1466,12 +1466,25 @@ ix86_return_pops_args (fundecl, funtype, size)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Lose any fake structure return argument. */
|
||||
/* Lose any fake structure return argument if it is passed on the stack. */
|
||||
if (aggregate_value_p (TREE_TYPE (funtype))
|
||||
&& !TARGET_64BIT)
|
||||
return GET_MODE_SIZE (Pmode);
|
||||
{
|
||||
int nregs = ix86_regparm;
|
||||
|
||||
return 0;
|
||||
if (funtype)
|
||||
{
|
||||
tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (funtype));
|
||||
|
||||
if (attr)
|
||||
nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
|
||||
}
|
||||
|
||||
if (!nregs)
|
||||
return GET_MODE_SIZE (Pmode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Argument support functions. */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2002-02-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/20020224-1.c: New test.
|
||||
|
||||
2002-02-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* gcc.c-torture/execute/20020225-1.c: New.
|
||||
|
41
gcc/testsuite/gcc.dg/20020224-1.c
Normal file
41
gcc/testsuite/gcc.dg/20020224-1.c
Normal file
@ -0,0 +1,41 @@
|
||||
/* PR target/5755
|
||||
This testcase failed because the caller of a function returning struct
|
||||
expected the callee to pop up the hidden return structure pointer,
|
||||
while callee was actually not poping it up (as the hidden argument
|
||||
was passed in register). */
|
||||
/* { dg-do run { target i?86-*-* } } */
|
||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
typedef struct {
|
||||
int a1, a2;
|
||||
} A;
|
||||
|
||||
A a;
|
||||
|
||||
A __attribute__ ((regparm (2)))
|
||||
foo (int x)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
int __attribute__ ((regparm (2)))
|
||||
bar (int x)
|
||||
{
|
||||
int r = foo(0).a2;
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int f;
|
||||
a.a1 = 530;
|
||||
a.a2 = 980;
|
||||
f = bar (0);
|
||||
if (f != 980)
|
||||
abort ();
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user