2009-01-30 Jakub Jelinek PR target/39013 * c-decl.c (pop_scope): Set DECL_EXTERNAL for functions declared inline but never defined. * gcc.target/i386/pr39013-1.c: New test. * gcc.target/i386/pr39013-2.c: New test. --- gcc/c-decl.c.jj 2009-01-26 15:24:44.000000000 +0100 +++ gcc/c-decl.c 2009-01-30 15:59:22.000000000 +0100 @@ -779,14 +779,18 @@ error ("nested function %q+D declared but never defined", p); undef_nested_function = true; } - /* C99 6.7.4p6: "a function with external linkage... declared - with an inline function specifier ... shall also be defined in the - same translation unit." */ - else if (DECL_DECLARED_INLINE_P (p) - && TREE_PUBLIC (p) - && !DECL_INITIAL (p) - && !flag_gnu89_inline) - pedwarn ("inline function %q+D declared but never defined", p); + else if (DECL_DECLARED_INLINE_P (p) + && TREE_PUBLIC (p) + && !DECL_INITIAL (p)) + { + /* C99 6.7.4p6: "a function with external linkage... declared + with an inline function specifier ... shall also be defined + in the same translation unit." */ + if (!flag_gnu89_inline) + pedwarn ("inline function %q+D declared but never defined", p); + if (!DECL_EXTERNAL (p)) + DECL_EXTERNAL (p) = 1; + } goto common_symbol; --- gcc/testsuite/gcc.target/i386/pr39013-1.c.jj 2009-01-30 16:15:06.000000000 +0100 +++ gcc/testsuite/gcc.target/i386/pr39013-1.c 2009-01-30 16:17:05.000000000 +0100 @@ -0,0 +1,15 @@ +/* PR target/39013 */ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpie -std=gnu89" } */ + +inline int foo (void); +extern inline int bar (void); + +int +main (void) +{ + return foo () + bar (); +} + +/* { dg-final { scan-assembler "foo@PLT" } } */ +/* { dg-final { scan-assembler "bar@PLT" } } */ --- gcc/testsuite/gcc.target/i386/pr39013-2.c.jj 2009-01-30 16:15:06.000000000 +0100 +++ gcc/testsuite/gcc.target/i386/pr39013-2.c 2009-01-30 16:17:15.000000000 +0100 @@ -0,0 +1,15 @@ +/* PR target/39013 */ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpie -std=gnu99" } */ + +inline int foo (void); /* { dg-warning "declared but never defined" } */ +extern inline int bar (void); /* { dg-warning "declared but never defined" } */ + +int +main (void) +{ + return foo () + bar (); +} + +/* { dg-final { scan-assembler "foo@PLT" } } */ +/* { dg-final { scan-assembler "bar@PLT" } } */