aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2019-01-07 22:39:43 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2019-01-07 22:39:43 +0000
commit65c5b1eb85f8f0f3078f614d549f107ee9a001af (patch)
treecbf34fb65f0b99d3b3ec4e876e9682f6e50554da
parentc3336d9b13da022973c9097edcdb5ff9ad57fac0 (diff)
downloadgcc-65c5b1eb85f8f0f3078f614d549f107ee9a001af.zip
gcc-65c5b1eb85f8f0f3078f614d549f107ee9a001af.tar.gz
gcc-65c5b1eb85f8f0f3078f614d549f107ee9a001af.tar.bz2
Fix diagnostics for never-defined inline and nested functions (PR c/88720, PR c/88726).
Bugs 88720 and 88726 report issues where a function is declared inline in an inner scope, resulting in spurious diagnostics about it being declared but never defined when that scope is left (possibly in some cases also wrongly referring to the function as a nested function). These are regressions that were introduced with the support for C99 inline semantics in 4.3 (they don't appear with 4.2; it's possible some aspects of the bugs might have been introduced later than 4.3). For the case of functions being wrongly referred to as nested, DECL_EXTERNAL was not the right condition for a function being non-nested; TREE_PUBLIC is appropriate for the case of non-nested functions with external linkage, while !b->nested means this is the outermost scope in which the function was declared and so avoids catching the case of a file-scope static being redeclared inline inside a function. For the non-nested, external-linkage case, the code attempts to avoid duplicate diagnostics by diagnosing only when scope != external_scope, but actually scope == external_scope is more appropriate, as it's only when the file and external scopes are popped that the code can actually tell whether a function ended up being defined, and all such functions will appear in the (GCC-internal) external scope. Bootstrapped with no regressions on x86_64-pc-linux-gnu. PR c/88720 PR c/88726 gcc/c: * c-decl.c (pop_scope): Use TREE_PUBLIC and b->nested to determine whether a function is nested, not DECL_EXTERNAL. Diagnose inline functions declared but never defined only for external scope, not for other scopes. gcc/testsuite: * gcc.dg/inline-40.c, gcc.dg/inline-41.c: New tests. From-SVN: r267665
-rw-r--r--gcc/c/ChangeLog9
-rw-r--r--gcc/c/c-decl.c5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/inline-40.c49
-rw-r--r--gcc/testsuite/gcc.dg/inline-41.c49
5 files changed, 116 insertions, 2 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index fbd94f5..5ee4b66 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,12 @@
+2019-01-07 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/88720
+ PR c/88726
+ * c-decl.c (pop_scope): Use TREE_PUBLIC and b->nested to determine
+ whether a function is nested, not DECL_EXTERNAL. Diagnose inline
+ functions declared but never defined only for external scope, not
+ for other scopes.
+
2019-01-07 Jakub Jelinek <jakub@redhat.com>
PR c++/85052
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index d7726fa..5c7232f 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1251,8 +1251,9 @@ pop_scope (void)
&& DECL_ABSTRACT_ORIGIN (p) != NULL_TREE
&& DECL_ABSTRACT_ORIGIN (p) != p)
TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
- if (!DECL_EXTERNAL (p)
+ if (!TREE_PUBLIC (p)
&& !DECL_INITIAL (p)
+ && !b->nested
&& scope != file_scope
&& scope != external_scope)
{
@@ -1268,7 +1269,7 @@ pop_scope (void)
in the same translation unit." */
if (!flag_gnu89_inline
&& !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
- && scope != external_scope)
+ && scope == external_scope)
pedwarn (input_location, 0,
"inline function %q+D declared but never defined", p);
DECL_EXTERNAL (p) = 1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 29b3b83..ebc96a3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-07 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/88720
+ PR c/88726
+ * gcc.dg/inline-40.c, gcc.dg/inline-41.c: New tests.
+
2019-01-07 Paolo Carlini <paolo.carlini@oracle.com>
* g++.dg/diagnostic/constexpr1.C: New.
diff --git a/gcc/testsuite/gcc.dg/inline-40.c b/gcc/testsuite/gcc.dg/inline-40.c
new file mode 100644
index 0000000..d0fdaee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-40.c
@@ -0,0 +1,49 @@
+/* Test inline functions declared in inner scopes. Bugs 88720 and 88726. */
+/* { 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 inline_static_3 (void);
+static void inline_static_4 (void);
+
+static void
+test (void)
+{
+ inline void inline_1 (void);
+ extern inline void inline_2 (void);
+ inline void inline_3 (void);
+ extern inline void inline_4 (void);
+ inline void inline_static_1 (void);
+ extern inline void inline_static_2 (void);
+ inline void inline_static_3 (void);
+ extern inline void inline_static_4 (void);
+}
+
+void
+inline_3 (void)
+{
+}
+
+void
+inline_4 (void)
+{
+}
diff --git a/gcc/testsuite/gcc.dg/inline-41.c b/gcc/testsuite/gcc.dg/inline-41.c
new file mode 100644
index 0000000..1511aee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/inline-41.c
@@ -0,0 +1,49 @@
+/* Test inline functions declared in inner scopes. Bugs 88720 and 88726. */
+/* { 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 inline_static_3 (void);
+static void inline_static_4 (void);
+
+static void
+test (void)
+{
+ inline void inline_1 (void);
+ extern inline void inline_2 (void);
+ inline void inline_3 (void);
+ extern inline void inline_4 (void);
+ inline void inline_static_1 (void);
+ extern inline void inline_static_2 (void);
+ inline void inline_static_3 (void);
+ extern inline void inline_static_4 (void);
+}
+
+void
+inline_3 (void)
+{
+}
+
+void
+inline_4 (void)
+{
+}