gamesh411 updated this revision to Diff 548593. gamesh411 added a comment. minor review fixups
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153954/new/ https://reviews.llvm.org/D153954 Files: clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp clang/test/Analysis/enum-cast-out-of-range.cpp Index: clang/test/Analysis/enum-cast-out-of-range.cpp =================================================================== --- clang/test/Analysis/enum-cast-out-of-range.cpp +++ clang/test/Analysis/enum-cast-out-of-range.cpp @@ -198,3 +198,20 @@ 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); +} Index: clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -129,6 +129,14 @@ 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));
Index: clang/test/Analysis/enum-cast-out-of-range.cpp =================================================================== --- clang/test/Analysis/enum-cast-out-of-range.cpp +++ clang/test/Analysis/enum-cast-out-of-range.cpp @@ -198,3 +198,20 @@ 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); +} Index: clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp @@ -129,6 +129,14 @@ 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));
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits