c: add -Wmissing-variable-declarations [PR65213]

Resolves:
PR c/65213 - Extend -Wmissing-declarations to variables [i.e. add
-Wmissing-variable-declarations]

gcc/c-family/ChangeLog:

	PR c/65213
	* c.opt (-Wmissing-variable-declarations): New option.

gcc/c/ChangeLog:

	PR c/65213
	* c-decl.cc (start_decl): Handle
	-Wmissing-variable-declarations.

gcc/ChangeLog:

	PR c/65213
	* doc/invoke.texi (-Wmissing-variable-declarations): Document
	new option.

gcc/testsuite/ChangeLog:

	PR c/65213
	* gcc.dg/Wmissing-variable-declarations.c: New test.

Signed-off-by: Hamza Mahfooz <someguy@effective-light.com>
This commit is contained in:
Hamza Mahfooz 2023-07-31 19:03:47 +00:00 committed by Joseph Myers
parent ac0e0966eb
commit ffc7482246
4 changed files with 55 additions and 3 deletions

View file

@ -1048,6 +1048,10 @@ Wmissing-prototypes
C ObjC Var(warn_missing_prototypes) Warning
Warn about global functions without prototypes.
Wmissing-variable-declarations
C ObjC Var(warn_missing_variable_declarations) Warning
Warn about global variables without previous declarations.
Wmudflap
C ObjC C++ ObjC++ WarnRemoved

View file

@ -5340,6 +5340,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
location_t *lastloc /* = NULL */)
{
tree decl;
tree old_decl;
tree tem;
tree expr = NULL_TREE;
enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
@ -5360,7 +5361,9 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
if (!decl || decl == error_mark_node)
return NULL_TREE;
if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE)
old_decl = lookup_last_decl (decl);
if (tree lastdecl = lastloc ? old_decl : NULL_TREE)
if (lastdecl != error_mark_node)
*lastloc = DECL_SOURCE_LOCATION (lastdecl);
@ -5372,6 +5375,11 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
&& TREE_PUBLIC (decl))
warning (OPT_Wmain, "%q+D is usually a function", decl);
if (warn_missing_variable_declarations && VAR_P (decl)
&& !DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) && old_decl == NULL_TREE)
warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wmissing_variable_declarations,
"no previous declaration for %qD", decl);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
If not, set INITIALIZED to zero, which will indirectly

View file

@ -498,8 +498,8 @@ Objective-C and Objective-C++ Dialects}.
@item C and Objective-C-only Warning Options
@gccoptlist{-Wbad-function-cast -Wmissing-declarations
-Wmissing-parameter-type -Wmissing-prototypes -Wnested-externs
-Wold-style-declaration -Wold-style-definition
-Wmissing-parameter-type -Wmissing-prototypes -Wmissing-variable-declarations
-Wnested-externs -Wold-style-declaration -Wold-style-definition
-Wstrict-prototypes -Wtraditional -Wtraditional-conversion
-Wdeclaration-after-statement -Wpointer-sign}
@ -9611,6 +9611,13 @@ provide prototypes and a non-matching declaration declares an
overload rather than conflict with an earlier declaration.
Use @option{-Wmissing-declarations} to detect missing declarations in C++.
@opindex Wmissing-variable-declarations
@opindex Wno-missing-variable-declarations
@item -Wmissing-variable-declarations @r{(C and Objective-C only)}
Warn if a global variable is defined without a previous declaration.
Use this option to detect global variables that do not have a matching
extern declaration in a header file.
@opindex Wmissing-declarations
@opindex Wno-missing-declarations
@item -Wmissing-declarations

View file

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-Wmissing-variable-declarations" } */
int b0; /* { dg-warning "no previous declaration for 'b0'" } */
int b1 = 1; /* { dg-warning "no previous declaration for 'b1'" } */
int b2; /* { dg-warning "no previous declaration for 'b2'" } */
int b2 = 2;
struct {
int g0;
} b3; /* { dg-warning "no previous declaration for 'b3'" } */
int b4; /* { dg-warning "no previous declaration for 'b4'" } */
int b4 = 3;
extern int b4;
static int g1;
void g2(void);
extern int g3;
int g3;
int g3 = 4;
struct g4 {
int g5;
};
void g6(void) {
int g7;
}