1 // RUN: %clang_analyze_cc1 -std=c++11 %s \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-checker=cplusplus.NewDelete \
4 // RUN:   -analyzer-checker=alpha.cplusplus.PlacementNew \
5 // RUN:   -analyzer-output=text -verify \
6 // RUN:   -triple x86_64-unknown-linux-gnu
7 
8 #include "Inputs/system-header-simulator-cxx.h"
9 
f()10 void f() {
11   short s;                    // expected-note {{'s' declared without an initial value}}
12   long *lp = ::new (&s) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 3 {{}}
13   (void)lp;
14 }
15 
16 namespace testArrayNew {
f()17 void f() {
18   short s;                        // expected-note {{'s' declared without an initial value}}
19   char *buf = ::new (&s) char[8]; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 3 {{}}
20   (void)buf;
21 }
22 } // namespace testArrayNew
23 
24 namespace testBufferInOtherFun {
f(void * place)25 void f(void *place) {
26   long *lp = ::new (place) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
27   (void)lp;
28 }
g()29 void g() {
30   short buf; // expected-note {{'buf' declared without an initial value}}
31   f(&buf);   // expected-note 2 {{}}
32 }
33 } // namespace testBufferInOtherFun
34 
35 namespace testArrayBuffer {
f(void * place)36 void f(void *place) {
37   long *lp = ::new (place) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
38   (void)lp;
39 }
g()40 void g() {
41   char buf[2]; // expected-note {{'buf' initialized here}}
42   f(&buf);     // expected-note 2 {{}}
43 }
44 } // namespace testArrayBuffer
45 
46 namespace testGlobalPtrAsPlace {
47 void *gptr = nullptr;
48 short gs;
f()49 void f() {
50   gptr = &gs; // expected-note {{Value assigned to 'gptr'}}
51 }
g()52 void g() {
53   f();                          // expected-note 2 {{}}
54   long *lp = ::new (gptr) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
55   (void)lp;
56 }
57 } // namespace testGlobalPtrAsPlace
58 
59 namespace testRvalue {
60 short gs;
f()61 void *f() {
62   return &gs;
63 }
g()64 void g() {
65   long *lp = ::new (f()) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
66   (void)lp;
67 }
68 } // namespace testRvalue
69 
70 namespace testNoWarning {
71 void *f();
g()72 void g() {
73   long *lp = ::new (f()) long;
74   (void)lp;
75 }
76 } // namespace testNoWarning
77 
78 namespace testPtrToArrayAsPlace {
f()79 void f() {
80   //char *st = new char [8];
81   char buf[3];                // expected-note {{'buf' initialized here}}
82   void *st = buf;             // expected-note {{'st' initialized here}}
83   long *lp = ::new (st) long; // expected-warning{{Storage provided to placement new is only 3 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
84   (void)lp;
85 }
86 } // namespace testPtrToArrayAsPlace
87 
88 namespace testPtrToArrayWithOffsetAsPlace {
f()89 void f() {
90   int buf[3];                      // expected-note {{'buf' initialized here}}
91   long *lp = ::new (buf + 2) long; // expected-warning{{Storage provided to placement new is only 4 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
92   (void)lp;
93 }
94 } // namespace testPtrToArrayWithOffsetAsPlace
95 
96 namespace testHeapAllocatedBuffer {
g2()97 void g2() {
98   char *buf = new char[2];     // expected-note {{'buf' initialized here}}
99   long *lp = ::new (buf) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
100   (void)lp;
101 }
102 } // namespace testHeapAllocatedBuffer
103 
104 namespace testMultiDimensionalArray {
f()105 void f() {
106   char buf[2][3];              // expected-note {{'buf' initialized here}}
107   long *lp = ::new (buf) long; // expected-warning{{Storage provided to placement new is only 6 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
108   (void)lp;
109 }
110 } // namespace testMultiDimensionalArray
111 
112 namespace testMultiDimensionalArray2 {
f()113 void f() {
114   char buf[2][3];                  // expected-note {{'buf' initialized here}}
115   long *lp = ::new (buf + 1) long; // expected-warning{{Storage provided to placement new is only 3 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
116   (void)lp;
117 }
118 } // namespace testMultiDimensionalArray2
119 
120 namespace testMultiDimensionalArray3 {
f()121 void f() {
122   char buf[2][3];                     // expected-note {{'buf' initialized here}}
123   long *lp = ::new (&buf[1][1]) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
124   (void)lp;
125 }
126 } // namespace testMultiDimensionalArray3
127 
128 namespace testHierarchy {
129 struct Base {
130   char a[2];
131 };
132 struct Derived : Base {
133   char x[2];
134   int y;
135 };
f()136 void f() {
137   Base b;                           // expected-note {{'b' initialized here}}
138   Derived *dp = ::new (&b) Derived; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
139   (void)dp;
140 }
141 } // namespace testHierarchy
142