• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()11 A::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()24 void 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()40 void 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()52 void 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()64 void testReferenceMember() {
65   int *p = 0;
66   RefWrapper X(p); // expected-warning@-7 {{Dereference of null pointer}}
67 }
68 
testReferenceMember2()69 void 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