Commit d6e83a8d by Mikhail Maltsev Committed by Mikhail Maltsev

PR43651: add warning for duplicate qualifier

gcc/c/

	PR c/43651
	* c-decl.c (declspecs_add_qual): Warn when -Wduplicate-decl-specifier
	is enabled.
	* c-errors.c (pedwarn_c90): Return true if warned.
	* c-tree.h (pedwarn_c90): Change return type to bool.
	(enum c_declspec_word): Add new enumerator cdw_atomic.

gcc/

	PR c/43651
	* doc/invoke.texi (Wduplicate-decl-specifier): Document new option.

gcc/testsuite/

	PR c/43651
	* gcc.dg/Wduplicate-decl-specifier-c11.c: New test.
	* gcc.dg/Wduplicate-decl-specifier.c: Likewise.

gcc/c-family/

	PR c/43651
	* c.opt (Wduplicate-decl-specifier): New option.

From-SVN: r236142
parent 51e67ea3
2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
PR c/43651
* doc/invoke.texi (Wduplicate-decl-specifier): Document new option.
2016-05-11 Uros Bizjak <ubizjak@gmail.com> 2016-05-11 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (legitimize_pic_address): Use * config/i386/i386.c (legitimize_pic_address): Use
......
2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
PR c/43651
* c.opt (Wduplicate-decl-specifier): New option.
2016-05-11 Marek Polacek <polacek@redhat.com> 2016-05-11 Marek Polacek <polacek@redhat.com>
PR c++/71024 PR c++/71024
......
...@@ -1008,6 +1008,10 @@ Wsubobject-linkage ...@@ -1008,6 +1008,10 @@ Wsubobject-linkage
C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1) C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1)
Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage. Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage.
Wduplicate-decl-specifier
C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall)
Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier.
ansi ansi
C ObjC C++ ObjC++ C ObjC C++ ObjC++
A synonym for -std=c89 (for C) or -std=c++98 (for C++). A synonym for -std=c89 (for C) or -std=c++98 (for C++).
......
2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
PR c/43651
* c-decl.c (declspecs_add_qual): Warn when -Wduplicate-decl-specifier
is enabled.
* c-errors.c (pedwarn_c90): Return true if warned.
* c-tree.h (pedwarn_c90): Change return type to bool.
(enum c_declspec_word): Add new enumerator cdw_atomic.
2016-05-11 Marek Polacek <polacek@redhat.com> 2016-05-11 Marek Polacek <polacek@redhat.com>
PR c++/71024 PR c++/71024
......
...@@ -9515,32 +9515,48 @@ declspecs_add_qual (source_location loc, ...@@ -9515,32 +9515,48 @@ declspecs_add_qual (source_location loc,
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual)); && C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual); i = C_RID_CODE (qual);
location_t prev_loc = 0;
switch (i) switch (i)
{ {
case RID_CONST: case RID_CONST:
dupe = specs->const_p; dupe = specs->const_p;
specs->const_p = true; specs->const_p = true;
prev_loc = specs->locations[cdw_const];
specs->locations[cdw_const] = loc; specs->locations[cdw_const] = loc;
break; break;
case RID_VOLATILE: case RID_VOLATILE:
dupe = specs->volatile_p; dupe = specs->volatile_p;
specs->volatile_p = true; specs->volatile_p = true;
prev_loc = specs->locations[cdw_volatile];
specs->locations[cdw_volatile] = loc; specs->locations[cdw_volatile] = loc;
break; break;
case RID_RESTRICT: case RID_RESTRICT:
dupe = specs->restrict_p; dupe = specs->restrict_p;
specs->restrict_p = true; specs->restrict_p = true;
prev_loc = specs->locations[cdw_restrict];
specs->locations[cdw_restrict] = loc; specs->locations[cdw_restrict] = loc;
break; break;
case RID_ATOMIC: case RID_ATOMIC:
dupe = specs->atomic_p; dupe = specs->atomic_p;
specs->atomic_p = true; specs->atomic_p = true;
prev_loc = specs->locations[cdw_atomic];
specs->locations[cdw_atomic] = loc;
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
if (dupe) if (dupe)
pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %qE", qual); {
bool warned = pedwarn_c90 (loc, OPT_Wpedantic,
"duplicate %qE declaration specifier", qual);
if (!warned
&& warn_duplicate_decl_specifier
&& prev_loc >= RESERVED_LOCATION_COUNT
&& !from_macro_expansion_at (prev_loc)
&& !from_macro_expansion_at (loc))
warning_at (loc, OPT_Wduplicate_decl_specifier,
"duplicate %qE declaration specifier", qual);
}
return specs; return specs;
} }
......
...@@ -71,11 +71,12 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...) ...@@ -71,11 +71,12 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn
when C99 is specified. (There is no flag_c90.) */ when C99 is specified. (There is no flag_c90.) */
void bool
pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
{ {
diagnostic_info diagnostic; diagnostic_info diagnostic;
va_list ap; va_list ap;
bool warned = false;
rich_location richloc (line_table, location); rich_location richloc (line_table, location);
va_start (ap, gmsgid); va_start (ap, gmsgid);
...@@ -92,6 +93,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) ...@@ -92,6 +93,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
? DK_PEDWARN : DK_WARNING); ? DK_PEDWARN : DK_WARNING);
diagnostic.option_index = opt; diagnostic.option_index = opt;
report_diagnostic (&diagnostic); report_diagnostic (&diagnostic);
warned = true;
goto out; goto out;
} }
} }
...@@ -114,7 +116,9 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...) ...@@ -114,7 +116,9 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
diagnostic.option_index = opt; diagnostic.option_index = opt;
report_diagnostic (&diagnostic); report_diagnostic (&diagnostic);
warned = true;
} }
out: out:
va_end (ap); va_end (ap);
return warned;
} }
...@@ -253,6 +253,7 @@ enum c_declspec_word { ...@@ -253,6 +253,7 @@ enum c_declspec_word {
cdw_const, cdw_const,
cdw_volatile, cdw_volatile,
cdw_restrict, cdw_restrict,
cdw_atomic,
cdw_saturating, cdw_saturating,
cdw_alignas, cdw_alignas,
cdw_address_space, cdw_address_space,
...@@ -716,7 +717,7 @@ extern void c_bind (location_t, tree, bool); ...@@ -716,7 +717,7 @@ extern void c_bind (location_t, tree, bool);
extern bool tag_exists_p (enum tree_code, tree); extern bool tag_exists_p (enum tree_code, tree);
/* In c-errors.c */ /* In c-errors.c */
extern void pedwarn_c90 (location_t, int opt, const char *, ...) extern bool pedwarn_c90 (location_t, int opt, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4); ATTRIBUTE_GCC_DIAG(3,4);
extern bool pedwarn_c99 (location_t, int opt, const char *, ...) extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4); ATTRIBUTE_GCC_DIAG(3,4);
......
...@@ -3542,6 +3542,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}. ...@@ -3542,6 +3542,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-Wc++11-compat -Wc++14-compat@gol -Wc++11-compat -Wc++14-compat@gol
-Wchar-subscripts @gol -Wchar-subscripts @gol
-Wcomment @gol -Wcomment @gol
-Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
-Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol -Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
-Wformat @gol -Wformat @gol
-Wimplicit @r{(C and Objective-C only)} @gol -Wimplicit @r{(C and Objective-C only)} @gol
...@@ -3699,6 +3700,13 @@ float area(float radius) ...@@ -3699,6 +3700,13 @@ float area(float radius)
the compiler performs the entire computation with @code{double} the compiler performs the entire computation with @code{double}
because the floating-point literal is a @code{double}. because the floating-point literal is a @code{double}.
@item -Wduplicate-decl-specifier @r{(C and Objective-C only)}
@opindex Wduplicate-decl-specifier
@opindex Wno-duplicate-decl-specifier
Warn if a declaration has duplicate @code{const}, @code{volatile},
@code{restrict} or @code{_Atomic} specifier. This warning is enabled by
@option{-Wall}.
@item -Wformat @item -Wformat
@itemx -Wformat=@var{n} @itemx -Wformat=@var{n}
@opindex Wformat @opindex Wformat
......
2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
PR c/43651
* gcc.dg/Wduplicate-decl-specifier-c11.c: New test.
* gcc.dg/Wduplicate-decl-specifier.c: Likewise.
2016-05-11 Uros Bizjak <ubizjak@gmail.com> 2016-05-11 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/sse-13.c: Add dg-add-options bind_pic_locally * gcc.target/i386/sse-13.c: Add dg-add-options bind_pic_locally
......
/* { dg-do compile } */
/* { dg-options "-std=c11 -Wduplicate-decl-specifier" } */
typedef _Atomic int AT1;
#define AT2 _Atomic int
void
foo (void)
{
_Atomic AT1 x1;
_Atomic AT2 x2;
AT1 _Atomic x3;
AT2 _Atomic x4;
_Atomic int _Atomic x5; /* { dg-warning "duplicate ._Atomic." } */
}
void a1(_Atomic AT1 t) { }
void a2(_Atomic AT2 t) { }
void a3(AT1 _Atomic t) { }
void a4(AT2 _Atomic t) { }
void a5(_Atomic int _Atomic t) { } /* { dg-warning "duplicate ._Atomic." } */
typedef _Atomic AT1 AAT1;
typedef _Atomic AT2 AAT2;
typedef AT1 _Atomic AT1A;
typedef AT2 _Atomic AT2A;
typedef _Atomic int _Atomic AIA; /* { dg-warning "duplicate ._Atomic." } */
/* PR43651 */
/* { dg-do compile } */
/* { dg-options "-Wduplicate-decl-specifier" } */
typedef const int CT1;
#define CT2 const int
typedef volatile int VT1;
#define VT2 volatile int
typedef char *restrict RT1;
#define RT2 char *restrict
void
foo (void)
{
const CT1 x1;
const CT2 x2;
CT1 const x3;
CT2 const x4;
const int const x5; /* { dg-warning "duplicate .const." } */
const int *const x6;
volatile VT1 y1;
volatile VT2 y2;
VT1 volatile y3;
VT2 volatile y4;
volatile int volatile y5; /* { dg-warning "duplicate .volatile." } */
volatile int *volatile y6;
RT1 restrict r1;
RT2 restrict r2;
restrict RT1 r3;
/* "restrict RT2" is invalid */
char *restrict restrict r4; /* { dg-warning "duplicate .restrict." } */
char *restrict *restrict r5;
}
void c1(const CT1 t) { }
void c2(const CT2 t) { }
void c3(CT1 const t) { }
void c4(CT2 const t) { }
void c5(const int const t) { } /* { dg-warning "duplicate .const." } */
void v1(volatile VT1 t) { }
void v2(volatile VT2 t) { }
void v3(VT1 volatile t) { }
void v4(VT2 volatile t) { }
void v5(volatile int volatile t) { } /* { dg-warning "duplicate .volatile." } */
void r1(restrict RT1 t) { }
void r2(RT1 restrict t) { }
void r3(RT2 restrict t) { }
void r4(char *restrict restrict t) { } /* { dg-warning "duplicate .restrict." } */
typedef const CT1 CCT1;
typedef const CT2 CCT2;
typedef CT1 const CT1C;
typedef CT2 const CT2C;
typedef const int const CIC; /* { dg-warning "duplicate .const." } */
typedef volatile VT1 VVT1;
typedef volatile VT2 VVT2;
typedef VT1 volatile VT1V;
typedef VT2 volatile VT2V;
typedef volatile int volatile VIV; /* { dg-warning "duplicate .volatile." } */
typedef RT1 restrict RT1R;
typedef RT2 restrict RT2R;
typedef restrict RT1 RRT1;
typedef int *restrict restrict IRR; /* { dg-warning "duplicate .restrict." } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment