re PR target/12329 (x86: local function declared with attribute((regparm(3))) gets...
authorUros Bizjak <uros@gcc.gnu.org>
Sun, 6 Apr 2008 06:40:47 +0000 (08:40 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 6 Apr 2008 06:40:47 +0000 (08:40 +0200)
        PR target/12329
        * config/i386/i386.c (ix86_function_regparm): Error if regparm(3)
        attribute is used for nested functions.

testsuite/ChangeLog:

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

From-SVN: r133954

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr12329.c [new file with mode: 0644]

index de51e84e60451e6763af2657e9ffd2aeff331749..56c8a9407f56f103e4122e896858e3bbf8cfc857 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2008-04-05  Jan Hubicka  <jh@suse.cz>
 
        * emit-rtl.c (init_emit): xcalloc regno_pointer_align.
@@ -13,8 +19,8 @@
        it out based on pass type.
        (register_dump_files_1): Likewise.
        (init_optimization_passes): Update register_one_dump_file calls.
-       (execute_one_pass): Sanity check that IPA passes are called at IPA level
-       and RTL passes at RTL level.
+       (execute_one_pass): Sanity check that IPA passes are called at IPA
+       level and RTL passes at RTL level.
        (execute_pass_list): IPA pass can not be after or subpass of
        GIMPLE/RTL pass.
        (execute_ipa_pass_list): Handle IPA subpasses of IPA subpasses and
index 14aac4689188c7314c5c9127716214822a371be5..161f9e4fbd159daaedbf9a0a2b9486d4c81331fc 100644 (file)
@@ -3250,12 +3250,33 @@ ix86_function_regparm (const_tree type, const_tree decl)
   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 are limited to 2 register parameters");
+             error_issued = true;
+             return 0;
+           }
+       }
+
+      return regparm;
+    }
 
   if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
     return 2;
index 85105c45cce4ec011dc923a41f1bee1e5b3e7cef..ee449b600e33d6927c7d367f0224274499fd167f 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-06  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/12329
+       * gcc.target/i386/pr12329.c: New test.
+
 2008-04-05  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/pr35823.adb: Rename to size_attribute.adb.
 
        * lib/gfortran-dg.exp:  New harness to compile Fortran progs
        with all combinations of debug options available on target.
-        * gfortran.dg/debug/debug.exp:  Ditto.
-        * gfortran.dg/debug/trivial.f:  Ditto.
-        * gfortran.dg/debug/pr35154-stabs.f:  New test case for
-        .stabs functionality.
-        * gfortran.dg/debug/pr35154-dwarf2.f:  New test case for
-        DWARF functionality.
+       * gfortran.dg/debug/debug.exp:  Ditto.
+       * gfortran.dg/debug/trivial.f:  Ditto.
+       * gfortran.dg/debug/pr35154-stabs.f:  New test case for
+       .stabs functionality.
+       * gfortran.dg/debug/pr35154-dwarf2.f:  New test case for
+       DWARF functionality.
 
 2008-04-01  Volker Reichelt  <v.reichelt@netcologne.de>
 
diff --git a/gcc/testsuite/gcc.target/i386/pr12329.c b/gcc/testsuite/gcc.target/i386/pr12329.c
new file mode 100644 (file)
index 0000000..aeefeb0
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { 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 are limited to 2 register parameters" } */
+    return i + j + k + l;
+  }
+
+  return foo (i, i+1, i+2);
+}