brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.7 KiB · 81763ae Raw
244 lines · cpp
1// RUN: %clang_analyze_cc1 \2// RUN:   -analyzer-checker=core,optin.core.EnumCastOutOfRange \3// RUN:   -std=c++11 -verify %s4 5// expected-note@+1 + {{enum declared here}}6enum unscoped_unspecified_t {7  unscoped_unspecified_0 = -4,8  unscoped_unspecified_1,9  unscoped_unspecified_2 = 1,10  unscoped_unspecified_3,11  unscoped_unspecified_4 = 412};13 14// expected-note@+1 + {{enum declared here}}15enum unscoped_specified_t : int {16  unscoped_specified_0 = -4,17  unscoped_specified_1,18  unscoped_specified_2 = 1,19  unscoped_specified_3,20  unscoped_specified_4 = 421};22 23// expected-note@+1 + {{enum declared here}}24enum class scoped_unspecified_t {25  scoped_unspecified_0 = -4,26  scoped_unspecified_1,27  scoped_unspecified_2 = 1,28  scoped_unspecified_3,29  scoped_unspecified_4 = 430};31 32// expected-note@+1 + {{enum declared here}}33enum class scoped_specified_t : int {34  scoped_specified_0 = -4,35  scoped_specified_1,36  scoped_specified_2 = 1,37  scoped_specified_3,38  scoped_specified_4 = 439};40 41struct S {42  unscoped_unspecified_t E : 5;43};44 45void unscopedUnspecified() {46  unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}47  unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK.48  unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK.49  unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}50  unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}51  unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}52  unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK.53  unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK.54  unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}55  unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK.56  unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}57}58 59void unscopedSpecified() {60  unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}61  unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK.62  unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK.63  unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}64  unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}65  unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}66  unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK.67  unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK.68  unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}69  unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK.70  unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}71}72 73void scopedUnspecified() {74  scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}75  scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK.76  scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK.77  scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}78  scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}79  scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}80  scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK.81  scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK.82  scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}83  scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK.84  scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}85}86 87void scopedSpecified() {88  scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}89  scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK.90  scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK.91  scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}92  scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}93  scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}94  scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK.95  scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK.96  scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}97  scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK.98  scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}99}100 101void unscopedUnspecifiedCStyle() {102  unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}103  unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK.104  unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK.105  unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}106  unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}107  unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}108  unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK.109  unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK.110  unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}111  unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK.112  unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}113}114 115void unscopedSpecifiedCStyle() {116  unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}117  unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK.118  unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK.119  unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}120  unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}121  unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}122  unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK.123  unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK.124  unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}125  unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK.126  unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}127}128 129void scopedUnspecifiedCStyle() {130  scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}131  scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK.132  scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK.133  scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}134  scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}135  scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}136  scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK.137  scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK.138  scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}139  scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK.140  scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}141}142 143void scopedSpecifiedCStyle() {144  scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}145  scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK.146  scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK.147  scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}148  scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}149  scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}150  scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK.151  scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK.152  scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}153  scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK.154  scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}155}156 157unscoped_unspecified_t unused;158void unusedExpr() {159  // following line is not something that EnumCastOutOfRangeChecker should evaluate.  checker should either ignore this line160  // or process it without producing any warnings.  However, compilation will (and should) still generate a warning having161  // nothing to do with this checker.162  unused; // expected-warning {{expression result unused}}163}164 165void rangeConstrained1(int input) {166  if (input > -5 && input < 5)167    auto value = static_cast<scoped_specified_t>(input); // OK. Being conservative, this is a possibly good value.168}169 170void rangeConstrained2(int input) {171  if (input < -5)172    auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}173}174 175void rangeConstrained3(int input) {176  if (input >= -2 && input <= -1)177    auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}178}179 180void rangeConstrained4(int input) {181  if (input >= -2 && input <= 1)182    auto value = static_cast<scoped_specified_t>(input); // OK. Possibly 1.183}184 185void rangeConstrained5(int input) {186  if (input >= 1 && input <= 2)187    auto value = static_cast<scoped_specified_t>(input); // OK. Strict inner matching.188}189 190void rangeConstrained6(int input) {191  if (input >= 2 && input <= 4)192    auto value = static_cast<scoped_specified_t>(input); // OK. The value is possibly 2 or 4, dont warn.193}194 195void rangeConstrained7(int input) {196  if (input >= 3 && input <= 3)197    auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}198}199 200void enumBitFieldAssignment() {201  S s;202  s.E = static_cast<unscoped_unspecified_t>(4); // OK.203  s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}204}205 206 207enum class empty_unspecified {};208 209enum class empty_specified: char {};210 211enum class empty_specified_unsigned: unsigned char {};212 213void ignore_unused(...);214 215void empty_enums_init_with_zero_should_not_warn() {216  auto eu = static_cast<empty_unspecified>(0); //should always be OK to zero initialize any enum217  auto ef = static_cast<empty_specified>(0);218  auto efu = static_cast<empty_specified_unsigned>(0);219 220  ignore_unused(eu, ef, efu);221}222 223//Test the example from checkers.rst:224enum WidgetKind { A=1, B, C, X=99 }; // expected-note {{enum declared here}}225 226void foo() {227  WidgetKind c = static_cast<WidgetKind>(3);  // OK228  WidgetKind x = static_cast<WidgetKind>(99); // OK229  WidgetKind d = static_cast<WidgetKind>(4);  // expected-warning {{The value '4' provided to the cast expression is not in the valid range of values for 'WidgetKind'}}230 231  ignore_unused(c, x, d);232}233 234enum [[clang::flag_enum]] FlagEnum {235  FE_BIT_1 = 1 << 0,236  FE_BIT_2 = 1 << 1,237  FE_BIT_3 = 1 << 2,238};239 240void testFlagEnum_gh_76208(void) {241  FlagEnum First2BitsSet = (FlagEnum)(FE_BIT_1 | FE_BIT_2); // no-warning: Enums with the attribute 'flag_enum' are not checked242  (void)First2BitsSet;243}244