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