re PR c/36507 (ISO C99 inline semantics doesn't play together with nested functions)
authorJakub Jelinek <jakub@redhat.com>
Fri, 13 Jun 2008 09:38:31 +0000 (11:38 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 13 Jun 2008 09:38:31 +0000 (11:38 +0200)
PR c/36507
* c-decl.c (merge_decls): Don't clear DECL_EXTERNAL for
nested inline functions.
(start_decl, start_function): Don't invert DECL_EXTERNAL
for nested inline functions.

* gcc.dg/inline-28.c: New test.
* gcc.dg/inline-29.c: New test.
* gcc.dg/inline-30.c: New test.

From-SVN: r136745

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/inline-28.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline-29.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline-30.c [new file with mode: 0644]

index 1f1728914944dcede7a7a97b2a0c02c2725a2c31..37ff36aaa9ed901140915bdc21e055abb8db740d 100644 (file)
@@ -1,3 +1,11 @@
+2008-06-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/36507
+       * c-decl.c (merge_decls): Don't clear DECL_EXTERNAL for
+       nested inline functions.
+       (start_decl, start_function): Don't invert DECL_EXTERNAL
+       for nested inline functions.
+
 2008-06-13  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config/mips/mips.md: Remove TARGET_DEBUG_D_MODE conditions from
index 9abb4dfc65f2de9973372ea8b1d3c62d2b64e25b..89fdf3d1b45cdaf342a161021db9132677af6e51 100644 (file)
@@ -1763,7 +1763,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
          || !DECL_DECLARED_INLINE_P (olddecl)
          || !DECL_EXTERNAL (olddecl))
       && DECL_EXTERNAL (newdecl)
-      && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl)))
+      && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl))
+      && (DECL_CONTEXT (newdecl) == NULL_TREE
+         || TREE_CODE (DECL_CONTEXT (newdecl)) != FUNCTION_DECL))
     DECL_EXTERNAL (newdecl) = 0;
 
   if (DECL_EXTERNAL (newdecl))
@@ -3264,7 +3266,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   if (declspecs->inline_p
       && !flag_gnu89_inline
       && TREE_CODE (decl) == FUNCTION_DECL
-      && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl)))
+      && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl))
+         || current_function_decl))
     {
       if (declspecs->storage_class == csc_auto && current_scope != file_scope)
        ;
@@ -6094,7 +6097,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
   if (declspecs->inline_p
       && !flag_gnu89_inline
       && TREE_CODE (decl1) == FUNCTION_DECL
-      && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1)))
+      && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1))
+         || current_function_decl))
     {
       if (declspecs->storage_class != csc_static)
        DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1);
index 2026e22b1598ffe28d4dc4b94ee85ec8d5c0a37f..c9e1e422496c4dafc80096afcaf595a4471ad77e 100644 (file)
@@ -1,3 +1,10 @@
+2008-06-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/36507
+       * gcc.dg/inline-28.c: New test.
+       * gcc.dg/inline-29.c: New test.
+       * gcc.dg/inline-30.c: New test.
+
 2008-06-12  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/36462
diff --git a/gcc/testsuite/gcc.dg/inline-28.c b/gcc/testsuite/gcc.dg/inline-28.c
new file mode 100644 (file)
index 0000000..20916ae
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR c/36507 */
+/* { dg-do run } */
+/* { dg-options "-O0 -std=gnu89" } */
+
+int
+main (void)
+{
+  int i = 2;
+  auto inline int f1 (void)
+  {
+    return i;
+  }
+  inline int f2 (void)
+  {
+    return i;
+  }
+  auto inline int f3 (void);
+  auto inline int f3 (void)
+  {
+    return i;
+  }
+  auto inline int f4 (void);
+  inline int f4 (void)
+  {
+    return i;
+  }
+  return f1 () + f2 () + f3 () + f4 () - 8;
+}
diff --git a/gcc/testsuite/gcc.dg/inline-29.c b/gcc/testsuite/gcc.dg/inline-29.c
new file mode 100644 (file)
index 0000000..77672f3
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR c/36507 */
+/* { dg-do run } */
+/* { dg-options "-O0 -std=gnu99" } */
+
+int
+main (void)
+{
+  int i = 2;
+  auto inline int f1 (void)
+  {
+    return i;
+  }
+  inline int f2 (void)
+  {
+    return i;
+  }
+  auto inline int f3 (void);
+  auto inline int f3 (void)
+  {
+    return i;
+  }
+  auto inline int f4 (void);
+  inline int f4 (void)
+  {
+    return i;
+  }
+  return f1 () + f2 () + f3 () + f4 () - 8;
+}
diff --git a/gcc/testsuite/gcc.dg/inline-30.c b/gcc/testsuite/gcc.dg/inline-30.c
new file mode 100644 (file)
index 0000000..bb9b2b4
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR c/36507 */
+/* { dg-do run } */
+/* { dg-options "-O0 -std=gnu99 -fgnu89-inline" } */
+
+int
+main (void)
+{
+  int i = 2;
+  auto inline int f1 (void)
+  {
+    return i;
+  }
+  inline int f2 (void)
+  {
+    return i;
+  }
+  auto inline int f3 (void);
+  auto inline int f3 (void)
+  {
+    return i;
+  }
+  auto inline int f4 (void);
+  inline int f4 (void)
+  {
+    return i;
+  }
+  return f1 () + f2 () + f3 () + f4 () - 8;
+}