https://github.com/AaronBallman created 
https://github.com/llvm/llvm-project/pull/138012

The existing diagnostic, already enabled by default in C, will diagnose use of 
duplicate declaration specifiers (e.g., `const const`). However, the C++ 
standard claims that is ill-formed, so the diagnostic is now also controlled 
via -Wc++-compat.

Note: Clang treats this as a warning in C++ rather than an error, but GCC does 
treat this as an error in C++, so the compatibility concerns are minor but do 
exist.

>From 3471e09bd9a871216408336aa86a3b24c6e433a1 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aa...@aaronballman.com>
Date: Wed, 30 Apr 2025 14:33:03 -0400
Subject: [PATCH] [C] Add -Wduplicate-decl-specifier to -Wc++-compat

The existing diagnostic, already enabled by default in C, will diagnose
use of duplicate declaration specifiers (e.g., `const const`). However,
the C++ standard claims that is ill-formed, so the diagnostic is now
also controlled via -Wc++-compat.

Note: Clang treats this as a warning in C++ rather than an error, but
GCC does treat this as an error in C++, so the compatibility concerns
are minor but do exist.
---
 clang/docs/ReleaseNotes.rst                     |  3 +++
 clang/include/clang/Basic/DiagnosticGroups.td   |  6 ++++--
 clang/test/Sema/warn-duplicate-decl-specifier.c | 17 +++++++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/warn-duplicate-decl-specifier.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5cc1a36fac1e8..3becd3e3e4603 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -188,6 +188,9 @@ C Language Changes
   ``-Wunterminated-string-initialization``. However, this diagnostic is not
   silenced by the ``nonstring`` attribute as these initializations are always
   incompatible with C++.
+- Added the existing ``-Wduplicate-decl-specifier`` diagnostic, which is on by
+  default, to ``-Wc++-compat`` because duplicated declaration specifiers are
+  not valid in C++.
 
 C2y Feature Support
 ^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 75e8fc541305b..de3374962c6b0 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -156,6 +156,8 @@ def BuiltinRequiresHeader : 
DiagGroup<"builtin-requires-header">;
 def C99Compat : DiagGroup<"c99-compat">;
 def C23Compat : DiagGroup<"c23-compat">;
 def : DiagGroup<"c2x-compat", [C23Compat]>;
+
+def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def InitStringTooLongMissingNonString :
   DiagGroup<"unterminated-string-initialization">;
 def InitStringTooLongForCpp :
@@ -168,7 +170,8 @@ def ImplicitIntToEnumCast : 
DiagGroup<"implicit-int-enum-cast",
                                       [ImplicitEnumEnumCast]>;
 def CXXCompat: DiagGroup<"c++-compat", [ImplicitVoidPtrCast, DefaultConstInit,
                                         ImplicitIntToEnumCast, HiddenCppDecl,
-                                        InitStringTooLongForCpp]>;
+                                        InitStringTooLongForCpp,
+                                        DuplicateDeclSpecifier]>;
 
 def ExternCCompat : DiagGroup<"extern-c-compat">;
 def KeywordCompat : DiagGroup<"keyword-compat">;
@@ -814,7 +817,6 @@ def TautologicalCompare : DiagGroup<"tautological-compare",
                                      TautologicalObjCBoolCompare,
                                      TautologicalNegationCompare]>;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
-def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
 def GNUUnionCast : DiagGroup<"gnu-union-cast">;
 def GNUVariableSizedTypeNotAtEnd : 
DiagGroup<"gnu-variable-sized-type-not-at-end">;
diff --git a/clang/test/Sema/warn-duplicate-decl-specifier.c 
b/clang/test/Sema/warn-duplicate-decl-specifier.c
new file mode 100644
index 0000000000000..d57bb867f66f1
--- /dev/null
+++ b/clang/test/Sema/warn-duplicate-decl-specifier.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wduplicate-decl-specifier %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wc++-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-duplicate-decl-specifier 
-Wc++-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify=good -Wc++-compat 
-Wno-duplicate-decl-specifier %s
+// RUN: %clang_cc1 -fsyntax-only -verify=good -Wno-duplicate-decl-specifier %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// good-no-diagnostics
+
+// Note: we treat this as a warning in C++, so you get the same diagnostics in
+// either language mode. However, GCC diagnoses this as an error, so the
+// compatibility warning has value.
+const const int i = 12; // expected-warning {{duplicate 'const' declaration 
specifier}}
+
+__attribute__((address_space(1)))
+__attribute__((address_space(1))) // expected-warning {{multiple identical 
address spaces specified for type}}
+int j = 12;
+

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to