[RFC,v1] c: Do not warn about external declaration following inline definition

Message ID 20231028191402.217288-1-pobrn@protonmail.com
State Accepted
Headers
Series [RFC,v1] c: Do not warn about external declaration following inline definition |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Barnabás Pőcze Oct. 28, 2023, 7:14 p.m. UTC
  An external declaration following an inline definition is not redundant
because it forces the compiler to emit an external definition for the function.
That is,

  inline void f(void) { }
  [extern] void f(void);

should not trigger the

  redundant redeclaration of ...

warning.

gcc/c/ChangeLog:

	* c-decl.cc (diagnose_mismatched_decls): Add new
	case for Wredundant-decls suppression.
---
 gcc/c/c-decl.cc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
  

Comments

Joseph Myers Oct. 30, 2023, 6:01 p.m. UTC | #1
On Sat, 28 Oct 2023, Barnabás Pőcze wrote:

> An external declaration following an inline definition is not redundant
> because it forces the compiler to emit an external definition for the function.
> That is,
> 
>   inline void f(void) { }
>   [extern] void f(void);
> 
> should not trigger the
> 
>   redundant redeclaration of ...
> 
> warning.

This should add a testcase to the testsuite (that fails before and passes 
after the front-end change is made).
  
Barnabás Pőcze Oct. 30, 2023, 7:55 p.m. UTC | #2
Hi


2023. október 30., hétfő 19:01 keltezéssel, Joseph Myers írta:

> On Sat, 28 Oct 2023, Barnabás Pőcze wrote:
> 
> > An external declaration following an inline definition is not redundant
> > because it forces the compiler to emit an external definition for the function.
> > That is,
> > 
> > inline void f(void) { }
> > [extern] void f(void);
> > 
> > should not trigger the
> > 
> > redundant redeclaration of ...
> > 
> > warning.
> 
> 
> This should add a testcase to the testsuite (that fails before and passes
> after the front-end change is made).

I did not want to commit more effort until I have some feedback.
I will most certainly add a test case if it turns out that the change
seems reasonable and has a chance of being accepted.


Regards,
Barnabás Pőcze
  
Joseph Myers Oct. 30, 2023, 8:39 p.m. UTC | #3
On Mon, 30 Oct 2023, Barnabás Pőcze wrote:

> Hi
> 
> 
> 2023. október 30., hétfő 19:01 keltezéssel, Joseph Myers írta:
> 
> > On Sat, 28 Oct 2023, Barnabás Pőcze wrote:
> > 
> > > An external declaration following an inline definition is not redundant
> > > because it forces the compiler to emit an external definition for the function.
> > > That is,
> > > 
> > > inline void f(void) { }
> > > [extern] void f(void);
> > > 
> > > should not trigger the
> > > 
> > > redundant redeclaration of ...
> > > 
> > > warning.
> > 
> > 
> > This should add a testcase to the testsuite (that fails before and passes
> > after the front-end change is made).
> 
> I did not want to commit more effort until I have some feedback.
> I will most certainly add a test case if it turns out that the change
> seems reasonable and has a chance of being accepted.

I agree that such a declaration is not redundant, and indeed serves a 
useful purpose, and so it's appropriate to avoid the warning in that case.  
Maybe also edit the documentation in invoke.texi to mention this case as 
not being diagnosed because not redundant.

Hopefully cases such as

inline void f(void) { }
void f(void);
void f(void);

do warn for the final declaration, because that one *is* redundant.  
Similarly, the changes should not affect warnings in the -fgnu89-inline 
case, because then a subsequent extern declaration has no effect on a 
prior inline definition.  Tests should include all these variations.
  

Patch

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 7a145bed281..e86f7950858 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -2592,7 +2592,12 @@  diagnose_mismatched_decls (tree newdecl, tree olddecl,
 	   && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
       /* Don't warn about a variable definition following a declaration.  */
       && !(VAR_P (newdecl)
-	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl)))
+	   && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
+      /* Don't warn about external declaration following inline definition.  */
+      && !(TREE_CODE (newdecl) == FUNCTION_DECL
+	   && !DECL_INITIAL (newdecl) && !DECL_DECLARED_INLINE_P (newdecl)
+	   && DECL_EXTERNAL (newdecl) && DECL_INITIAL (olddecl)
+	   && DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl)))
     {
       warned = warning (OPT_Wredundant_decls, "redundant redeclaration of %q+D",
 			newdecl);