aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMikhail Maltsev <maltsevm@gmail.com>2016-05-11 20:23:37 +0000
committerMikhail Maltsev <miyuki@gcc.gnu.org>2016-05-11 20:23:37 +0000
commitd6e83a8dec2b4fd3a92e87add4fa0485dd87d9f7 (patch)
tree53be56313df606591b5a5db27a863bed98dc7f1a /gcc/c
parent51e67ea376b70fd41542c1540d809a32f10ed9ca (diff)
downloadgcc-d6e83a8dec2b4fd3a92e87add4fa0485dd87d9f7.zip
gcc-d6e83a8dec2b4fd3a92e87add4fa0485dd87d9f7.tar.gz
gcc-d6e83a8dec2b4fd3a92e87add4fa0485dd87d9f7.tar.bz2
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
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog9
-rw-r--r--gcc/c/c-decl.c18
-rw-r--r--gcc/c/c-errors.c6
-rw-r--r--gcc/c/c-tree.h3
4 files changed, 33 insertions, 3 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 7044400..d17cd92 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,12 @@
+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>
PR c++/71024
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 6ba0e0e..88424a7 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -9515,32 +9515,48 @@ declspecs_add_qual (source_location loc,
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual);
+ location_t prev_loc = 0;
switch (i)
{
case RID_CONST:
dupe = specs->const_p;
specs->const_p = true;
+ prev_loc = specs->locations[cdw_const];
specs->locations[cdw_const] = loc;
break;
case RID_VOLATILE:
dupe = specs->volatile_p;
specs->volatile_p = true;
+ prev_loc = specs->locations[cdw_volatile];
specs->locations[cdw_volatile] = loc;
break;
case RID_RESTRICT:
dupe = specs->restrict_p;
specs->restrict_p = true;
+ prev_loc = specs->locations[cdw_restrict];
specs->locations[cdw_restrict] = loc;
break;
case RID_ATOMIC:
dupe = specs->atomic_p;
specs->atomic_p = true;
+ prev_loc = specs->locations[cdw_atomic];
+ specs->locations[cdw_atomic] = loc;
break;
default:
gcc_unreachable ();
}
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;
}
diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c
index d5e78b8..af157c0 100644
--- a/gcc/c/c-errors.c
+++ b/gcc/c/c-errors.c
@@ -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
when C99 is specified. (There is no flag_c90.) */
-void
+bool
pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
+ bool warned = false;
rich_location richloc (line_table, location);
va_start (ap, gmsgid);
@@ -92,6 +93,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
? DK_PEDWARN : DK_WARNING);
diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
+ warned = true;
goto out;
}
}
@@ -114,7 +116,9 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
+ warned = true;
}
out:
va_end (ap);
+ return warned;
}
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 07d0f65..d97e575 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -253,6 +253,7 @@ enum c_declspec_word {
cdw_const,
cdw_volatile,
cdw_restrict,
+ cdw_atomic,
cdw_saturating,
cdw_alignas,
cdw_address_space,
@@ -716,7 +717,7 @@ extern void c_bind (location_t, tree, bool);
extern bool tag_exists_p (enum tree_code, tree);
/* 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);
extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4);