From: Joseph Myers Date: Wed, 15 Jan 2020 20:52:45 +0000 (+0000) Subject: Fix setting of DECL_CONTEXT in pushdecl (PR c/93072). X-Git-Tag: releases/gcc-9.3.0~225 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cc6b679a0d0e50c0e1671fefa815dc753554184;p=thirdparty%2Fgcc.git Fix setting of DECL_CONTEXT in pushdecl (PR c/93072). 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) --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3b9e284a4279..64f0275a58c3 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2020-01-15 Joseph Myers + + Backport from mainline: + 2020-01-15 Joseph Myers + + 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 Backport from mainline: diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index c632e4afd24f..f77fb1739ca7 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12d7839b858f..4acbb6c88bce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-01-15 Joseph Myers + + Backport from mainline: + 2020-01-15 Joseph Myers + + PR c/93072 + * gcc.dg/inline-42.c, gcc.dg/inline-43.c: New tests. + 2020-01-14 Martin Jambor 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 index 000000000000..f5ccea8f3cf1 --- /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 000000000000..87b24450384c --- /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) +{ +}