[clang-tools-extra] [clang-tidy] Improve readability-enum-initial-value diagnostic message (PR #176485)
Endre Fülöp via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 18 12:03:20 PST 2026
https://github.com/gamesh411 updated https://github.com/llvm/llvm-project/pull/176485
>From 5bd02764a8dc94e6c2d1d743bcb43de04bdfca77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Fri, 16 Jan 2026 19:05:02 +0100
Subject: [PATCH 1/8] [clang-tidy] Improve readability-enum-initial-value
diagnostic message
Enhance the readability-enum-initial-value checker to list which
enumerators
are not initialized in the warning message. This makes it easier for
users to
identify which specific enumerators need explicit initialization.
---
.../readability/EnumInitialValueCheck.cpp | 30 +++++++++++++++----
clang-tools-extra/docs/ReleaseNotes.rst | 6 ++++
.../checks/readability/enum-initial-value.rst | 9 ++++--
.../checkers/readability/enum-initial-value.c | 20 ++++++-------
.../readability/enum-initial-value.cpp | 2 +-
5 files changed, 48 insertions(+), 19 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
index 049ad759b834c..364ac74ffeed7 100644
--- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
@@ -15,6 +15,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
using namespace clang::ast_matchers;
@@ -165,12 +166,29 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) {
void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("inconsistent")) {
- const DiagnosticBuilder Diag =
- diag(
- Enum->getBeginLoc(),
- "initial values in enum '%0' are not consistent, consider explicit "
- "initialization of all, none or only the first enumerator")
- << getName(Enum);
+ llvm::SmallVector<StringRef, 4> UninitializedNames;
+ for (const EnumConstantDecl *ECD : Enum->enumerators())
+ if (ECD->getInitExpr() == nullptr && ECD->getDeclName())
+ UninitializedNames.push_back(ECD->getName());
+
+ llvm::SmallString<256> Message;
+ Message = "initial values in enum '%0' are not consistent, "
+ "consider explicit initialization of all, none or "
+ "only the first enumerator";
+ if (!UninitializedNames.empty()) {
+ Message += " (uninitialized enumerators: ";
+ for (size_t I = 0; I < UninitializedNames.size(); ++I) {
+ if (I > 0)
+ Message += (I < UninitializedNames.size() - 1) ? ", " : " and ";
+ Message += "'";
+ Message += UninitializedNames[I];
+ Message += "'";
+ }
+ Message += ")";
+ }
+
+ const DiagnosticBuilder Diag = diag(Enum->getBeginLoc(), Message)
+ << getName(Enum);
for (const EnumConstantDecl *ECD : Enum->enumerators())
if (ECD->getInitExpr() == nullptr) {
const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 94a11b1acb73a..e9ba7309cfa7d 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -113,6 +113,12 @@ Changes in existing checks
<clang-tidy/checks/performance/move-const-arg>` check by avoiding false
positives on trivially copyable types with a non-public copy constructor.
+- Improved :doc:`readability-enum-initial-value
+ <clang-tidy/checks/readability/enum-initial-value>` check:
+
+ - The warning message now lists which enumerators are not initialized, making
+ it easier to see which specific enumerators need explicit initialization.
+
Removed checks
^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
index b27e10d5c1336..65afe1c85b902 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
@@ -36,13 +36,18 @@ The following three cases are accepted:
c2 = 2,
};
- enum D { // Invalid, d1 is not explicitly initialized!
+ enum D { // warning: initial values in enum 'D' are not consistent,
+ // consider explicit initialization of all, none or only
+ // the first enumerator (uninitialized enumerators: 'd1')
d0 = 0,
d1,
d2 = 2,
};
- enum E { // Invalid, e1, e3, and e5 are not explicitly initialized.
+ enum E { // warning: initial values in enum 'E' are not consistent,
+ // consider explicit initialization of all, none or only
+ // the first enumerator (uninitialized enumerators:
+ // 'e1', 'e3' and 'e5')
e0 = 0,
e1,
e2 = 2,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
index 54108585f030f..0d935d7ec919a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
@@ -6,8 +6,8 @@
// RUN: }}'
enum EError {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EError' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
EError_a = 1,
EError_b,
// CHECK-FIXES: EError_b = 2,
@@ -34,8 +34,8 @@ enum EAll {
#define ENUMERATOR_1 EMacro1_b
enum EMacro1 {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro1' are not consistent
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro1' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro1_b')
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro1_b')
EMacro1_a = 1,
ENUMERATOR_1,
// CHECK-FIXES: ENUMERATOR_1 = 2,
@@ -45,8 +45,8 @@ enum EMacro1 {
#define ENUMERATOR_2 EMacro2_b = 2
enum EMacro2 {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro2' are not consistent
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro2' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro2_c')
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro2_c')
EMacro2_a = 1,
ENUMERATOR_2,
EMacro2_c,
@@ -55,8 +55,8 @@ enum EMacro2 {
enum {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EAnonymous_b')
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EAnonymous_b')
EAnonymous_a = 1,
EAnonymous_b,
// CHECK-FIXES: EAnonymous_b = 2,
@@ -94,8 +94,8 @@ enum EnumSequentialInitialValue {
enum WithFwdDeclInconsistent : int;
enum WithFwdDeclInconsistent : int {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EFI0' and 'EFI2')
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EFI0' and 'EFI2')
EFI0,
// CHECK-FIXES: EFI0 = 0,
EFI1 = 1,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
index 9d324a39ee6a3..ee32cd2429e71 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
@@ -1,7 +1,7 @@
// RUN: %check_clang_tidy %s readability-enum-initial-value %t
enum class EError {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
EError_a = 1,
EError_b,
// CHECK-FIXES: EError_b = 2,
>From b6e582e68930456829afc22eb1c4e72b5835e8c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sat, 17 Jan 2026 22:18:23 +0100
Subject: [PATCH 2/8] update release-notes
---
clang-tools-extra/docs/ReleaseNotes.rst | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index e9ba7309cfa7d..5416bb4ed052b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -114,10 +114,9 @@ Changes in existing checks
positives on trivially copyable types with a non-public copy constructor.
- Improved :doc:`readability-enum-initial-value
- <clang-tidy/checks/readability/enum-initial-value>` check:
-
- - The warning message now lists which enumerators are not initialized, making
- it easier to see which specific enumerators need explicit initialization.
+ <clang-tidy/checks/readability/enum-initial-value>` check: The warning message
+ now uses separate note diagnostics for each uninitialized enumerator, making
+ it easier to see which specific enumerators need explicit initialization.
Removed checks
^^^^^^^^^^^^^^
>From a4935a12a813392699b686ccc1079929c0c9a57e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sat, 17 Jan 2026 22:22:12 +0100
Subject: [PATCH 3/8] update docs
---
.../checks/readability/enum-initial-value.rst | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
index 65afe1c85b902..f59c433c51d0b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst
@@ -38,22 +38,23 @@ The following three cases are accepted:
enum D { // warning: initial values in enum 'D' are not consistent,
// consider explicit initialization of all, none or only
- // the first enumerator (uninitialized enumerators: 'd1')
+ // the first enumerator
d0 = 0,
- d1,
+ d1, // note: uninitialized enumerator 'd1' defined here
d2 = 2,
};
enum E { // warning: initial values in enum 'E' are not consistent,
// consider explicit initialization of all, none or only
- // the first enumerator (uninitialized enumerators:
- // 'e1', 'e3' and 'e5')
+ // the first enumerator
e0 = 0,
- e1,
+ e1, // note: uninitialized enumerator 'e1' defined here
e2 = 2,
- e3, // Dangerous, as the numeric values of e3 and e5 are both 3, and this is not explicitly visible in the code!
+ e3, // note: uninitialized enumerator 'e3' defined here
+ // Dangerous, as the numeric values of e3 and e5 are both 3,
+ // and this is not explicitly visible in the code!
e4 = 2,
- e5,
+ e5, // note: uninitialized enumerator 'e5' defined here
};
This check corresponds to the CERT C Coding Standard recommendation `INT09-C. Ensure enumeration constants map to unique values
>From 1ce4d944802cd716b5d353d45cdf1dc358ad66f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sat, 17 Jan 2026 22:25:51 +0100
Subject: [PATCH 4/8] update implementation to use notes
---
.../readability/EnumInitialValueCheck.cpp | 56 +++++++++----------
.../checkers/readability/enum-initial-value.c | 34 +++++++----
.../readability/enum-initial-value.cpp | 3 +-
3 files changed, 52 insertions(+), 41 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
index 364ac74ffeed7..a27843e5a95fa 100644
--- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
@@ -15,7 +15,6 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
using namespace clang::ast_matchers;
@@ -166,39 +165,36 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) {
void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("inconsistent")) {
- llvm::SmallVector<StringRef, 4> UninitializedNames;
- for (const EnumConstantDecl *ECD : Enum->enumerators())
- if (ECD->getInitExpr() == nullptr && ECD->getDeclName())
- UninitializedNames.push_back(ECD->getName());
-
- llvm::SmallString<256> Message;
- Message = "initial values in enum '%0' are not consistent, "
- "consider explicit initialization of all, none or "
- "only the first enumerator";
- if (!UninitializedNames.empty()) {
- Message += " (uninitialized enumerators: ";
- for (size_t I = 0; I < UninitializedNames.size(); ++I) {
- if (I > 0)
- Message += (I < UninitializedNames.size() - 1) ? ", " : " and ";
- Message += "'";
- Message += UninitializedNames[I];
- Message += "'";
+ // Emit warning first (DiagnosticBuilder emits on destruction), then notes.
+ // Notes must follow the primary diagnostic or they may be dropped.
+ {
+ DiagnosticBuilder Diag =
+ diag(Enum->getBeginLoc(), "initial values in enum '%0' are not "
+ "consistent, consider explicit "
+ "initialization of all, none or only the "
+ "first enumerator")
+ << getName(Enum);
+
+ for (const EnumConstantDecl *ECD : Enum->enumerators()) {
+ if (ECD->getInitExpr() == nullptr) {
+ const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+ ECD->getLocation(), 0, *Result.SourceManager, getLangOpts());
+ if (EndLoc.isMacroID())
+ continue;
+ llvm::SmallString<8> Str{" = "};
+ ECD->getInitVal().toString(Str);
+ Diag << FixItHint::CreateInsertion(EndLoc, Str);
+ }
}
- Message += ")";
}
- const DiagnosticBuilder Diag = diag(Enum->getBeginLoc(), Message)
- << getName(Enum);
- for (const EnumConstantDecl *ECD : Enum->enumerators())
- if (ECD->getInitExpr() == nullptr) {
- const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
- ECD->getLocation(), 0, *Result.SourceManager, getLangOpts());
- if (EndLoc.isMacroID())
- continue;
- llvm::SmallString<8> Str{" = "};
- ECD->getInitVal().toString(Str);
- Diag << FixItHint::CreateInsertion(EndLoc, Str);
+ for (const EnumConstantDecl *ECD : Enum->enumerators()) {
+ if (ECD->getInitExpr() == nullptr && ECD->getDeclName()) {
+ diag(ECD->getLocation(), "uninitialized enumerator '%0' defined here",
+ DiagnosticIDs::Note)
+ << ECD->getName();
}
+ }
return;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
index 0d935d7ec919a..fcf5b20ea4ee2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c
@@ -6,10 +6,12 @@
// RUN: }}'
enum EError {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator
EError_a = 1,
EError_b,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EError_b' defined here
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:3: note: uninitialized enumerator 'EError_b' defined here
// CHECK-FIXES: EError_b = 2,
EError_c = 3,
};
@@ -34,10 +36,14 @@ enum EAll {
#define ENUMERATOR_1 EMacro1_b
enum EMacro1 {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro1_b')
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro1_b')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro1' are not consistent, consider explicit initialization of all, none or only the first enumerator
EMacro1_a = 1,
ENUMERATOR_1,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EMacro1_b' defined here
+ // CHECK-MESSAGES: note: expanded from macro 'ENUMERATOR_1'
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-3]]:3: note: uninitialized enumerator 'EMacro1_b' defined here
+ // CHECK-MESSAGES-ENABLE: note: expanded from macro 'ENUMERATOR_1'
// CHECK-FIXES: ENUMERATOR_1 = 2,
EMacro1_c = 3,
};
@@ -45,20 +51,24 @@ enum EMacro1 {
#define ENUMERATOR_2 EMacro2_b = 2
enum EMacro2 {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro2_c')
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EMacro2_c')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'EMacro2' are not consistent, consider explicit initialization of all, none or only the first enumerator
EMacro2_a = 1,
ENUMERATOR_2,
EMacro2_c,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EMacro2_c' defined here
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:3: note: uninitialized enumerator 'EMacro2_c' defined here
// CHECK-FIXES: EMacro2_c = 3,
};
enum {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EAnonymous_b')
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EAnonymous_b')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' are not consistent, consider explicit initialization of all, none or only the first enumerator
EAnonymous_a = 1,
EAnonymous_b,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EAnonymous_b' defined here
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:3: note: uninitialized enumerator 'EAnonymous_b' defined here
// CHECK-FIXES: EAnonymous_b = 2,
EAnonymous_c = 3,
};
@@ -94,12 +104,16 @@ enum EnumSequentialInitialValue {
enum WithFwdDeclInconsistent : int;
enum WithFwdDeclInconsistent : int {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EFI0' and 'EFI2')
- // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EFI0' and 'EFI2')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum 'WithFwdDeclInconsistent' are not consistent, consider explicit initialization of all, none or only the first enumerator
EFI0,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EFI0' defined here
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:3: note: uninitialized enumerator 'EFI0' defined here
// CHECK-FIXES: EFI0 = 0,
EFI1 = 1,
EFI2,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EFI2' defined here
+ // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:3: note: uninitialized enumerator 'EFI2' defined here
// CHECK-FIXES: EFI2 = 2,
};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
index ee32cd2429e71..7a97534fd8e2b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp
@@ -1,9 +1,10 @@
// RUN: %check_clang_tidy %s readability-enum-initial-value %t
enum class EError {
- // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator (uninitialized enumerators: 'EError_b')
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum 'EError' are not consistent, consider explicit initialization of all, none or only the first enumerator
EError_a = 1,
EError_b,
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: note: uninitialized enumerator 'EError_b' defined here
// CHECK-FIXES: EError_b = 2,
EError_c = 3,
};
>From e14826133e509c32ec83d0a482c6c48450986fa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sun, 18 Jan 2026 04:32:14 +0100
Subject: [PATCH 5/8] add linter-suggested const
---
clang-tools-extra/clang-tidy/.clang-format | 8 ++++----
.../clang-tidy/readability/EnumInitialValueCheck.cpp | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/.clang-format b/clang-tools-extra/clang-tidy/.clang-format
index 96fb7ce8fce61..5396a66c838d8 100644
--- a/clang-tools-extra/clang-tidy/.clang-format
+++ b/clang-tools-extra/clang-tidy/.clang-format
@@ -1,9 +1,9 @@
BasedOnStyle: LLVM
InsertNewlineAtEOF: true
-KeepEmptyLines:
- AtEndOfFile: false
- AtStartOfBlock: false
- AtStartOfFile: false
+# KeepEmptyLines:
+# AtEndOfFile: false
+# AtStartOfBlock: false
+# AtStartOfFile: false
LineEnding: LF
QualifierAlignment: Left
RemoveBracesLLVM: true
diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
index a27843e5a95fa..666d686d6abbd 100644
--- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
@@ -168,7 +168,7 @@ void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
// Emit warning first (DiagnosticBuilder emits on destruction), then notes.
// Notes must follow the primary diagnostic or they may be dropped.
{
- DiagnosticBuilder Diag =
+ const DiagnosticBuilder Diag =
diag(Enum->getBeginLoc(), "initial values in enum '%0' are not "
"consistent, consider explicit "
"initialization of all, none or only the "
>From e333e618ffdc9971147e49e75332399157ec56cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sun, 18 Jan 2026 04:36:42 +0100
Subject: [PATCH 6/8] fix capitalization in release notes
---
clang-tools-extra/docs/ReleaseNotes.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5416bb4ed052b..68293fcdfafe2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -114,7 +114,7 @@ Changes in existing checks
positives on trivially copyable types with a non-public copy constructor.
- Improved :doc:`readability-enum-initial-value
- <clang-tidy/checks/readability/enum-initial-value>` check: The warning message
+ <clang-tidy/checks/readability/enum-initial-value>` check: the warning message
now uses separate note diagnostics for each uninitialized enumerator, making
it easier to see which specific enumerators need explicit initialization.
>From 25a7569a62f3eba4ead65105600831f8b9440c45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sun, 18 Jan 2026 04:52:47 +0100
Subject: [PATCH 7/8] revert erroneous clang-format config change
---
clang-tools-extra/clang-tidy/.clang-format | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/.clang-format b/clang-tools-extra/clang-tidy/.clang-format
index 5396a66c838d8..96fb7ce8fce61 100644
--- a/clang-tools-extra/clang-tidy/.clang-format
+++ b/clang-tools-extra/clang-tidy/.clang-format
@@ -1,9 +1,9 @@
BasedOnStyle: LLVM
InsertNewlineAtEOF: true
-# KeepEmptyLines:
-# AtEndOfFile: false
-# AtStartOfBlock: false
-# AtStartOfFile: false
+KeepEmptyLines:
+ AtEndOfFile: false
+ AtStartOfBlock: false
+ AtStartOfFile: false
LineEnding: LF
QualifierAlignment: Left
RemoveBracesLLVM: true
>From e8598377e561fd355518fbeaefee9860330fb129 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <endre.fulop at sigmatechnology.com>
Date: Sun, 18 Jan 2026 21:02:38 +0100
Subject: [PATCH 8/8] remove (most likely) redundant name check
---
.../clang-tidy/readability/EnumInitialValueCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
index 666d686d6abbd..d99143c875729 100644
--- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
@@ -189,7 +189,7 @@ void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
}
for (const EnumConstantDecl *ECD : Enum->enumerators()) {
- if (ECD->getInitExpr() == nullptr && ECD->getDeclName()) {
+ if (ECD->getInitExpr() == nullptr) {
diag(ECD->getLocation(), "uninitialized enumerator '%0' defined here",
DiagnosticIDs::Note)
<< ECD->getName();
More information about the cfe-commits
mailing list