At present, we print the "inline function ... declared but never
defined" warning twice.  The reason for that is that this warning
is being printed in pop_scope, which is called when popping file
scope (c_common_parse_file->pop_file_scope), and when popping
external scope (c_write_global_declarations).  I think we should
not print this warning when popping the external scope.
We don't have to worry about nested functions here.

Writing a proper testcase is a little bit tricky, but I hope what
I did would work fine.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2014-10-23  Marek Polacek  <pola...@redhat.com>

        PR c/63626
        * c-decl.c (pop_scope): Don't print warning in external_scope.

        * gcc.dg/pr63626.c: New test.

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index b18da48..7d1840e 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -1182,7 +1182,8 @@ pop_scope (void)
                 with an inline function specifier ... shall also be defined
                 in the same translation unit."  */
              if (!flag_gnu89_inline
-                 && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p)))
+                 && !lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (p))
+                 && scope != external_scope)
                pedwarn (input_location, 0,
                         "inline function %q+D declared but never defined", p);
              DECL_EXTERNAL (p) = 1;
diff --git gcc/testsuite/gcc.dg/pr63626.c gcc/testsuite/gcc.dg/pr63626.c
index e69de29..1f03818 100644
--- gcc/testsuite/gcc.dg/pr63626.c
+++ gcc/testsuite/gcc.dg/pr63626.c
@@ -0,0 +1,8 @@
+/* PR c/63626 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Test that we don't output the warning twice.  */
+
+inline int foo (void); /* { dg-bogus "inline function.*inline function" } */
+/* { dg-warning "inline function .foo. declared but never defined" "" { target 
*-*-* } 7 } */

        Marek

Reply via email to