xref: /llvm-project/clang/test/Analysis/enum-cast-out-of-range.c (revision c873f77e87a9ebd02f94d6b9d46e84d43e1ceb38)
1 // RUN: %clang_analyze_cc1 \
2 // RUN:   -analyzer-checker=core,optin.core.EnumCastOutOfRange \
3 // RUN:   -analyzer-output text \
4 // RUN:   -verify %s
5 
6 // expected-note@+1 + {{enum declared here}}
7 enum En_t {
8   En_0 = -4,
9   En_1,
10   En_2 = 1,
11   En_3,
12   En_4 = 4
13 };
14 
unscopedUnspecifiedCStyle(void)15 void 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 
35 enum En_t unused;
unusedExpr(void)36 void unusedExpr(void) {
37   // Following line is not something that EnumCastOutOfRangeChecker should
38   // evaluate.  Checker should either ignore this line or process it without
39   // producing any warnings.  However, compilation will (and should) still
40   // generate a warning having nothing to do with this checker.
41   unused; // expected-warning {{expression result unused}}
42 }
43 
44 // Test typedef-ed anonymous enums
45 typedef enum { // expected-note {{enum declared here}}
46     TD_0 = 0,
47 } TD_t;
48 
testTypeDefEnum(void)49 void 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 tracking
set(int * p,int v)55 void set(int* p, int v) {
56   *p = v; // expected-note {{The value -1 is assigned to 'i'}}
57 }
58 
59 
testTrackExpression(int i)60 void 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