jjc@UUNET.UU.NET (James Clark) (09/13/89)
g++ 1.35.0 configured for i386g generates incorrect code for the
following:
struct units {
int n;
units(int i);
};
void foo(units);
struct A {
units u;
A(int);
units get();
};
main()
{
A *p = new A(120);
foo(p->get());
}
units::units(int i) : n(i)
{
}
units A::get()
{
return u;
}
A::A(int i) : u(i)
{
}
void foo(units u)
{
printf("%d\n", u.n);
}
The assembly for main.c (without -O) is
_main:
pushl %ebp
movl %esp,%ebp
subl $4,%esp
pushl %ebx
pushl $120
pushl $0
call _A_PSA_SI
movl %eax,-4(%ebp)
subl $0,%esp
movl %esp,%eax
movl -4(%ebp),%ebx
pushl %ebx
pushl %eax
call _get_PSA
leal 4(%esp),%esp <** should be leal 8(%esp),%esp
call _foo
leal 8(%esp),%esp
L1:
leal -8(%ebp),%esp
popl %ebx
leave
ret
The fix is to incorporate the following change made in gcc 1.35:
*** expr.c.distrib Tue Sep 12 19:01:01 1989
--- expr.c Tue Sep 12 19:01:13 1989
***************
*** 4122,4128 ****
INIT_CUMULATIVE_ARGS (args_so_far, funtype);
tem = FUNCTION_ARG (args_so_far, Pmode,
build_pointer_type (TREE_TYPE (funtype)), 1);
! if (tem != 0 && GET_CODE (tem) == MEM)
{
actparms = tree_cons (error_mark_node,
build (SAVE_EXPR,
--- 4122,4128 ----
INIT_CUMULATIVE_ARGS (args_so_far, funtype);
tem = FUNCTION_ARG (args_so_far, Pmode,
build_pointer_type (TREE_TYPE (funtype)), 1);
! if (tem == 0)
{
actparms = tree_cons (error_mark_node,
build (SAVE_EXPR,
James Clark
jjc@jclark.uucp