Commit 34614fff by Mikulas Patocka Committed by Uros Bizjak

re PR target/35504 (incorrect code generated on i386 for C++ multiple…

re PR target/35504 (incorrect code generated on i386 for C++ multiple inheritance, large return structures and regparm or fastcall calling conventions)

        PR target/35504
        * config/i386/i386.c (x86_this_parameter): Calculate correct location
        of "this" pointer when "regparm = N" or "fastcall" is in effect.

testsuite/ChangeLog

        PR target/35504
        * g++.dg/other/pr35504.C: New test.

From-SVN: r133324
parent 88ab8cf2
2008-03-18 Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
PR target/35504
* config/i386/i386.c (x86_this_parameter): Calculate correct location
of "this" pointer when "regparm = N" or "fastcall" is in effect.
2008-03-18 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/include/texinfo.tex: Update to version 2008-03-17.10.
......
......@@ -22698,6 +22698,7 @@ x86_this_parameter (tree function)
{
tree type = TREE_TYPE (function);
bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
int nregs;
if (TARGET_64BIT)
{
......@@ -22710,11 +22711,25 @@ x86_this_parameter (tree function)
return gen_rtx_REG (DImode, parm_regs[aggr]);
}
if (ix86_function_regparm (type, function) > 0 && !stdarg_p (type))
nregs = ix86_function_regparm (type, function);
if (nregs > 0 && !stdarg_p (type))
{
int regno = AX_REG;
int regno;
if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
regno = CX_REG;
regno = aggr ? DX_REG : CX_REG;
else
{
regno = AX_REG;
if (aggr)
{
regno = DX_REG;
if (nregs == 1)
return gen_rtx_MEM (SImode,
plus_constant (stack_pointer_rtx, 4));
}
}
return gen_rtx_REG (SImode, regno);
}
......
2008-03-18 Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
PR target/35504
* g++.dg/other/pr35504.C: New test.
2008-03-18 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/forwprop-4.c: New testcase.
// { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
#define ATTR0 __attribute__((__regparm__(0)))
#define ATTR1 __attribute__((__regparm__(1)))
#define ATTR2 __attribute__((__regparm__(2)))
#define ATTR3 __attribute__((__regparm__(3)))
#define ATTR4 __attribute__((__fastcall__))
#define ATTR5 __attribute__((__stdcall__))
#define ATTR6 __attribute__((__cdecl__))
#define ATTR7
extern "C" void abort (void);
struct long_struct
{
int a[3];
};
struct long_struct ret;
class c3 *this3;
class c1
{
int val1;
public:
virtual void foo () { }
};
class c2
{
public:
virtual ATTR0 struct long_struct method0 ()
{
return ret;
}
virtual ATTR1 struct long_struct method1 ()
{
return ret;
}
virtual ATTR2 struct long_struct method2 ()
{
return ret;
}
virtual ATTR3 struct long_struct method3 ()
{
return ret;
}
virtual ATTR4 struct long_struct method4 ()
{
return ret;
}
virtual ATTR5 struct long_struct method5 ()
{
return ret;
}
virtual ATTR6 struct long_struct method6 ()
{
return ret;
}
virtual ATTR7 struct long_struct method7 ()
{
return ret;
}
};
class c3:c1, public c2
{
public:
c3 ()
{
this3 = this;
}
struct long_struct check_this (int a)
{
if (this3 != this)
abort ();
return ret;
}
virtual ATTR0 struct long_struct method0 ()
{
return check_this (0);
}
virtual ATTR1 struct long_struct method1 ()
{
return check_this (1);
}
virtual ATTR2 struct long_struct method2 ()
{
return check_this (2);
}
virtual ATTR3 struct long_struct method3 ()
{
return check_this (3);
}
virtual ATTR4 struct long_struct method4 ()
{
return check_this (4);
}
virtual ATTR5 struct long_struct method5 ()
{
return check_this (5);
}
virtual ATTR6 struct long_struct method6 ()
{
return check_this (6);
}
virtual ATTR7 struct long_struct method7 ()
{
return check_this (7);
}
};
class c3 c3_instance;
class c2 *c2_ptr = &c3_instance;
int
main ()
{
c2_ptr->method0 ();
c2_ptr->method1 ();
c2_ptr->method2 ();
c2_ptr->method3 ();
c2_ptr->method4 ();
c2_ptr->method5 ();
c2_ptr->method6 ();
c2_ptr->method7 ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment