This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, i386]: Fix PR target/12329


Hello!

This patch errors out when regparm(3) is used for nested function. Nested functions pass static chain pointer in %ecx register, which is also used as third regparm register.

It has been suggested, that it is not appropriate to fix this issue by silently passing third argument via stack instead of register, since regparm(3) nested function can be called from asm, and arguments can't be fixed there.

2008-04-05 Uros Bizjak <ubizjak@gmail.com>

       PR target/12329
       * config/i386/i386.c (ix86_function_regparm): Error if regparm(3)
       attribute is used for nested functions.

testsuite/ChangeLog:

2008-04-05 Uros Bizjak <ubizjak@gmail.com>

       PR target/12329
       * gcc.target/i386/pr12329.c: New test.

The patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}. I'll wait until tomorrow if there are any comments on this approach before committing the patch to mainline.

Uros.
Index: testsuite/gcc.target/i386/pr12329.c
===================================================================
--- testsuite/gcc.target/i386/pr12329.c	(revision 0)
+++ testsuite/gcc.target/i386/pr12329.c	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+int test_nested (int i)
+{
+  int __attribute__ ((__noinline__, __regparm__(3))) foo(int j, int k, int l)
+  { /* { dg-error "nested functions limited to 2 register parameters" } */
+    return i + j + k + l;
+  }
+
+  return foo (i, i+1, i+2);
+}
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 133937)
+++ config/i386/i386.c	(working copy)
@@ -3250,12 +3250,33 @@ ix86_function_regparm (const_tree type, 
   tree attr;
   int regparm = ix86_regparm;
 
+  static bool error_issued;
+
   if (TARGET_64BIT)
     return regparm;
 
   attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
   if (attr)
-    return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+    {
+      regparm
+	= TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+
+      if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+	{
+	  /* We can't use regparm(3) for nested functions because
+	     these pass static chain pointer in %ecx register.  */
+	  if (!error_issued && regparm == 3
+	      && decl_function_context (decl)
+	      && !DECL_NO_STATIC_CHAIN (decl))
+	    {
+	      error ("nested functions limited to 2 register parameters");
+	      error_issued = true;
+	      return 0;
+	    }
+	}
+
+      return regparm;
+    }
 
   if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
     return 2;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]