llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Endre Fülöp (gamesh411) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/176485.diff 5 Files Affected: - (modified) clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp (+24-6) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) - (modified) clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst (+7-2) - (modified) clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c (+10-10) - (modified) clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp (+1-1) ``````````diff 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, `````````` </details> https://github.com/llvm/llvm-project/pull/176485 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
