diff mbox

Don't warn for missing prototypes on inline fns (PR c/54113)

Message ID 20131204174709.GH32420@redhat.com
State New
Headers show

Commit Message

Marek Polacek Dec. 4, 2013, 5:47 p.m. UTC
In C99, one way how to deal with inline functions is to put definition
of the function into header:
inline void foo (void) { /* ... */ }
and put the declaration into exactly one .c file, with extern keyword
(it can also have inline keyword):
extern void foo (void);
But in this case, we shouldn't issue the "missing prototype" warning.
So the following should suppress that warning in C99 mode, when
-fgnu89-inline is not in effect.  (But the function could still have
the gnu_inline attribute, so it might be better to disable that
warning for all inline functions?)

Regtested/bootstrapped on x86_64-unknown-linux-gnu.  Ok for trunk?

2013-12-04  Marek Polacek  <polacek@redhat.com>

	PR c/54113
c/
	* c-decl.c (start_function): Don't warn for missing prototype for
	inline functions in C99+.
testsuite/
	* gcc.dg/pr54113.c: New test.


	Marek

Comments

Marek Polacek Dec. 4, 2013, 5:51 p.m. UTC | #1
On Wed, Dec 04, 2013 at 06:47:09PM +0100, Marek Polacek wrote:
> In C99, one way how to deal with inline functions is to put definition
> of the function into header:
> inline void foo (void) { /* ... */ }
> and put the declaration into exactly one .c file, with extern keyword
> (it can also have inline keyword):
> extern void foo (void);
> But in this case, we shouldn't issue the "missing prototype" warning.
> So the following should suppress that warning in C99 mode, when
> -fgnu89-inline is not in effect.  (But the function could still have
> the gnu_inline attribute, so it might be better to disable that
> warning for all inline functions?)
> 
> Regtested/bootstrapped on x86_64-unknown-linux-gnu.  Ok for trunk?
> 
> 2013-12-04  Marek Polacek  <polacek@redhat.com>
> 
> 	PR c/54113
> c/
> 	* c-decl.c (start_function): Don't warn for missing prototype for
> 	inline functions in C99+.
> testsuite/
> 	* gcc.dg/pr54113.c: New test.
> 
> --- gcc/c/c-decl.c.mp3	2013-12-04 17:11:43.063878926 +0100
> +++ gcc/c/c-decl.c	2013-12-04 18:32:17.567008028 +0100
> @@ -7974,7 +7974,10 @@ start_function (struct c_declspecs *decl
>  	   && old_decl != error_mark_node
>  	   && TREE_PUBLIC (decl1)
>  	   && !MAIN_NAME_P (DECL_NAME (decl1))
> -	   && C_DECL_ISNT_PROTOTYPE (old_decl))
> +	   && C_DECL_ISNT_PROTOTYPE (old_decl)
> +	   && !(DECL_DECLARED_INLINE_P (decl1)
> +		&& flag_isoc99
> +		&& !flag_gnu89_inline))
>      warning_at (loc, OPT_Wmissing_prototypes,
>  		"no previous prototype for %qD", decl1);
>    /* Optionally warn of any def with no previous prototype
> --- gcc/testsuite/gcc.dg/pr54113.c.mp3	2013-12-04 17:52:45.671288940 +0100
> +++ gcc/testsuite/gcc.dg/pr54113.c	2013-12-04 17:36:43.000000000 +0100
> @@ -0,0 +1,5 @@
> +/* { dg-do compile } */
> +/* { dg-options "-std=c99" } */

-Wmissing-prototypes is missing here, in my local copy of the patch
this is fixed.

	Marek
Jakub Jelinek Dec. 4, 2013, 5:55 p.m. UTC | #2
On Wed, Dec 04, 2013 at 06:47:09PM +0100, Marek Polacek wrote:
> In C99, one way how to deal with inline functions is to put definition
> of the function into header:
> inline void foo (void) { /* ... */ }
> and put the declaration into exactly one .c file, with extern keyword
> (it can also have inline keyword):
> extern void foo (void);
> But in this case, we shouldn't issue the "missing prototype" warning.
> So the following should suppress that warning in C99 mode, when
> -fgnu89-inline is not in effect.  (But the function could still have
> the gnu_inline attribute, so it might be better to disable that
> warning for all inline functions?)

A function definition can't have attributes after the (), and
start_function is called with the attributes argument, so you can just
look through those for gnu_inline attribute.

	Jakub
Joseph Myers Dec. 4, 2013, 6:22 p.m. UTC | #3
On Wed, 4 Dec 2013, Marek Polacek wrote:

> In C99, one way how to deal with inline functions is to put definition
> of the function into header:
> inline void foo (void) { /* ... */ }
> and put the declaration into exactly one .c file, with extern keyword
> (it can also have inline keyword):
> extern void foo (void);
> But in this case, we shouldn't issue the "missing prototype" warning.
> So the following should suppress that warning in C99 mode, when
> -fgnu89-inline is not in effect.  (But the function could still have
> the gnu_inline attribute, so it might be better to disable that
> warning for all inline functions?)
> 
> Regtested/bootstrapped on x86_64-unknown-linux-gnu.  Ok for trunk?

OK.
Marek Polacek Dec. 4, 2013, 6:27 p.m. UTC | #4
On Wed, Dec 04, 2013 at 06:22:28PM +0000, Joseph S. Myers wrote:
> On Wed, 4 Dec 2013, Marek Polacek wrote:
> 
> > In C99, one way how to deal with inline functions is to put definition
> > of the function into header:
> > inline void foo (void) { /* ... */ }
> > and put the declaration into exactly one .c file, with extern keyword
> > (it can also have inline keyword):
> > extern void foo (void);
> > But in this case, we shouldn't issue the "missing prototype" warning.
> > So the following should suppress that warning in C99 mode, when
> > -fgnu89-inline is not in effect.  (But the function could still have
> > the gnu_inline attribute, so it might be better to disable that
> > warning for all inline functions?)
> > 
> > Regtested/bootstrapped on x86_64-unknown-linux-gnu.  Ok for trunk?
> 
> OK.

Should I commit the version with or without the lookup for gnu_inline
attribute?  Thanks,

	Marek
diff mbox

Patch

--- gcc/c/c-decl.c.mp3	2013-12-04 17:11:43.063878926 +0100
+++ gcc/c/c-decl.c	2013-12-04 18:32:17.567008028 +0100
@@ -7974,7 +7974,10 @@  start_function (struct c_declspecs *decl
 	   && old_decl != error_mark_node
 	   && TREE_PUBLIC (decl1)
 	   && !MAIN_NAME_P (DECL_NAME (decl1))
-	   && C_DECL_ISNT_PROTOTYPE (old_decl))
+	   && C_DECL_ISNT_PROTOTYPE (old_decl)
+	   && !(DECL_DECLARED_INLINE_P (decl1)
+		&& flag_isoc99
+		&& !flag_gnu89_inline))
     warning_at (loc, OPT_Wmissing_prototypes,
 		"no previous prototype for %qD", decl1);
   /* Optionally warn of any def with no previous prototype
--- gcc/testsuite/gcc.dg/pr54113.c.mp3	2013-12-04 17:52:45.671288940 +0100
+++ gcc/testsuite/gcc.dg/pr54113.c	2013-12-04 17:36:43.000000000 +0100
@@ -0,0 +1,5 @@ 
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+inline int foo (void) { return 42; } /* { dg-bogus "no previous prototype" } */
+extern int foo(void);