• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PR14634(int x)5 bool PR14634(int x) {
6   double y = (double)x;
7   return !y;
8 }
9 
PR14634_implicit(int x)10 bool PR14634_implicit(int x) {
11   double y = (double)x;
12   return y;
13 }
14 
intAsBoolAsSwitchCondition(int c)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 
castToIntPtrLValueRef(char * p)27 int *&castToIntPtrLValueRef(char *p) {
28   return (int *&)*(int *)p;
29 }
testCastToIntPtrLValueRef(char * p,int * s)30 bool testCastToIntPtrLValueRef(char *p, int *s) {
31   return castToIntPtrLValueRef(p) != s; // no-crash
32 }
33 
castToIntPtrRValueRef(char * p)34 int *&&castToIntPtrRValueRef(char *p) {
35   return (int *&&)*(int *)p;
36 }
testCastToIntPtrRValueRef(char * p,int * s)37 bool testCastToIntPtrRValueRef(char *p, int *s) {
38   return castToIntPtrRValueRef(p) != s; // no-crash
39 }
40 
retrievePointerFromBoolean(int * p)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 
foo(A * a)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 
foo(B * b)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:
operator int()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:
getNotInt()87   int getNotInt() { return NI; }
88   NotInt NI;
89 };
90 
91 class SubTransparent : public Transparent {};
92 
castToDerived(Transparent * TRef)93 SubTransparent *castToDerived(Transparent *TRef) {
94   return (SubTransparent *)TRef;
95 }
96 
foo(OpaqueRef ORef)97 void foo(OpaqueRef ORef) {
98   castToDerived(reinterpret_cast<Transparent *>(ORef))->getNotInt();
99 }
100 
foo(VeryOpaqueRef ORef)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 };
foo(S s)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