1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
3 template <class T
> void clang_analyzer_dump(T
);
4 void clang_analyzer_eval(bool);
6 void usePointer(int * const *);
7 void useReference(int * const &);
15 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
17 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
21 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
23 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
27 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
29 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
33 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
35 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
43 void useStruct(Wrapper
&w
);
44 void useConstStruct(const Wrapper
&w
);
46 void testPointerStruct() {
52 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
54 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
58 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
60 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
68 void useStruct(RefWrapper
&w
);
69 void useConstStruct(const RefWrapper
&w
);
71 void testReferenceStruct() {
76 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
78 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
81 // FIXME: This test is split into two functions because region invalidation
82 // does not preserve reference bindings.
83 void testConstReferenceStruct() {
88 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
90 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
94 int usePointerPure(int * const *) __attribute__((pure
));
95 int usePointerConst(int * const *) __attribute__((const));
97 void testPureConst() {
105 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
106 clang_analyzer_eval(global
== -5); // expected-warning{{TRUE}}
108 (void)usePointerPure(&p
);
109 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
110 clang_analyzer_eval(global
== -5); // expected-warning{{TRUE}}
112 (void)usePointerConst(&p
);
113 clang_analyzer_eval(x
== 42); // expected-warning{{TRUE}}
114 clang_analyzer_eval(global
== -5); // expected-warning{{TRUE}}
117 clang_analyzer_eval(x
== 42); // expected-warning{{UNKNOWN}}
118 clang_analyzer_eval(global
== -5); // expected-warning{{UNKNOWN}}
129 void useAnything(void *);
130 void useAnythingConst(const void *);
132 void testInvalidationThroughBaseRegionPointer() {
136 clang_analyzer_eval(s1
.x
== 1); // expected-warning{{TRUE}}
137 clang_analyzer_eval(s1
.z
== 1); // expected-warning{{TRUE}}
138 // Not only passing a structure pointer through const pointer parameter,
139 // but also passing a field pointer through const pointer parameter
140 // should preserve the contents of the structure.
141 useAnythingConst(&(s1
.y
));
142 clang_analyzer_eval(s1
.x
== 1); // expected-warning{{TRUE}}
143 // FIXME: Should say "UNKNOWN", because it is not uncommon to
144 // modify a mutable member variable through const pointer.
145 clang_analyzer_eval(s1
.z
== 1); // expected-warning{{TRUE}}
146 useAnything(&(s1
.y
));
147 clang_analyzer_eval(s1
.x
== 1); // expected-warning{{UNKNOWN}}
151 void useFirstConstSecondNonConst(const void *x
, void *y
);
152 void useFirstNonConstSecondConst(void *x
, const void *y
);
154 void testMixedConstNonConstCalls() {
157 useFirstConstSecondNonConst(&(s2
.x
), &(s2
.y
));
158 clang_analyzer_eval(s2
.x
== 1); // expected-warning{{UNKNOWN}}
160 useFirstNonConstSecondConst(&(s2
.x
), &(s2
.y
));
161 clang_analyzer_eval(s2
.x
== 1); // expected-warning{{UNKNOWN}}
163 useFirstConstSecondNonConst(&(s2
.x
), &(s2
.y
));
164 clang_analyzer_eval(s2
.y
== 1); // expected-warning{{UNKNOWN}}
166 useFirstNonConstSecondConst(&(s2
.x
), &(s2
.y
));
167 clang_analyzer_eval(s2
.y
== 1); // expected-warning{{UNKNOWN}}
178 struct StdWrappingOpaque
{
179 std::Opaque o
; // first member
182 struct StdWrappingOpaqueSwapped
{
183 int uninit
; // first member
187 int testStdCtorDoesNotInvalidateParentObject() {
188 StdWrappingOpaque obj
;
189 int x
= obj
.o
.nested_member
; // no-garbage: std::Opaque::ctor might initialized this
190 int y
= obj
.uninit
; // FIXME: We should have a garbage read here. Read the details.
191 // As the first member ("obj.o") is invalidated, a conjured default binding is bound
192 // to the offset 0 within cluster "obj", and this masks every uninitialized fields
193 // that follows. We need a better store with extents to fix this.
197 int testStdCtorDoesNotInvalidateParentObjectSwapped() {
198 StdWrappingOpaqueSwapped obj
;
199 int x
= obj
.o
.nested_member
; // no-garbage: std::Opaque::ctor might initialized this
200 int y
= obj
.uninit
; // expected-warning {{Assigned value is garbage or undefined}}
204 class UserProvidedOpaque
{
206 UserProvidedOpaque(); // might reinterpret_cast(this)
210 struct WrappingUserProvidedOpaque
{
211 UserProvidedOpaque o
; // first member
214 struct WrappingUserProvidedOpaqueSwapped
{
215 int uninit
; // first member
216 UserProvidedOpaque o
;
219 int testUserProvidedCtorInvalidatesParentObject() {
220 WrappingUserProvidedOpaque obj
;
221 int x
= obj
.o
.nested_member
; // no-garbage: UserProvidedOpaque::ctor might initialized this
222 int y
= obj
.uninit
; // no-garbage: UserProvidedOpaque::ctor might reinterpret_cast(this) and write to the "uninit" member.
226 int testUserProvidedCtorInvalidatesParentObjectSwapped() {
227 WrappingUserProvidedOpaqueSwapped obj
;
228 int x
= obj
.o
.nested_member
; // no-garbage: same as above
229 int y
= obj
.uninit
; // no-garbage: same as above
233 struct WrappingStdWrappingOpaqueOuterInits
{
237 WrappingStdWrappingOpaqueOuterInits() {
238 clang_analyzer_dump(first
); // expected-warning {{1 S32b}}
239 clang_analyzer_dump(second
.nested_member
); // expected-warning {{derived_}}
240 clang_analyzer_dump(third
); // expected-warning {{3 S32b}}
244 struct WrappingUserProvidedOpaqueOuterInits
{
245 int first
= 1; // Potentially overwritten by UserProvidedOpaque::ctor
246 UserProvidedOpaque second
; // Invalidates the object so far.
247 int third
= 3; // Happens after UserProvidedOpaque::ctor, thus preserved!
248 WrappingUserProvidedOpaqueOuterInits() {
249 clang_analyzer_dump(first
); // expected-warning {{derived_}}
250 clang_analyzer_dump(second
.nested_member
); // expected-warning {{derived_}}
251 clang_analyzer_dump(third
); // expected-warning {{3 S32b}}
257 inline namespace v1
{
258 namespace custom_ranges
{
265 }; // struct iterator
267 } // namespace custom_ranges
272 struct StdWrappingFancyOpaque
{
274 std::custom_ranges::Fancy::iterator::Opaque o
;
277 int testNestedStdNamespacesAndRecords() {
278 StdWrappingFancyOpaque obj
;
279 int x
= obj
.o
.nested_member
; // no-garbage: ctor
280 int y
= obj
.uninit
; // expected-warning {{Assigned value is garbage or undefined}}