This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug c/22052] [4.0/4.1 Regression] redefinition of inlinefunction succeeds
- From: Eric Christopher <echristo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: joseph at codesourcery dot com
- Date: Tue, 21 Jun 2005 15:28:49 -0700
- Subject: Re: [Bug c/22052] [4.0/4.1 Regression] redefinition of inlinefunction succeeds
- References: <20050613190209.22052.echristo@redhat.com> <20050617204833.25859.qmail@sourceware.org>
> These results seem OK.
Here's the full patch then. Tested on x86-linux with a bootstrap and an
--enable-intermodule bootstrap and no regressions. Four new testcases
added.
OK?
-eric
2005-06-20 Eric Christopher <echristo@redhat.com>
* c-decl.c (diagnose_mismatched_decls): Define
DECL_EXTERN_INLINE. Use. Fix detection of invalid
extern inline redefinition.
2005-06-20 Eric Christopher <echristo@redhat.com>
* gcc.dg/inline1.c: New test.
* gcc.dg/inline2.c: Ditto.
* gcc.dg/inline3.c: Ditto.
* gcc.dg/inline4.c: Ditto.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.664
diff -u -p -w -r1.664 c-decl.c
--- c-decl.c 19 Jun 2005 16:55:20 -0000 1.664
+++ c-decl.c 21 Jun 2005 22:22:46 -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 21 Jun 2005 22:22:46 -0000
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+/* 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 21 Jun 2005 22:22:46 -0000
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+/* 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 21 Jun 2005 22:22:46 -0000
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+/* 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 21 Jun 2005 22:22:46 -0000
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+/* 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" } */