OSDN Git Service

PR target/35504
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Mar 2008 20:00:12 +0000 (20:00 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Mar 2008 20:00:12 +0000 (20:00 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133324 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/pr35504.C [new file with mode: 0644]

index c2d7543..d3601a7 100644 (file)
@@ -1,19 +1,25 @@
+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.
 
 2008-03-18  Paolo Bonzini  <bonzini@gnu.org>
 
-        * expr.c (store_expr): Assume lang_hooks.reduce_bit_field_operations
-        is true.
-        (expand_expr_real_1) <REDUCE_BIT_FIELD>: Don't look at ignore.
-        (expand_expr_real_1): Assume lang_hooks.reduce_bit_field_operations
-        is true.  Add "&& !ignore" condition to reduce_bit_field.  Modify
-        target after ignore has been set, and move there also the commputation
-        of subtarget and original_target.
-        * langhooks-def.h (LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS): Delete.
-        (LANG_HOOKS_INITIALIZER): Remove it.
-        * langhooks.h (struct lang_hooks): Remove reduce_bit_field_operations.
+       * expr.c (store_expr): Assume lang_hooks.reduce_bit_field_operations
+       is true.
+       (expand_expr_real_1) <REDUCE_BIT_FIELD>: Don't look at ignore.
+       (expand_expr_real_1): Assume lang_hooks.reduce_bit_field_operations
+       is true.  Add "&& !ignore" condition to reduce_bit_field.  Modify
+       target after ignore has been set, and move there also the commputation
+       of subtarget and original_target.
+       * langhooks-def.h (LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS): Delete.
+       (LANG_HOOKS_INITIALIZER): Remove it.
+       * langhooks.h (struct lang_hooks): Remove reduce_bit_field_operations.
 
 2008-03-18  Richard Guenther  <rguenther@suse.de>
 
index 883f226..5bb5494 100644 (file)
@@ -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);
     }
 
index d9bca39..6a30392 100644 (file)
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/g++.dg/other/pr35504.C b/gcc/testsuite/g++.dg/other/pr35504.C
new file mode 100644 (file)
index 0000000..09c13fd
--- /dev/null
@@ -0,0 +1,147 @@
+// { 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;
+}