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]

Re: [Bug c/22052] [4.0/4.1 Regression] redefinition of inlinefunction succeeds


> > This testcase fails with a redefinition error... is this the behavior we
> > want?
> 
> As recent GCC rejects it, I think an error is indeed the desired behavior.
> 

OK. Patch attached. Including new testcase (now 5).

-eric


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

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

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

	PR c/22052
	* 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.


Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.666
diff -u -p -w -r1.666 c-decl.c
--- c-decl.c	26 Jun 2005 21:21:22 -0000	1.666
+++ c-decl.c	27 Jun 2005 21:13:03 -0000
@@ -1155,6 +1155,9 @@ diagnose_mismatched_decls (tree newdecl,
   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)
@@ -1283,6 +1286,7 @@ diagnose_mismatched_decls (tree newdecl,
      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
@@ -1305,44 +1309,24 @@ diagnose_mismatched_decls (tree newdecl,
 	{
 	  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,
@@ -1372,8 +1356,7 @@ diagnose_mismatched_decls (tree newdecl,
 	     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,
   if (warned || pedwarned)
     locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
 
+#undef DECL_EXTERN_INLINE
+
   return retval;
 }
 
Index: testsuite/gcc.dg/inline1.c
===================================================================
RCS file: testsuite/gcc.dg/inline1.c
diff -N testsuite/gcc.dg/inline1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/inline1.c	27 Jun 2005 21:13:03 -0000
@@ -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" } */
+
Index: testsuite/gcc.dg/inline2.c
===================================================================
RCS file: testsuite/gcc.dg/inline2.c
diff -N testsuite/gcc.dg/inline2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/inline2.c	27 Jun 2005 21:13:03 -0000
@@ -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; }
Index: testsuite/gcc.dg/inline3.c
===================================================================
RCS file: testsuite/gcc.dg/inline3.c
diff -N testsuite/gcc.dg/inline3.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/inline3.c	27 Jun 2005 21:13:03 -0000
@@ -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" } */
Index: testsuite/gcc.dg/inline4.c
===================================================================
RCS file: testsuite/gcc.dg/inline4.c
diff -N testsuite/gcc.dg/inline4.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/inline4.c	27 Jun 2005 21:13:03 -0000
@@ -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" } */
Index: testsuite/gcc.dg/inline5.c
===================================================================
RCS file: testsuite/gcc.dg/inline5.c
diff -N testsuite/gcc.dg/inline5.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/inline5.c	27 Jun 2005 21:13:03 -0000
@@ -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" } */

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