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