Author: Endre Fülöp Date: 2023-08-09T15:12:09+02:00 New Revision: 90c1f51c4b3e7a38a5e1b75de75d15757fc861e4
URL: https://github.com/llvm/llvm-project/commit/90c1f51c4b3e7a38a5e1b75de75d15757fc861e4 DIFF: https://github.com/llvm/llvm-project/commit/90c1f51c4b3e7a38a5e1b75de75d15757fc861e4.diff LOG: [clang][analyzer] Fix empty enum handling in EnumCastOutOfRange checker The alpha.cplusplus.EnumCastOutOfRange checker previously gave many false positives because a warning was given if the initializer value did not appear in the enumerator list. The strict handling caused std::byte to always give a warning, as it is implemented as an enum class without any declarators. Reviewed By: donat.nagy, steakhal Differential Revision: https://reviews.llvm.org/D153954 Added: Modified: clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp clang/test/Analysis/enum-cast-out-of-range.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp index 1077ceb6288efe..bfb8d1cc010535 100644 --- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -129,6 +129,14 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE, const EnumDecl *ED = T->castAs<EnumType>()->getDecl(); EnumValueVector DeclValues = getDeclValuesForEnum(ED); + + // If the declarator list is empty, bail out. + // Every initialization an enum with a fixed underlying type but without any + // enumerators would produce a warning if we were to continue at this point. + // The most notable example is std::byte in the C++17 standard library. + if (DeclValues.size() == 0) + return; + // Check if any of the enum values possibly match. bool PossibleValueMatch = llvm::any_of( DeclValues, ConstraintBasedEQEvaluator(C, *ValueToCast)); diff --git a/clang/test/Analysis/enum-cast-out-of-range.cpp b/clang/test/Analysis/enum-cast-out-of-range.cpp index b600367f8c14a4..abc1431e5be140 100644 --- a/clang/test/Analysis/enum-cast-out-of-range.cpp +++ b/clang/test/Analysis/enum-cast-out-of-range.cpp @@ -198,3 +198,20 @@ void enumBitFieldAssignment() { s.E = static_cast<unscoped_unspecified_t>(4); // OK. s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for the enum}} } + + +enum class empty_unspecified {}; + +enum class empty_specified: char {}; + +enum class empty_specified_unsigned: unsigned char {}; + +void ignore_unused(...); + +void empty_enums_init_with_zero_should_not_warn() { + auto eu = static_cast<empty_unspecified>(0); //should always be OK to zero initialize any enum + auto ef = static_cast<empty_specified>(0); + auto efu = static_cast<empty_specified_unsigned>(0); + + ignore_unused(eu, ef, efu); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits