1 | // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s |
2 | |
3 | void clang_analyzer_eval(bool); |
4 | |
5 | bool PR14634(int x) { |
6 | double y = (double)x; |
7 | return !y; |
8 | } |
9 | |
10 | bool PR14634_implicit(int x) { |
11 | double y = (double)x; |
12 | return y; |
13 | } |
14 | |
15 | void intAsBoolAsSwitchCondition(int c) { |
16 | switch ((bool)c) { // expected-warning {{switch condition has boolean value}} |
17 | case 0: |
18 | break; |
19 | } |
20 | |
21 | switch ((int)(bool)c) { // no-warning |
22 | case 0: |
23 | break; |
24 | } |
25 | } |
26 | |
27 | int *&castToIntPtrLValueRef(char *p) { |
28 | return (int *&)*(int *)p; |
29 | } |
30 | bool testCastToIntPtrLValueRef(char *p, int *s) { |
31 | return castToIntPtrLValueRef(p) != s; // no-crash |
32 | } |
33 | |
34 | int *&&castToIntPtrRValueRef(char *p) { |
35 | return (int *&&)*(int *)p; |
36 | } |
37 | bool testCastToIntPtrRValueRef(char *p, int *s) { |
38 | return castToIntPtrRValueRef(p) != s; // no-crash |
39 | } |
40 | |
41 | bool retrievePointerFromBoolean(int *p) { |
42 | bool q; |
43 | *reinterpret_cast<int **>(&q) = p; |
44 | return q; |
45 | } |
46 | |
47 | namespace base_to_derived { |
48 | struct A {}; |
49 | struct B : public A{}; |
50 | |
51 | void foo(A* a) { |
52 | B* b = (B* ) a; |
53 | A* a2 = (A *) b; |
54 | clang_analyzer_eval(a2 == a); // expected-warning{{TRUE}} |
55 | } |
56 | } |
57 | |
58 | namespace base_to_derived_double_inheritance { |
59 | struct A { |
60 | int x; |
61 | }; |
62 | struct B { |
63 | int y; |
64 | }; |
65 | struct C : A, B {}; |
66 | |
67 | void foo(B *b) { |
68 | C *c = (C *)b; |
69 | b->y = 1; |
70 | clang_analyzer_eval(c->x); // expected-warning{{UNKNOWN}} |
71 | clang_analyzer_eval(c->y); // expected-warning{{TRUE}} |
72 | } |
73 | } // namespace base_to_derived_double_inheritance |
74 | |
75 | namespace base_to_derived_opaque_class { |
76 | class NotInt { |
77 | public: |
78 | operator int() { return !x; } // no-crash |
79 | int x; |
80 | }; |
81 | |
82 | typedef struct Opaque *OpaqueRef; |
83 | typedef void *VeryOpaqueRef; |
84 | |
85 | class Transparent { |
86 | public: |
87 | int getNotInt() { return NI; } |
88 | NotInt NI; |
89 | }; |
90 | |
91 | class SubTransparent : public Transparent {}; |
92 | |
93 | SubTransparent *castToDerived(Transparent *TRef) { |
94 | return (SubTransparent *)TRef; |
95 | } |
96 | |
97 | void foo(OpaqueRef ORef) { |
98 | castToDerived(reinterpret_cast<Transparent *>(ORef))->getNotInt(); |
99 | } |
100 | |
101 | void foo(VeryOpaqueRef ORef) { |
102 | castToDerived(reinterpret_cast<Transparent *>(ORef))->getNotInt(); |
103 | } |
104 | } // namespace base_to_derived_opaque_class |
105 | |
106 | namespace bool_to_nullptr { |
107 | struct S { |
108 | int *a[1]; |
109 | bool b; |
110 | }; |
111 | void foo(S s) { |
112 | s.b = true; |
113 | for (int i = 0; i < 2; ++i) |
114 | (void)(s.a[i] != nullptr); // no-crash |
115 | } |
116 | } // namespace bool_to_nullptr |
117 | |