From 6663ee3b84d0ba79c38fc63216307ce91ef174d7 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 29 Jun 2005 00:11:36 +0000 Subject: [PATCH] re PR c/22052 (redefinition of inline function succeeds) 2005-06-28 Eric Christopher 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 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 | 7 +++++ gcc/c-decl.c | 55 +++++++++++++--------------------- gcc/testsuite/ChangeLog | 10 +++++++ gcc/testsuite/gcc.dg/inline1.c | 8 +++++ gcc/testsuite/gcc.dg/inline2.c | 5 ++++ gcc/testsuite/gcc.dg/inline3.c | 7 +++++ gcc/testsuite/gcc.dg/inline4.c | 6 ++++ gcc/testsuite/gcc.dg/inline5.c | 6 ++++ 8 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/inline1.c create mode 100644 gcc/testsuite/gcc.dg/inline2.c create mode 100644 gcc/testsuite/gcc.dg/inline3.c create mode 100644 gcc/testsuite/gcc.dg/inline4.c create mode 100644 gcc/testsuite/gcc.dg/inline5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d7f99365a7..2afa66c0556 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-06-28 Eric Christopher + + 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 * tree-optimize.c (init_tree_optimization_passes): Fix typo. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index eececb18d39..21248ae7b1d 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f6a4c5e4fe..1634814bffd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2005-06-28 Eric Christopher + + 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 PR libfortran/22142 diff --git a/gcc/testsuite/gcc.dg/inline1.c b/gcc/testsuite/gcc.dg/inline1.c new file mode 100644 index 00000000000..f7a7eb4b956 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline1.c @@ -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 index 00000000000..ede41049274 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline2.c @@ -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 index 00000000000..bc755e32ed2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline3.c @@ -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 index 00000000000..a5c7dda0a02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline4.c @@ -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 index 00000000000..86a2776251b --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline5.c @@ -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" } */ -- 2.30.2