1 // RUN: %clang_analyze_cc1 -std=c++11 %s \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-checker=cplusplus.NewDelete \
4 // RUN:   -analyzer-checker=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 
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 {
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 {
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 }
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 {
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 }
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;
49 void f() {
50   gptr = &gs; // expected-note {{Value assigned to 'gptr'}}
51 }
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;
61 void *f() {
62   return &gs;
63 }
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();
72 void g() {
73   long *lp = ::new (f()) long;
74   (void)lp;
75 }
76 } // namespace testNoWarning
77 
78 namespace testPtrToArrayAsPlace {
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 {
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 testZeroSize {
97 void f() {
98   int buf[3];                      // expected-note {{'buf' initialized here}}
99   long *lp = ::new (buf + 3) long; // expected-warning{{Storage provided to placement new is only 0 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
100   (void)lp;
101 }
102 } // namespace testZeroSize
103 
104 namespace testNegativeSize {
105 void f() {
106   int buf[3];                      // expected-note {{'buf' initialized here}}
107   long *lp = ::new (buf + 4) long; // expected-warning{{Storage provided to placement new is only -4 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
108   (void)lp;
109 }
110 } // namespace testNegativeSize
111 
112 namespace testHeapAllocatedBuffer {
113 void g2() {
114   char *buf = new char[2];     // expected-note {{'buf' initialized here}}
115   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 {{}}
116   (void)lp;
117 }
118 } // namespace testHeapAllocatedBuffer
119 
120 namespace testMultiDimensionalArray {
121 void f() {
122   char buf[2][3];              // expected-note {{'buf' initialized here}}
123   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 {{}}
124   (void)lp;
125 }
126 } // namespace testMultiDimensionalArray
127 
128 namespace testMultiDimensionalArray2 {
129 void f() {
130   char buf[2][3];                  // expected-note {{'buf' initialized here}}
131   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 {{}}
132   (void)lp;
133 }
134 } // namespace testMultiDimensionalArray2
135 
136 namespace testMultiDimensionalArray3 {
137 void f() {
138   char buf[2][3];                     // expected-note {{'buf' initialized here}}
139   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 {{}}
140   (void)lp;
141 }
142 } // namespace testMultiDimensionalArray3
143 
144 namespace testHierarchy {
145 struct Base {
146   char a[2];
147 };
148 struct Derived : Base {
149   char x[2];
150   int y;
151 };
152 void f() {
153   Base b;                           // expected-note {{'b' initialized here}}
154   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 {{}}
155   (void)dp;
156 }
157 } // namespace testHierarchy
158