diff --git a/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp index e0323848870bd..d81be621005be 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp @@ -19,9 +19,10 @@ namespace clang::tidy::bugprone { namespace { -AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) { +AST_MATCHER(EnumDecl, isCompleteNonEmptyAndHasNoZeroValue) { const EnumDecl *Definition = Node.getDefinition(); return Definition && Node.isComplete() && + Definition->enumerator_begin() != Definition->enumerator_end() && std::none_of(Definition->enumerator_begin(), Definition->enumerator_end(), [](const EnumConstantDecl *Value) { @@ -29,6 +30,11 @@ AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) { }); } +AST_MATCHER(EnumDecl, hasBoolAsUnderlyingType) { + const QualType UnderlyingType = Node.getIntegerType(); + return !UnderlyingType.isNull() && UnderlyingType->isBooleanType(); +} + } // namespace NonZeroEnumToBoolConversionCheck::NonZeroEnumToBoolConversionCheck( @@ -59,7 +65,8 @@ void NonZeroEnumToBoolConversionCheck::registerMatchers(MatchFinder *Finder) { unless(isExpansionInSystemHeader()), hasType(booleanType()), hasSourceExpression( expr(hasType(qualType(hasCanonicalType(hasDeclaration( - enumDecl(isCompleteAndHasNoZeroValue(), + enumDecl(isCompleteNonEmptyAndHasNoZeroValue(), + unless(hasBoolAsUnderlyingType()), unless(matchers::matchesAnyListedName( EnumIgnoreList))) .bind("enum"))))), diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 0ad52f83fad85..68af57564b793 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -118,6 +118,10 @@ New check aliases Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Improved :doc:`bugprone-non-zero-enum-to-bool-conversion + ` check to + ignore enums without enumerators and enums with ``bool`` as underlying type. + - Improved :doc:`bugprone-optional-value-conversion ` check to detect conversion in argument of ``std::make_optional``. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.rst index 168ed71674773..de842099a71c3 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.rst @@ -12,7 +12,8 @@ and maintainability and can result in bugs. May produce false positives if the ``enum`` is used to store other values (used as a bit-mask or zero-initialized on purpose). To deal with them, ``// NOLINT`` or casting first to the underlying type before casting to ``bool`` -can be used. +can be used. Enums without enumerators and enums that use ``bool`` as the +underlying type are ignored. It is important to note that this check will not generate warnings if the definition of the enumeration type is not available. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp index 42927c615ffc7..36892ce0231b0 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion-cpp11.cpp @@ -106,5 +106,18 @@ bool testEnumConversion(const EResult& value) { } } +} + +namespace without::issue { +namespace enum_bool { +enum EResult : bool { + OK = 1 +}; + +bool testEnumConversion(const EResult& value) { + return value; +} + +} } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp index 3375f69b59111..22d931cd35f42 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/non-zero-enum-to-bool-conversion.cpp @@ -126,4 +126,10 @@ void testCustomOperator(CustomOperatorEnum e) { if (!(e & E1)) {} } +enum EmptyEnum {}; + +bool testCustomOperator(EmptyEnum value) { + return value; +} + }