1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s 2 3 void clang_analyzer_eval(bool); 4 5 #include "Inputs/system-header-simulator-cxx.h" 6 7 class A { 8 int x; 9 public: 10 A(); 11 }; 12 13 A::A() : x(0) { 14 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 15 } 16 17 18 class DirectMember { 19 int x; 20 public: 21 DirectMember(int value) : x(value) {} 22 23 int getX() { return x; } 24 }; 25 26 void testDirectMember() { 27 DirectMember obj(3); 28 clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}} 29 } 30 31 32 class IndirectMember { 33 struct { 34 int x; 35 }; 36 public: 37 IndirectMember(int value) : x(value) {} 38 39 int getX() { return x; } 40 }; 41 42 void testIndirectMember() { 43 IndirectMember obj(3); 44 clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}} 45 } 46 47 48 struct DelegatingConstructor { 49 int x; 50 DelegatingConstructor(int y) { x = y; } 51 DelegatingConstructor() : DelegatingConstructor(42) {} 52 }; 53 54 void testDelegatingConstructor() { 55 DelegatingConstructor obj; 56 clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}} 57 } 58 59 60 struct RefWrapper { 61 RefWrapper(int *p) : x(*p) {} 62 RefWrapper(int &r) : x(r) {} 63 int &x; 64 }; 65 66 void testReferenceMember() { 67 int *p = 0; 68 RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}} 69 } 70 71 void testReferenceMember2() { 72 int *p = 0; 73 RefWrapper X(*p); // expected-warning {{Forming reference to null pointer}} 74 } 75 76 77 extern "C" char *strdup(const char *); 78 79 class StringWrapper { 80 char *str; 81 public: 82 StringWrapper(const char *input) : str(strdup(input)) {} // no-warning 83 }; 84 85 86 // PR15070 - Constructing a type containing a non-POD array mistakenly 87 // tried to perform a bind instead of relying on the CXXConstructExpr, 88 // which caused a cast<> failure in RegionStore. 89 namespace DefaultConstructorWithCleanups { 90 class Element { 91 public: 92 int value; 93 94 class Helper { 95 public: 96 ~Helper(); 97 }; 98 Element(Helper h = Helper()); 99 }; 100 class Wrapper { 101 public: 102 Element arr[2]; 103 104 Wrapper(); 105 }; 106 107 Wrapper::Wrapper() /* initializers synthesized */ {} 108 109 int test() { 110 Wrapper w; 111 return w.arr[0].value; // no-warning 112 } 113 } 114 115 namespace DefaultMemberInitializers { 116 struct Wrapper { 117 int value = 42; 118 119 Wrapper() {} 120 Wrapper(int x) : value(x) {} 121 Wrapper(bool) {} 122 }; 123 124 void test() { 125 Wrapper w1; 126 clang_analyzer_eval(w1.value == 42); // expected-warning{{TRUE}} 127 128 Wrapper w2(50); 129 clang_analyzer_eval(w2.value == 50); // expected-warning{{TRUE}} 130 131 Wrapper w3(false); 132 clang_analyzer_eval(w3.value == 42); // expected-warning{{TRUE}} 133 } 134 135 struct StringWrapper { 136 const char s[4] = "abc"; 137 const char *p = "xyz"; 138 139 StringWrapper(bool) {} 140 }; 141 142 void testString() { 143 StringWrapper w(true); 144 clang_analyzer_eval(w.s[1] == 'b'); // expected-warning{{TRUE}} 145 clang_analyzer_eval(w.p[1] == 'y'); // expected-warning{{TRUE}} 146 } 147 } 148 149 namespace ReferenceInitialization { 150 struct OtherStruct { 151 OtherStruct(int i); 152 ~OtherStruct(); 153 }; 154 155 struct MyStruct { 156 MyStruct(int i); 157 MyStruct(OtherStruct os); 158 159 void method() const; 160 }; 161 162 void referenceInitializeLocal() { 163 const MyStruct &myStruct(5); 164 myStruct.method(); // no-warning 165 } 166 167 void referenceInitializeMultipleLocals() { 168 const MyStruct &myStruct1(5), myStruct2(5), &myStruct3(5); 169 myStruct1.method(); // no-warning 170 myStruct2.method(); // no-warning 171 myStruct3.method(); // no-warning 172 } 173 174 void referenceInitializeLocalWithCleanup() { 175 const MyStruct &myStruct(OtherStruct(5)); 176 myStruct.method(); // no-warning 177 } 178 179 struct HasMyStruct { 180 const MyStruct &ms; // expected-note {{reference member declared here}} 181 const MyStruct &msWithCleanups; // expected-note {{reference member declared here}} 182 183 // clang's Sema issues a warning when binding a reference member to a 184 // temporary value. 185 HasMyStruct() : ms(5), msWithCleanups(OtherStruct(5)) { 186 // expected-warning@-1 {{binding reference member 'ms' to a temporary value}} 187 // expected-warning@-2 {{binding reference member 'msWithCleanups' to a temporary value}} 188 189 // At this point the members are not garbage so we should not expect an 190 // analyzer warning here even though binding a reference member 191 // to a member is a terrible idea. 192 ms.method(); // no-warning 193 msWithCleanups.method(); // no-warning 194 } 195 }; 196 197 void referenceInitializeField() { 198 HasMyStruct hms; 199 } 200 201 }; 202 203 namespace PR31592 { 204 struct C { 205 C() : f("}") { } // no-crash 206 const char(&f)[2]; 207 }; 208 } 209 210 namespace CXX_initializer_lists { 211 struct C { 212 C(std::initializer_list<int *> list); 213 }; 214 void foo() { 215 C empty{}; // no-crash 216 217 // Do not warn that 'x' leaks. It might have been deleted by 218 // the destructor of 'c'. 219 int *x = new int; 220 C c{x}; // no-warning 221 } 222 } 223