This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, i386]: Fix PR target/12329
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: "H.J. Lu" <hjl dot tools at gmail dot com>
- Date: Sat, 05 Apr 2008 19:30:20 +0200
- Subject: [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;