Artem Dergachev | 31f8139 | 2018-10-03 22:48:00 +0000 | [diff] [blame] | 1 | // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s |
Artem Dergachev | 4e864b8 | 2018-08-29 22:43:31 +0000 | [diff] [blame] | 2 | |
| 3 | void clang_analyzer_eval(bool); |
Jordan Rose | 36bc6b4 | 2013-09-18 18:58:58 +0000 | [diff] [blame] | 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 | } |
Jordan Rose | 7ae3362 | 2013-12-19 22:32:39 +0000 | [diff] [blame] | 14 | |
| 15 | void intAsBoolAsSwitchCondition(int c) { |
Jordan Rose | 821f102 | 2013-12-19 23:05:40 +0000 | [diff] [blame] | 16 | switch ((bool)c) { // expected-warning {{switch condition has boolean value}} |
Jordan Rose | 7ae3362 | 2013-12-19 22:32:39 +0000 | [diff] [blame] | 17 | case 0: |
| 18 | break; |
| 19 | } |
Jordan Rose | 821f102 | 2013-12-19 23:05:40 +0000 | [diff] [blame] | 20 | |
| 21 | switch ((int)(bool)c) { // no-warning |
| 22 | case 0: |
| 23 | break; |
| 24 | } |
Jordan Rose | 7ae3362 | 2013-12-19 22:32:39 +0000 | [diff] [blame] | 25 | } |
Artem Dergachev | 2fd6aa7 | 2018-05-04 21:39:25 +0000 | [diff] [blame] | 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 | } |
Artem Dergachev | 35dbd0b | 2018-07-17 00:42:35 +0000 | [diff] [blame] | 40 | |
| 41 | bool retrievePointerFromBoolean(int *p) { |
| 42 | bool q; |
| 43 | *reinterpret_cast<int **>(&q) = p; |
| 44 | return q; |
| 45 | } |
Artem Dergachev | 4e864b8 | 2018-08-29 22:43:31 +0000 | [diff] [blame] | 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 | } |
Artem Dergachev | 69ece33 | 2018-09-26 00:17:14 +0000 | [diff] [blame] | 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; |
Artem Dergachev | 4e864b8 | 2018-08-29 22:43:31 +0000 | [diff] [blame] | 95 | } |
| 96 | |
Artem Dergachev | 69ece33 | 2018-09-26 00:17:14 +0000 | [diff] [blame] | 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 |
Artem Dergachev | 02955af | 2018-12-22 02:06:51 +0000 | [diff] [blame] | 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 |