]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix setting of DECL_CONTEXT in pushdecl (PR c/93072).
authorJoseph Myers <joseph@codesourcery.com>
Wed, 15 Jan 2020 20:52:45 +0000 (20:52 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 15 Jan 2020 20:53:15 +0000 (20:53 +0000)
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.

PR c/93072
gcc/c:
* c-decl.c (pushdecl): Use TREE_PUBLIC, not DECL_EXTERNAL, to
determine whether to set DECL_CONTEXT.

gcc/testsuite:
* gcc.dg/inline-42.c, gcc.dg/inline-43.c: New tests.

(cherry picked from commit e2346a33b05871fc065815d4cfd531dfa0195507)

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/inline-42.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/inline-43.c [new file with mode: 0644]

index 3b9e284a4279eb7f7bdb7b66bddf42b86ce6cfd2..64f0275a58c390293da78b03218ca74bc80b09d1 100644 (file)
@@ -1,3 +1,12 @@
+2020-01-15  Joseph Myers  <joseph@codesourcery.com>
+
+       Backport from mainline:
+       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.
+
 2020-01-13  Joseph Myers  <joseph@codesourcery.com>
 
        Backport from mainline:
index c632e4afd24fa7fc0c47060f8a3485c18b8ab3e8..f77fb1739ca7e0313b212970e19720f026bc91ce 100644 (file)
@@ -3044,7 +3044,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.  */
index 12d7839b858f7f1c7bf7477bd4a6426c074f4dbc..4acbb6c88bced0a3ad41b1457ffc772482bbf65b 100644 (file)
@@ -1,3 +1,11 @@
+2020-01-15  Joseph Myers  <joseph@codesourcery.com>
+
+       Backport from mainline:
+       2020-01-15  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/93072
+       * gcc.dg/inline-42.c, gcc.dg/inline-43.c: New tests.
+
 2020-01-14  Martin Jambor  <mjambor@suse.cz>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/inline-42.c b/gcc/testsuite/gcc.dg/inline-42.c
new file mode 100644 (file)
index 0000000..f5ccea8
--- /dev/null
@@ -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 (file)
index 0000000..87b2445
--- /dev/null
@@ -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)
+{
+}