[clang-tools-extra] [clang-tidy] Fix `cppcoreguidelines-use-enum-class` anonymous enum bug (PR #215352)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 12 09:57:36 PDT 2026
https://github.com/void2012 updated https://github.com/llvm/llvm-project/pull/215352
>From c52a49dd7103ba0a87070ab79b862ceb89d5f711 Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 00:40:52 +0700
Subject: [PATCH 1/9] Ignore anonymous enums in `UseEnumClassCheck`
`UseEnumClassCheck::registerMatchers` didn't check for empty enum names, fix this
---
.../clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
index 84720d10c233e..8ed64cbb9214e 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
@@ -28,8 +28,8 @@ void UseEnumClassCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void UseEnumClassCheck::registerMatchers(MatchFinder *Finder) {
const auto EnumDecl =
IgnoreUnscopedEnumsInClasses
- ? enumDecl(unless(isScoped()), unless(hasParent(recordDecl())))
- : enumDecl(unless(isScoped()));
+ ? enumDecl(unless(isScoped()), unless(hasName("")), unless(hasParent(recordDecl())))
+ : enumDecl(unless(isScoped()), unless(hasName("")));
Finder->addMatcher(EnumDecl.bind("unscoped_enum"), this);
}
>From dcd92724588e61a7713bac40e039f61606615ef0 Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 00:48:59 +0700
Subject: [PATCH 2/9] Add anonymous enum test to
`cppcoreguidelines/use-enum-class.cpp`
---
.../clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp
index f53d787f80efa..033865a7ac830 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/use-enum-class.cpp
@@ -60,3 +60,5 @@ enum ForwardE : int;
enum class ForwardEC : int;
enum struct ForwardES : int;
+
+enum { A };
>From da263493562fa7fe6879cc32d24e827410e09bd6 Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 00:53:56 +0700
Subject: [PATCH 3/9] Fix formatting
---
.../clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
index 84720d10c233e..9d3915e509ec8 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
@@ -26,10 +26,10 @@ void UseEnumClassCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void UseEnumClassCheck::registerMatchers(MatchFinder *Finder) {
- const auto EnumDecl =
- IgnoreUnscopedEnumsInClasses
- ? enumDecl(unless(isScoped()), unless(hasParent(recordDecl())))
- : enumDecl(unless(isScoped()));
+ const auto EnumDecl = IgnoreUnscopedEnumsInClasses
+ ? enumDecl(unless(isScoped()), unless(hasName("")),
+ unless(hasParent(recordDecl())))
+ : enumDecl(unless(isScoped()), unless(hasName("")));
Finder->addMatcher(EnumDecl.bind("unscoped_enum"), this);
}
>From 4a677dd3655ad6502f4101cf975597e738be028c Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 01:45:15 +0700
Subject: [PATCH 4/9] Fix `HasNameMatcher` assertion failure
---
.../cppcoreguidelines/UseEnumClassCheck.cpp | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
index 9d3915e509ec8..340f09c513165 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
@@ -10,6 +10,14 @@
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
+using namespace clang::ast_matchers::internal;
+
+namespace {
+// FIXME: The matcher 'hasName(Name)' asserts that its argument 'Name' is
+// nonempty. Perhaps remove that assertion and replace 'isUnnamed()' with
+// 'hasName("")'.
+AST_MATCHER(clang::EnumDecl, isUnnamed) { return Node.getName().empty(); }
+} // namespace
namespace clang::tidy::cppcoreguidelines {
@@ -27,9 +35,9 @@ void UseEnumClassCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void UseEnumClassCheck::registerMatchers(MatchFinder *Finder) {
const auto EnumDecl = IgnoreUnscopedEnumsInClasses
- ? enumDecl(unless(isScoped()), unless(hasName("")),
+ ? enumDecl(unless(isScoped()), unless(isUnnamed()),
unless(hasParent(recordDecl())))
- : enumDecl(unless(isScoped()), unless(hasName("")));
+ : enumDecl(unless(isScoped()), unless(isUnnamed()));
Finder->addMatcher(EnumDecl.bind("unscoped_enum"), this);
}
>From c9eea2d720dc312d2b1dd2d01e35abcb199512cf Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 02:04:07 +0700
Subject: [PATCH 5/9] Update ReleaseNotes.md
---
clang-tools-extra/docs/ReleaseNotes.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 29de9aef9e4b6..9b45a5f70bf11 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -144,6 +144,9 @@ infrastructure are described first, followed by tool-specific sections.
<clang-tidy/checks/readability/use-std-min-max>` check by fixing spurious
trailing semicolons and lost comments when the `if` body has no braces.
+- Fixed {doc}`cppcoreguidelines-use-enum-class
+ <clang-tidy/checks/cppcoreguidelines/use-enum-class>` suggesting `enum class` for unnamed enums (which is ill-formed).
+
#### Removed checks
- Removed the deprecated `zircon-temporary-objects` check. Users should migrate to
>From 42a1c3df5edbfb3d25a04e09044e2de7ab04862e Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Tue, 11 Aug 2026 02:26:21 +0700
Subject: [PATCH 6/9] Fix ReleaseNotes alphabetical order
---
clang-tools-extra/docs/ReleaseNotes.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 9b45a5f70bf11..06ae4fc684e3e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -121,6 +121,9 @@ infrastructure are described first, followed by tool-specific sections.
- Improved {doc}`cppcoreguidelines-pro-type-member-init
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check by treating
`std::array` the same as built-in arrays when `IgnoreArrays` option is enabled.
+
+- Fixed {doc}`cppcoreguidelines-use-enum-class
+ <clang-tidy/checks/cppcoreguidelines/use-enum-class>` suggesting `enum class` for unnamed enums (which is ill-formed).
- Improved {doc}`misc-redundant-expression
<clang-tidy/checks/misc/redundant-expression>` by fixing false positives in
@@ -144,9 +147,6 @@ infrastructure are described first, followed by tool-specific sections.
<clang-tidy/checks/readability/use-std-min-max>` check by fixing spurious
trailing semicolons and lost comments when the `if` body has no braces.
-- Fixed {doc}`cppcoreguidelines-use-enum-class
- <clang-tidy/checks/cppcoreguidelines/use-enum-class>` suggesting `enum class` for unnamed enums (which is ill-formed).
-
#### Removed checks
- Removed the deprecated `zircon-temporary-objects` check. Users should migrate to
>From 89e11adb8cb7a463ae2f5c460e05759c63161086 Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Wed, 12 Aug 2026 00:50:48 +0700
Subject: [PATCH 7/9] Update ReleaseNotes.md
---
clang-tools-extra/docs/ReleaseNotes.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 06ae4fc684e3e..21354ee12f9b5 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -122,8 +122,8 @@ infrastructure are described first, followed by tool-specific sections.
<clang-tidy/checks/cppcoreguidelines/pro-type-member-init>` check by treating
`std::array` the same as built-in arrays when `IgnoreArrays` option is enabled.
-- Fixed {doc}`cppcoreguidelines-use-enum-class
- <clang-tidy/checks/cppcoreguidelines/use-enum-class>` suggesting `enum class` for unnamed enums (which is ill-formed).
+- Improved {doc}`cppcoreguidelines-use-enum-class
+ <clang-tidy/checks/cppcoreguidelines/use-enum-class>` check by omitting unnamed enums from the `enum class` requirement, as previously the check suggested users an ill-formed fix.
- Improved {doc}`misc-redundant-expression
<clang-tidy/checks/misc/redundant-expression>` by fixing false positives in
>From e6b9d61f767138765b2abcd195c2c3c193b48c58 Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Wed, 12 Aug 2026 23:53:05 +0700
Subject: [PATCH 8/9] Move `isUnnamed` to the inside of
`clang::tidy::cppcoreguidelines`
`clang::EnumDecl` -> `EnumDecl`
---
.../clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
index 340f09c513165..0865148a2fad4 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp
@@ -12,15 +12,14 @@
using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;
+namespace clang::tidy::cppcoreguidelines {
namespace {
// FIXME: The matcher 'hasName(Name)' asserts that its argument 'Name' is
// nonempty. Perhaps remove that assertion and replace 'isUnnamed()' with
// 'hasName("")'.
-AST_MATCHER(clang::EnumDecl, isUnnamed) { return Node.getName().empty(); }
+AST_MATCHER(EnumDecl, isUnnamed) { return Node.getName().empty(); }
} // namespace
-namespace clang::tidy::cppcoreguidelines {
-
UseEnumClassCheck::UseEnumClassCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IgnoreUnscopedEnumsInClasses(
>From ca9a44e653815d78659003291b7ee9e07601b7fd Mon Sep 17 00:00:00 2001
From: void_17 <heroerror3 at gmail.com>
Date: Wed, 12 Aug 2026 23:57:22 +0700
Subject: [PATCH 9/9] Update use-enum-class.rst
---
.../clang-tidy/checks/cppcoreguidelines/use-enum-class.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst
index 746d24aa8ea34..dd0f3fc25fa8b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/use-enum-class.rst
@@ -4,7 +4,8 @@ cppcoreguidelines-use-enum-class
================================
Finds unscoped (non-class) ``enum`` declarations and suggests using
-``enum class`` instead.
+``enum class`` instead. Unnamed enum are ignored and will be handled by check implementing `Enum.6
+<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#enum6-avoid-unnamed-enumerations>`_.
This check implements `Enum.3
<https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#renum-class>`_
More information about the cfe-commits
mailing list