Commit 6663ee3b by Eric Christopher Committed by Eric Christopher

re PR c/22052 (redefinition of inline function succeeds)

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
parent 38c955ff
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> 2005-06-28 Diego Novillo <dnovillo@redhat.com>
* tree-optimize.c (init_tree_optimization_passes): Fix typo. * tree-optimize.c (init_tree_optimization_passes): Fix typo.
......
...@@ -1154,6 +1154,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1154,6 +1154,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
bool warned = false; bool warned = false;
bool retval = true; 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 /* If we have error_mark_node for either decl or type, just discard
the previous decl - we're in an error cascade already. */ the previous decl - we're in an error cascade already. */
if (olddecl == error_mark_node || newdecl == error_mark_node) if (olddecl == error_mark_node || newdecl == error_mark_node)
...@@ -1282,6 +1285,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1282,6 +1285,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
Multiple definitions are not allowed (6.9p3,5) but GCC permits Multiple definitions are not allowed (6.9p3,5) but GCC permits
two definitions if one is 'extern inline' and one is not. The non- two definitions if one is 'extern inline' and one is not. The non-
extern-inline definition supersedes the extern-inline definition. */ extern-inline definition supersedes the extern-inline definition. */
else if (TREE_CODE (newdecl) == FUNCTION_DECL) else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
/* If you declare a built-in function name as static, or /* If you declare a built-in function name as static, or
...@@ -1304,45 +1308,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1304,45 +1308,25 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
{ {
if (DECL_INITIAL (olddecl)) if (DECL_INITIAL (olddecl))
{ {
/* If both decls have extern inline and are in the same TU, /* If both decls are in the same TU and the new declaration
reject the new decl. */ isn't overridding an extern inline reject the new decl.
if (DECL_DECLARED_INLINE_P (olddecl) When we handle c99 style inline rules we'll want to reject
&& DECL_EXTERNAL (olddecl) the following:
&& DECL_DECLARED_INLINE_P (newdecl)
&& DECL_EXTERNAL (newdecl) 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)) && same_translation_unit_p (newdecl, olddecl))
{ {
error ("%Jredefinition of %qD", newdecl, newdecl); error ("%Jredefinition of %qD", newdecl, newdecl);
locate_old_decl (olddecl, error); locate_old_decl (olddecl, error);
return false; 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, /* If we have a prototype after an old-style function definition,
the argument types must be checked specially. */ the argument types must be checked specially. */
...@@ -1371,8 +1355,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1371,8 +1355,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
occur only in Objective C; see also above. (FIXME: Make occur only in Objective C; see also above. (FIXME: Make
Objective C use normal builtins.) */ Objective C use normal builtins.) */
if (!DECL_IS_BUILTIN (olddecl) if (!DECL_IS_BUILTIN (olddecl)
&& !(DECL_EXTERNAL (olddecl) && !DECL_EXTERN_INLINE (olddecl))
&& DECL_DECLARED_INLINE_P (olddecl)))
{ {
error ("%Jstatic declaration of %qD follows " error ("%Jstatic declaration of %qD follows "
"non-static declaration", newdecl, newdecl); "non-static declaration", newdecl, newdecl);
...@@ -1585,6 +1568,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1585,6 +1568,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
if (warned || pedwarned) if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning0); locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
#undef DECL_EXTERN_INLINE
return retval; return retval;
} }
......
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> 2005-06-28 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/22142 PR libfortran/22142
......
/* { 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" } */
/* { 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; }
/* { 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" } */
/* { 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" } */
/* { 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" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment