re PR c/22052 (redefinition of inline function succeeds)
authorEric Christopher <echristo@redhat.com>
Wed, 29 Jun 2005 00:11:36 +0000 (00:11 +0000)
committerEric Christopher <echristo@gcc.gnu.org>
Wed, 29 Jun 2005 00:11:36 +0000 (00:11 +0000)
2005-06-28  Eric Christopher  <echristo@redhat.com>

        PR c/22052
        PR c/21975
        * c-decl.c (diagnose_mismatched_decls): Define DECL_EXTERN_INLINE.
        Use. Fix detection of invalid extern inline redefinition.

2005-06-28  Eric Christopher  <echristo@redhat.com>

        PR c/22052
        PR c/21975
        * gcc.dg/inline1.c: New test.
        * gcc.dg/inline2.c: Ditto.
        * gcc.dg/inline3.c: Ditto.
        * gcc.dg/inline4.c: Ditto.
        * gcc.dg/inline5.c: Ditto.

From-SVN: r101400

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/inline1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline5.c [new file with mode: 0644]

index 3d7f99365a73284647b4b9f23673051bd52c843b..2afa66c05568ac57ada2aa751d861c87a4834ce9 100644 (file)
@@ -1,3 +1,10 @@
+2005-06-28  Eric Christopher  <echristo@redhat.com>
+
+       PR c/22052
+       PR c/21975
+       * c-decl.c (diagnose_mismatched_decls): Define DECL_EXTERN_INLINE.
+       Use. Fix detection of invalid extern inline redefinition.
+
 2005-06-28  Diego Novillo  <dnovillo@redhat.com>
 
        * tree-optimize.c (init_tree_optimization_passes): Fix typo.
index eececb18d39b5b7c19ef8735756df051ee1a7372..21248ae7b1d9b3b1a2cbb35a13fc7799ce9e1108 100644 (file)
@@ -1154,6 +1154,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   bool warned = false;
   bool retval = true;
 
+#define DECL_EXTERN_INLINE(DECL) (DECL_DECLARED_INLINE_P (DECL)  \
+                                 && DECL_EXTERNAL (DECL))
+
   /* If we have error_mark_node for either decl or type, just discard
      the previous decl - we're in an error cascade already.  */
   if (olddecl == error_mark_node || newdecl == error_mark_node)
@@ -1282,6 +1285,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
      Multiple definitions are not allowed (6.9p3,5) but GCC permits
      two definitions if one is 'extern inline' and one is not.  The non-
      extern-inline definition supersedes the extern-inline definition.  */
+
   else if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
       /* If you declare a built-in function name as static, or
@@ -1304,45 +1308,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
        {
          if (DECL_INITIAL (olddecl))
            {
-             /* If both decls have extern inline and are in the same TU,
-                reject the new decl.  */
-             if (DECL_DECLARED_INLINE_P (olddecl)
-                 && DECL_EXTERNAL (olddecl)
-                 && DECL_DECLARED_INLINE_P (newdecl)
-                 && DECL_EXTERNAL (newdecl)
+             /* If both decls are in the same TU and the new declaration
+                isn't overridding an extern inline reject the new decl.
+                When we handle c99 style inline rules we'll want to reject
+                the following:
+
+                DECL_EXTERN_INLINE (olddecl)
+                && !DECL_EXTERN_INLINE (newdecl)
+
+                if they're in the same translation unit. Until we implement
+                the full semantics we accept the construct.  */
+             if (!(DECL_EXTERN_INLINE (olddecl)
+                   && !DECL_EXTERN_INLINE (newdecl))
                  && same_translation_unit_p (newdecl, olddecl))
                {
                  error ("%Jredefinition of %qD", newdecl, newdecl);
                  locate_old_decl (olddecl, error);
                  return false;
                }
-             /* If both decls have not extern inline, reject the new decl.  */
-             if (!DECL_DECLARED_INLINE_P (olddecl)
-                 && !DECL_EXTERNAL (olddecl)
-                 && !DECL_DECLARED_INLINE_P (newdecl)
-                 && !DECL_EXTERNAL (newdecl))
-               {
-                 error ("%Jredefinition of %qD", newdecl, newdecl);
-                 locate_old_decl (olddecl, error);
-                 return false;
-               }
-             /* If the new decl is declared as extern inline, error if they are
-                in the same TU, otherwise retain the old decl.  */
-             if (!DECL_DECLARED_INLINE_P (olddecl)
-                 && !DECL_EXTERNAL (olddecl)
-                 && DECL_DECLARED_INLINE_P (newdecl)
-                 && DECL_EXTERNAL (newdecl))
-               {
-                 if (same_translation_unit_p (newdecl, olddecl))
-                   {
-                     error ("%Jredefinition of %qD", newdecl, newdecl);
-                     locate_old_decl (olddecl, error);
-                     return false;
-                   }
-                 else
-                   retval = false;
-               }
-          }
+           }
        }
       /* If we have a prototype after an old-style function definition,
         the argument types must be checked specially.  */
@@ -1371,8 +1355,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
             occur only in Objective C; see also above.  (FIXME: Make
             Objective C use normal builtins.)  */
          if (!DECL_IS_BUILTIN (olddecl)
-             && !(DECL_EXTERNAL (olddecl)
-                  && DECL_DECLARED_INLINE_P (olddecl)))
+             && !DECL_EXTERN_INLINE (olddecl))
            {
              error ("%Jstatic declaration of %qD follows "
                     "non-static declaration", newdecl, newdecl);
@@ -1585,6 +1568,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
   if (warned || pedwarned)
     locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
 
+#undef DECL_EXTERN_INLINE
+
   return retval;
 }
 
index 3f6a4c5e4fe159543c786196a27e0affb55989ec..1634814bffd3db098fd94a4572df1baaab203d7d 100644 (file)
@@ -1,3 +1,13 @@
+2005-06-28  Eric Christopher  <echristo@redhat.com>
+
+       PR c/22052
+       PR c/21975
+       * gcc.dg/inline1.c: New test.
+       * gcc.dg/inline2.c: Ditto.
+       * gcc.dg/inline3.c: Ditto.
+       * gcc.dg/inline4.c: Ditto.
+       * gcc.dg/inline5.c: Ditto.
+       
 2005-06-28  Thomas Koenig  <Thomas.Koenig@online.de>
 
         PR libfortran/22142
diff --git a/gcc/testsuite/gcc.dg/inline1.c b/gcc/testsuite/gcc.dg/inline1.c
new file mode 100644 (file)
index 0000000..f7a7eb4
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -std=gnu89" } */
+/* This test is expected to fail with an error for the redefinition of foo.
+   This violates the constraint of 6.9#3 (no more than one external definition
+   of an identifier with internal linkage in the same translation unit).  */
+static inline int foo(void) { return 1; } /* { dg-error "previous definition of" } */
+static inline int foo(void) { return 0; } /* { dg-error "redefinition of" } */
+
diff --git a/gcc/testsuite/gcc.dg/inline2.c b/gcc/testsuite/gcc.dg/inline2.c
new file mode 100644 (file)
index 0000000..ede4104
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -std=gnu89" } */
+/* This test should compile successfully.  */
+extern inline int foo (void) { return 0; }
+inline int foo (void) { return 1; }
diff --git a/gcc/testsuite/gcc.dg/inline3.c b/gcc/testsuite/gcc.dg/inline3.c
new file mode 100644 (file)
index 0000000..bc755e3
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -std=gnu89" } */
+/* This testcase should fail since we're redefining foo in the same
+   translation unit.  */
+extern inline int foo(void) { return 0; }
+inline int foo (void) { return 1; } /* { dg-error "previous definition of" } */
+int foo (void) { return 2; } /* { dg-error "error: redefinition of" } */
diff --git a/gcc/testsuite/gcc.dg/inline4.c b/gcc/testsuite/gcc.dg/inline4.c
new file mode 100644 (file)
index 0000000..a5c7dda
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -std=gnu89" } */
+/* This testcase should fail since we're redefining foo in the same
+   translation unit.  */
+int foo (void) { return 2; } /* { dg-error "previous definition of" } */
+extern inline int foo (void) { return 1; } /* { dg-error "redefinition of" } */
diff --git a/gcc/testsuite/gcc.dg/inline5.c b/gcc/testsuite/gcc.dg/inline5.c
new file mode 100644 (file)
index 0000000..86a2776
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall -std=gnu89" } */
+/* This testcase should fail since we're redefining foo in the same
+   translation unit.  */
+extern inline int foo (void) { return 2; } /* { dg-error "previous definition of" } */
+extern inline int foo (void) { return 1; } /* { dg-error "redefinition of" } */