This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix setting of DECL_CONTEXT in pushdecl (PR c/93072)
- From: Joseph Myers <joseph at codesourcery dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 15 Jan 2020 02:55:36 +0000
- Subject: Fix setting of DECL_CONTEXT in pushdecl (PR c/93072)
- Ironport-sdr: Ny4jWDHeqpJom9B6QooxPYKI5koXrqUhEy5hpAGXoqFfn9c5VPrNJgwJHvZg5E2DBWNRLxuhz6 XGLUsEWzgppMqrj/2bnvghqqhTSN4xs936vbWpIRB1UtBCDPlweneGqLJyzg8LBhKU1Ie5qsQY s/iaMIdSuP4WBnnDkATVpDq+jB+4dXHUD7F3Tg6bUxCLwpC5WIfp3aDnyF+NMoPrKRQ2fHdYGx mapY5BoFcW9c2YDFZQB6tjU27Tl365kZjc3M0JQB1Y4lGgUI5+VKz9VGfEqvwgIpIgzWZVJwlt NGE=
- Ironport-sdr: +wAlOI0BYGudd2yDMvcdINCFwfkwo4x7/wP/A0hG95IlEhy+0S1qi4G6R8WKxHoVtXIMRsso2T jLwTBaucOOHUHxezoatYh4yR1lFHnaEE2nVroD2/FYYM8e10tPajwkeFJyisRraUVx0qUhYTvT foLYQNUra079KQ5+PduitAcNcmBcV06yHvif7TpIqSQfxwQdz9uQwdcVWx9gWRJTKL7M4bH+64 20prUBv9eKuxbkaQSP7/ndDKcaTN+8mYslMVYYSac7eYiOD/mB1CQLyfJYRo3V+zK+7hbJbD2a jVY=
Bug 93072 is a case where the C front end (a) wrongly interprets an
inline declaration at block scope as indicating that DECL_CONTEXT
should be set for an inline function and (b) this results in an ICE.
This is a regression resulting from a previous fix of mine for other
bugs involving such declarations being wrongly interpreted elsewhere
as nested function declarations. The fix is similar to the previous
fix: use TREE_PUBLIC instead of DECL_EXTERNAL in another place as the
relevant test to determine whether to set DECL_CONTEXT. (When a
variable reaches the code in question in pushdecl, the two are
equivalent.)
Bootstrapped with no regressions for x86_64-pc-linux-gnu. Applied to
mainline. Will backport to GCC 9 and 8 branches.
gcc/c:
2020-01-15 Joseph Myers <joseph@codesourcery.com>
PR c/93072
* c-decl.c (pushdecl): Use TREE_PUBLIC, not DECL_EXTERNAL, to
determine whether to set DECL_CONTEXT.
gcc/testsuite:
2020-01-15 Joseph Myers <joseph@codesourcery.com>
PR c/93072
* gcc.dg/inline-42.c, gcc.dg/inline-43.c: New tests.
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index fa834d91730..8281af7307a 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -3048,7 +3048,7 @@ pushdecl (tree x)
unless they have initializers (which generate code). */
if (current_function_decl
&& (!VAR_OR_FUNCTION_DECL_P (x)
- || DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
+ || DECL_INITIAL (x) || !TREE_PUBLIC (x)))
DECL_CONTEXT (x) = current_function_decl;
/* Anonymous decls are just inserted in the scope. */
diff --git a/gcc/testsuite/gcc.dg/inline-42.c b/gcc/testsuite/gcc.dg/inline-42.c
new file mode 100644
index 00000000000..f5ccea8f3cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-42.c
@@ -0,0 +1,50 @@
+/* Test inline functions declared in inner scopes. Bug 93072. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+inline_1 (void)
+{
+}
+
+void
+inline_2 (void)
+{
+}
+
+static void
+inline_static_1 (void)
+{
+}
+
+static void
+inline_static_2 (void)
+{
+}
+
+static void
+test (void)
+{
+ inline void inline_1 (void);
+ if (inline_1 == 0) ;
+ extern inline void inline_2 (void);
+ if (inline_2 == 0) ;
+ inline void inline_3 (void);
+ if (inline_3 == 0) ;
+ extern inline void inline_4 (void);
+ if (inline_4 == 0) ;
+ inline void inline_static_1 (void);
+ if (inline_static_1 == 0) ;
+ extern inline void inline_static_2 (void);
+ if (inline_static_2 == 0) ;
+}
+
+void
+inline_3 (void)
+{
+}
+
+void
+inline_4 (void)
+{
+}
diff --git a/gcc/testsuite/gcc.dg/inline-43.c b/gcc/testsuite/gcc.dg/inline-43.c
new file mode 100644
index 00000000000..87b24450384
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-43.c
@@ -0,0 +1,50 @@
+/* Test inline functions declared in inner scopes. Bug 93072. */
+/* { dg-do compile } */
+/* { dg-options "-fgnu89-inline" } */
+
+void
+inline_1 (void)
+{
+}
+
+void
+inline_2 (void)
+{
+}
+
+static void
+inline_static_1 (void)
+{
+}
+
+static void
+inline_static_2 (void)
+{
+}
+
+static void
+test (void)
+{
+ inline void inline_1 (void);
+ if (inline_1 == 0) ;
+ extern inline void inline_2 (void);
+ if (inline_2 == 0) ;
+ inline void inline_3 (void);
+ if (inline_3 == 0) ;
+ extern inline void inline_4 (void);
+ if (inline_4 == 0) ;
+ inline void inline_static_1 (void);
+ if (inline_static_1 == 0) ;
+ extern inline void inline_static_2 (void);
+ if (inline_static_2 == 0) ;
+}
+
+void
+inline_3 (void)
+{
+}
+
+void
+inline_4 (void)
+{
+}
--
Joseph S. Myers
joseph@codesourcery.com