1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
3 #include "Inputs/system-header-simulator-cxx.h"
5 void clang_analyzer_eval(bool);
6 void clang_analyzer_checkInlined(bool);
8 // A simplified version of std::move.
11 return static_cast<T &&>(obj);
22 *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
30 void testCopyConstructor() {
35 clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
38 struct NonPODIntWrapper {
44 void testNonPODCopyConstructor() {
48 NonPODIntWrapper b(a);
49 clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
53 namespace ConstructorVirtualCalls {
56 int *out1, *out2, *out3;
58 virtual int get() { return 1; }
67 virtual int get() { return 2; }
69 B(int *out1, int *out2) : A(out1) {
76 virtual int get() { return 3; }
78 C(int *out1, int *out2, int *out3) : B(out1, out2) {
87 clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
88 clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
89 clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
91 clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
93 // Sanity check for devirtualization.
95 clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
99 namespace TemporaryConstructor {
103 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
110 // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined.
111 if (BoolWrapper().value)
117 namespace ConstructorUsedAsRValue {
118 using TemporaryConstructor::BoolWrapper;
120 bool extractValue(BoolWrapper b) {
125 bool result = extractValue(BoolWrapper());
126 clang_analyzer_eval(result); // expected-warning{{TRUE}}
130 namespace PODUninitialized {
146 NonPOD(const NonPOD &Other)
147 : x(Other.x), y(Other.y) // expected-warning {{undefined}}
150 NonPOD(NonPOD &&Other)
151 : x(Other.x), y(Other.y) // expected-warning {{undefined}}
155 NonPOD &operator=(const NonPOD &Other)
158 y = Other.y; // expected-warning {{undefined}}
161 NonPOD &operator=(NonPOD &&Other)
164 y = Other.y; // expected-warning {{undefined}}
169 class NonPODWrapper {
176 Inner(const Inner &Other)
177 : x(Other.x), y(Other.y) // expected-warning {{undefined}}
181 : x(Other.x), y(Other.y) // expected-warning {{undefined}}
185 Inner &operator=(const Inner &Other)
187 x = Other.x; // expected-warning {{undefined}}
191 Inner &operator=(Inner &&Other)
193 x = Other.x; // expected-warning {{undefined}}
205 POD p2 = p; // no-warning
206 clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
207 POD p3 = move(p); // no-warning
208 clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
210 // Use rvalues as well.
211 clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}
215 PODWrapper w2 = w; // no-warning
216 clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
217 PODWrapper w3 = move(w); // no-warning
218 clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
220 // Use rvalues as well.
221 clang_analyzer_eval(PODWrapper(w3).p.y == 1); // expected-warning{{TRUE}}
230 void testNonPODMove() {
236 void testNonPODWrapper() {
239 NonPODWrapper w2 = w;
242 void testNonPODWrapperMove() {
245 NonPODWrapper w2 = move(w);
248 // Not strictly about constructors, but trivial assignment operators should
249 // essentially work the same way.
250 namespace AssignmentOperator {
255 p2 = p; // no-warning
256 clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
258 p3 = move(p); // no-warning
259 clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
264 w2 = w; // no-warning
265 clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
267 w3 = move(w); // no-warning
268 clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
271 void testReturnValue() {
275 clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}}
280 clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}}
290 void testNonPODMove() {
297 void testNonPODWrapper() {
304 void testNonPODWrapperMove() {
313 namespace ArrayMembers {
318 void testPrimitive() {
319 Primitive a = { { 1, 2, 3 } };
321 clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}}
322 clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}}
323 clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}}
327 clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}}
328 clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}}
329 clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}}
334 clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}}
335 clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}}
336 clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}}
339 struct NestedPrimitive {
343 void testNestedPrimitive() {
344 NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } };
346 clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}}
347 clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}}
348 clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}}
350 NestedPrimitive b = a;
352 clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}}
353 clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}}
354 clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}}
359 clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}}
360 clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}}
361 clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}}
365 IntWrapper values[3];
369 POD a = { { { 1 }, { 2 }, { 3 } } };
371 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
372 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
373 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
377 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}}
378 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}}
379 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}}
384 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}}
385 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}}
386 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}}
390 IntWrapper values[2][3];
393 void testNestedPOD() {
394 NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } };
396 clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
397 clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
398 clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
402 clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}}
403 clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}}
404 clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}}
409 clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}}
410 clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}}
411 clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}}
415 NonPODIntWrapper values[3];
424 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
425 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
426 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
430 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
431 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
432 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}
437 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
438 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
439 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
442 struct NestedNonPOD {
443 NonPODIntWrapper values[2][3];
446 void testNestedNonPOD() {
448 a.values[0][0].x = 0;
449 a.values[0][1].x = 0;
450 a.values[0][2].x = 0;
451 a.values[1][0].x = 1;
452 a.values[1][1].x = 2;
453 a.values[1][2].x = 3;
455 clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}}
456 clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}}
457 clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}}
461 clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
462 clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
463 clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
468 clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}}
469 clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}}
470 clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}}
473 struct NonPODDefaulted {
474 NonPODIntWrapper values[3];
476 NonPODDefaulted() = default;
477 NonPODDefaulted(const NonPODDefaulted &) = default;
478 NonPODDefaulted &operator=(const NonPODDefaulted &) = default;
481 void testNonPODDefaulted() {
487 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}}
488 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}}
489 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}}
491 NonPODDefaulted b = a;
493 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}}
494 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}}
495 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}}
500 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}}
501 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}}
502 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
506 namespace VirtualInheritance {
515 struct virtual_subclass : public virtual base {
516 virtual_subclass() {}
519 struct double_subclass : public virtual_subclass {
526 clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
529 struct double_virtual_subclass : public virtual virtual_subclass {
530 double_virtual_subclass() {}
535 double_virtual_subclass obj;
536 clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}}
540 namespace ZeroInitialization {
548 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
549 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
552 void testTemporary() {
553 clang_analyzer_eval(raw_pair().p1 == 0); // expected-warning{{TRUE}}
554 clang_analyzer_eval(raw_pair().p2 == 0); // expected-warning{{TRUE}}
559 clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}}
560 clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}}
561 clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}}
562 clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}}
566 // FIXME: Pending proper implementation of constructors for 'new'.
567 raw_pair *pp = new raw_pair();
568 clang_analyzer_eval(pp->p1 == 0); // expected-warning{{UNKNOWN}}
569 clang_analyzer_eval(pp->p2 == 0); // expected-warning{{UNKNOWN}}
572 void testArrayNew() {
573 // FIXME: Pending proper implementation of constructors for 'new[]'.
574 raw_pair *p = new raw_pair[2]();
575 clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{UNKNOWN}}
576 clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{UNKNOWN}}
577 clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{UNKNOWN}}
578 clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{UNKNOWN}}
581 struct initializing_pair {
585 initializing_pair() : x(), y() {}
588 void testFieldInitializers() {
590 clang_analyzer_eval(p.x == 0); // expected-warning{{TRUE}}
591 clang_analyzer_eval(p.y.p1 == 0); // expected-warning{{TRUE}}
592 clang_analyzer_eval(p.y.p2 == 0); // expected-warning{{TRUE}}
595 struct subclass : public raw_pair {
596 subclass() = default;
599 void testSubclass() {
601 clang_analyzer_eval(p.p1 == 0); // expected-warning{{garbage}}
604 struct initializing_subclass : public raw_pair {
605 initializing_subclass() : raw_pair() {}
608 void testInitializingSubclass() {
609 initializing_subclass p;
610 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
611 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
614 struct pair_wrapper {
615 pair_wrapper() : p() {}
619 struct virtual_subclass : public virtual pair_wrapper {
620 virtual_subclass() {}
623 struct double_virtual_subclass : public virtual_subclass {
624 double_virtual_subclass() {
625 // This previously caused a crash because the pair_wrapper subobject was
626 // initialized twice.
635 class PairContainer : public Empty {
638 PairContainer() : Empty(), p() {
639 // This previously caused a crash because the empty base class looked
640 // like an initialization of 'p'.
642 PairContainer(int) : Empty(), p() {
643 // Test inlining something else here.
647 class PairContainerContainer {
651 PairContainerContainer() : pc(1) {}
655 namespace InitializerList {
657 bool usedInitializerList;
659 List() : usedInitializerList(false) {}
660 List(std::initializer_list<int>) : usedInitializerList(true) {}
665 clang_analyzer_eval(!defaultCtor.usedInitializerList); // expected-warning{{TRUE}}
668 clang_analyzer_eval(list.usedInitializerList); // expected-warning{{TRUE}}
672 List *list = new List{1, 2};
673 // FIXME: When we handle constructors with 'new', this will be TRUE.
674 clang_analyzer_eval(list->usedInitializerList); // expected-warning{{UNKNOWN}}