From 6cf598659e764d8955a1a90c32d2519ab689cea0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 13 Jun 2008 11:38:31 +0200 Subject: [PATCH] re PR c/36507 (ISO C99 inline semantics doesn't play together with nested functions) PR c/36507 * c-decl.c (merge_decls): Don't clear DECL_EXTERNAL for nested inline functions. (start_decl, start_function): Don't invert DECL_EXTERNAL for nested inline functions. * gcc.dg/inline-28.c: New test. * gcc.dg/inline-29.c: New test. * gcc.dg/inline-30.c: New test. From-SVN: r136745 --- gcc/ChangeLog | 8 ++++++++ gcc/c-decl.c | 10 +++++++--- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/inline-28.c | 28 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/inline-29.c | 28 ++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/inline-30.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/inline-28.c create mode 100644 gcc/testsuite/gcc.dg/inline-29.c create mode 100644 gcc/testsuite/gcc.dg/inline-30.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1f172891494..37ff36aaa9e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-06-13 Jakub Jelinek + + PR c/36507 + * c-decl.c (merge_decls): Don't clear DECL_EXTERNAL for + nested inline functions. + (start_decl, start_function): Don't invert DECL_EXTERNAL + for nested inline functions. + 2008-06-13 Richard Sandiford * config/mips/mips.md: Remove TARGET_DEBUG_D_MODE conditions from diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 9abb4dfc65f..89fdf3d1b45 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1763,7 +1763,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) || !DECL_DECLARED_INLINE_P (olddecl) || !DECL_EXTERNAL (olddecl)) && DECL_EXTERNAL (newdecl) - && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl))) + && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (newdecl)) + && (DECL_CONTEXT (newdecl) == NULL_TREE + || TREE_CODE (DECL_CONTEXT (newdecl)) != FUNCTION_DECL)) DECL_EXTERNAL (newdecl) = 0; if (DECL_EXTERNAL (newdecl)) @@ -3264,7 +3266,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, if (declspecs->inline_p && !flag_gnu89_inline && TREE_CODE (decl) == FUNCTION_DECL - && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl))) + && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl)) + || current_function_decl)) { if (declspecs->storage_class == csc_auto && current_scope != file_scope) ; @@ -6094,7 +6097,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, if (declspecs->inline_p && !flag_gnu89_inline && TREE_CODE (decl1) == FUNCTION_DECL - && lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1))) + && (lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (decl1)) + || current_function_decl)) { if (declspecs->storage_class != csc_static) DECL_EXTERNAL (decl1) = !DECL_EXTERNAL (decl1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2026e22b159..c9e1e422496 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-06-13 Jakub Jelinek + + PR c/36507 + * gcc.dg/inline-28.c: New test. + * gcc.dg/inline-29.c: New test. + * gcc.dg/inline-30.c: New test. + 2008-06-12 Tobias Burnus PR fortran/36462 diff --git a/gcc/testsuite/gcc.dg/inline-28.c b/gcc/testsuite/gcc.dg/inline-28.c new file mode 100644 index 00000000000..20916aef992 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline-28.c @@ -0,0 +1,28 @@ +/* PR c/36507 */ +/* { dg-do run } */ +/* { dg-options "-O0 -std=gnu89" } */ + +int +main (void) +{ + int i = 2; + auto inline int f1 (void) + { + return i; + } + inline int f2 (void) + { + return i; + } + auto inline int f3 (void); + auto inline int f3 (void) + { + return i; + } + auto inline int f4 (void); + inline int f4 (void) + { + return i; + } + return f1 () + f2 () + f3 () + f4 () - 8; +} diff --git a/gcc/testsuite/gcc.dg/inline-29.c b/gcc/testsuite/gcc.dg/inline-29.c new file mode 100644 index 00000000000..77672f34295 --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline-29.c @@ -0,0 +1,28 @@ +/* PR c/36507 */ +/* { dg-do run } */ +/* { dg-options "-O0 -std=gnu99" } */ + +int +main (void) +{ + int i = 2; + auto inline int f1 (void) + { + return i; + } + inline int f2 (void) + { + return i; + } + auto inline int f3 (void); + auto inline int f3 (void) + { + return i; + } + auto inline int f4 (void); + inline int f4 (void) + { + return i; + } + return f1 () + f2 () + f3 () + f4 () - 8; +} diff --git a/gcc/testsuite/gcc.dg/inline-30.c b/gcc/testsuite/gcc.dg/inline-30.c new file mode 100644 index 00000000000..bb9b2b4776b --- /dev/null +++ b/gcc/testsuite/gcc.dg/inline-30.c @@ -0,0 +1,28 @@ +/* PR c/36507 */ +/* { dg-do run } */ +/* { dg-options "-O0 -std=gnu99 -fgnu89-inline" } */ + +int +main (void) +{ + int i = 2; + auto inline int f1 (void) + { + return i; + } + inline int f2 (void) + { + return i; + } + auto inline int f3 (void); + auto inline int f3 (void) + { + return i; + } + auto inline int f4 (void); + inline int f4 (void) + { + return i; + } + return f1 () + f2 () + f3 () + f4 () - 8; +} -- 2.30.2