1 | // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.ExprInspection %s |
2 | |
3 | void clang_analyzer_eval(bool); |
4 | |
5 | enum class Foo { |
6 | Zero |
7 | }; |
8 | |
9 | bool pr15703(int x) { |
10 | return Foo::Zero == (Foo)x; // don't crash |
11 | } |
12 | |
13 | void testCasting(int i) { |
14 | Foo f = static_cast<Foo>(i); |
15 | int j = static_cast<int>(f); |
16 | if (i == 0) |
17 | { |
18 | clang_analyzer_eval(f == Foo::Zero); // expected-warning{{TRUE}} |
19 | clang_analyzer_eval(j == 0); // expected-warning{{TRUE}} |
20 | } |
21 | else |
22 | { |
23 | clang_analyzer_eval(f == Foo::Zero); // expected-warning{{FALSE}} |
24 | clang_analyzer_eval(j == 0); // expected-warning{{FALSE}} |
25 | } |
26 | } |
27 | |
28 | enum class EnumBool : bool { |
29 | F = false, |
30 | T = true |
31 | }; |
32 | |
33 | bool testNoCrashOnSwitchEnumBool(EnumBool E) { |
34 | switch (E) { |
35 | case EnumBool::F: |
36 | return false; |
37 | } |
38 | return true; |
39 | } |
40 | |
41 | bool testNoCrashOnSwitchEnumBoolConstant() { |
42 | EnumBool E = EnumBool::F; |
43 | switch (E) { |
44 | case EnumBool::F: |
45 | return false; |
46 | } |
47 | return true; |
48 | } |
49 | |
50 | typedef __INTPTR_TYPE__ intptr_t; |
51 | bool testNoCrashOnSwitchEnumBoolConstantCastedFromNullptr() { |
52 | EnumBool E = static_cast<EnumBool>((intptr_t)nullptr); |
53 | switch (E) { |
54 | case EnumBool::F: |
55 | return false; |
56 | } |
57 | return true; |
58 | } |
59 | |
60 | bool testNoCrashOnSwitchEnumBoolConstantCastedFromPtr() { |
61 | int X; |
62 | intptr_t P = (intptr_t)&X; |
63 | EnumBool E = static_cast<EnumBool>(P); |
64 | switch (E) { |
65 | case EnumBool::F: |
66 | return false; |
67 | } |
68 | return true; |
69 | } |
70 | |