https://github.com/gamesh411 created https://github.com/llvm/llvm-project/pull/176485
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. From 5bd02764a8dc94e6c2d1d743bcb43de04bdfca77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <[email protected]> Date: Fri, 16 Jan 2026 19:05:02 +0100 Subject: [PATCH] [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, _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
