78 lines · c
1// RUN: %clang_analyze_cc1 \2// RUN: -analyzer-checker=core,optin.core.EnumCastOutOfRange \3// RUN: -analyzer-output text \4// RUN: -verify %s5 6// expected-note@+1 + {{enum declared here}}7enum En_t {8 En_0 = -4,9 En_1,10 En_2 = 1,11 En_3,12 En_4 = 413};14 15void unscopedUnspecifiedCStyle(void) {16 enum En_t Below = (enum En_t)(-5); // expected-warning {{not in the valid range of values for 'En_t'}}17 // expected-note@-1 {{not in the valid range of values for 'En_t'}}18 enum En_t NegVal1 = (enum En_t)(-4); // OK.19 enum En_t NegVal2 = (enum En_t)(-3); // OK.20 enum En_t InRange1 = (enum En_t)(-2); // expected-warning {{not in the valid range of values for 'En_t'}}21 // expected-note@-1 {{not in the valid range of values for 'En_t'}}22 enum En_t InRange2 = (enum En_t)(-1); // expected-warning {{not in the valid range of values for 'En_t'}}23 // expected-note@-1 {{not in the valid range of values for 'En_t'}}24 enum En_t InRange3 = (enum En_t)(0); // expected-warning {{not in the valid range of values for 'En_t'}}25 // expected-note@-1 {{not in the valid range of values for 'En_t'}}26 enum En_t PosVal1 = (enum En_t)(1); // OK.27 enum En_t PosVal2 = (enum En_t)(2); // OK.28 enum En_t InRange4 = (enum En_t)(3); // expected-warning {{not in the valid range of values for 'En_t'}}29 // expected-note@-1 {{not in the valid range of values for 'En_t'}}30 enum En_t PosVal3 = (enum En_t)(4); // OK.31 enum En_t Above = (enum En_t)(5); // expected-warning {{not in the valid range of values for 'En_t'}}32 // expected-note@-1 {{not in the valid range of values for 'En_t'}}33}34 35enum En_t unused;36void unusedExpr(void) {37 // Following line is not something that EnumCastOutOfRangeChecker should38 // evaluate. Checker should either ignore this line or process it without39 // producing any warnings. However, compilation will (and should) still40 // generate a warning having nothing to do with this checker.41 unused; // expected-warning {{expression result unused}}42}43 44// Test typedef-ed anonymous enums45typedef enum { // expected-note {{enum declared here}}46 TD_0 = 0,47} TD_t;48 49void testTypeDefEnum(void) {50 (void)(TD_t)(-1); // expected-warning {{not in the valid range of values for the enum}}51 // expected-note@-1 {{not in the valid range of values for the enum}}52}53 54// Test expression tracking55void set(int* p, int v) {56 *p = v; // expected-note {{The value -1 is assigned to 'i'}}57}58 59 60void testTrackExpression(int i) {61 set(&i, -1); // expected-note {{Passing the value -1 via 2nd parameter 'v'}}62 // expected-note@-1 {{Calling 'set'}}63 // expected-note@-2 {{Returning from 'set'}}64 (void)(enum En_t)(i); // expected-warning {{not in the valid range of values for 'En_t'}}65 // expected-note@-1 {{not in the valid range of values for 'En_t'}}66}67 68enum __attribute__((flag_enum)) FlagEnum {69 FE_BIT_1 = 1 << 0,70 FE_BIT_2 = 1 << 1,71 FE_BIT_3 = 1 << 2,72};73 74void testFlagEnum_gh_76208(void) {75 enum FlagEnum First2BitsSet = (enum FlagEnum)(FE_BIT_1 | FE_BIT_2); // no-warning: Enums with the attribute 'flag_enum' are not checked76 (void)First2BitsSet;77}78