376 lines · cpp
1// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s2 3typedef __typeof__(sizeof(0)) size_t;4 5// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.6template<typename T> void *operator new(size_t, int (*)(T));7 8// Ensure that this declaration doesn't cause operator new to lose its9// 'noalias' attribute.10void *operator new[](size_t);11 12void t1() {13 delete new int;14 delete [] new int [3];15}16 17// CHECK: declare noundef nonnull ptr @_Znwm(i64 noundef) [[ATTR_NOBUILTIN:#[^ ]*]]18// CHECK: declare void @_ZdlPvm(ptr noundef, i64 noundef) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]19// CHECK: declare noundef nonnull ptr @_Znam(i64 noundef) [[ATTR_NOBUILTIN]]20// CHECK: declare void @_ZdaPv(ptr noundef) [[ATTR_NOBUILTIN_NOUNWIND]]21 22namespace std {23 struct nothrow_t {};24}25std::nothrow_t nothrow;26 27// Declare the reserved placement operators.28void *operator new(size_t, void*) throw();29void operator delete(void*, void*) throw();30void *operator new[](size_t, void*) throw();31void operator delete[](void*, void*) throw();32 33// Declare the replaceable global allocation operators.34void *operator new(size_t, const std::nothrow_t &) throw();35void *operator new[](size_t, const std::nothrow_t &) throw();36void operator delete(void *, const std::nothrow_t &) throw();37void operator delete[](void *, const std::nothrow_t &) throw();38 39// Declare some other placemenet operators.40void *operator new(size_t, void*, bool) throw();41void *operator new[](size_t, void*, bool) throw();42 43void t2(int* a) {44 int* b = new (a) int;45}46 47struct S {48 int a;49};50 51// POD types.52void t3() {53 int *a = new int(10);54 _Complex int* b = new _Complex int(10i);55 56 S s;57 s.a = 10;58 S *sp = new S(s);59}60 61// Non-POD62struct T {63 T();64 int a;65};66 67void t4() {68 // CHECK: call void @_ZN1TC1Ev69 T *t = new T;70}71 72struct T2 {73 int a;74 T2(int, int);75};76 77void t5() {78 // CHECK: call void @_ZN2T2C1Eii79 T2 *t2 = new T2(10, 10);80}81 82int *t6() {83 // Null check.84 return new (0) int(10);85}86 87void t7() {88 new int();89}90 91struct U {92 ~U();93};94 95void t8(int n) {96 new int[10];97 new int[n];98 99 // Non-POD100 new T[10];101 new T[n];102 103 // Cookie required104 new U[10];105 new U[n];106}107 108void t9() {109 bool b;110 111 new bool(true);112 new (&b) bool(true);113}114 115struct A {116 void* operator new(__typeof(sizeof(int)), int, float, ...);117 A();118};119 120A* t10() {121 // CHECK: @_ZN1AnwEmifz122 return new(1, 2, 3.45, 100) A;123}124 125// CHECK-LABEL: define{{.*}} void @_Z3t11i126struct B { int a; };127struct Bmemptr { int Bmemptr::* memptr; int a; };128 129void t11(int n) {130 // CHECK: call noalias noundef nonnull ptr @_Znwm131 // CHECK: call void @llvm.memset.p0.i64(132 B* b = new B();133 134 // CHECK: call noalias noundef nonnull ptr @_Znam135 // CHECK: {{call void.*llvm.memset.p0.i64.*i8 0, i64 %}}136 B *b2 = new B[n]();137 138 // CHECK: call noalias noundef nonnull ptr @_Znam139 // CHECK: call void @llvm.memcpy.p0.p0.i64140 // CHECK: br141 Bmemptr *b_memptr = new Bmemptr[n]();142 143 // CHECK: ret void144}145 146struct Empty { };147 148// We don't need to initialize an empty class.149// CHECK-LABEL: define{{.*}} void @_Z3t12v150void t12() {151 // CHECK: call noalias noundef nonnull ptr @_Znam152 // CHECK-NOT: br153 (void)new Empty[10];154 155 // CHECK: call noalias noundef nonnull ptr @_Znam156 // CHECK-NOT: br157 (void)new Empty[10]();158 159 // CHECK: ret void160}161 162// Zero-initialization163// CHECK-LABEL: define{{.*}} void @_Z3t13i164void t13(int n) {165 // CHECK: call noalias noundef nonnull ptr @_Znwm166 // CHECK: store i32 0, ptr167 (void)new int();168 169 // CHECK: call noalias noundef nonnull ptr @_Znam170 // CHECK: {{call void.*llvm.memset.p0.i64.*i8 0, i64 %}}171 (void)new int[n]();172 173 // CHECK-NEXT: ret void174}175 176struct Alloc{177 int x;178 void* operator new[](size_t size);179 __attribute__((returns_nonnull)) void *operator new[](size_t size, const std::nothrow_t &) throw();180 void operator delete[](void* p);181 ~Alloc();182};183 184void f() {185 // CHECK: call noundef ptr @_ZN5AllocnaEm(i64 noundef 808)186 // CHECK: store i64 200187 // CHECK: call void @_ZN5AllocD1Ev(188 // CHECK: call void @_ZN5AllocdaEPv(ptr189 delete[] new Alloc[10][20];190 // CHECK: [[P:%.*]] = call noundef nonnull ptr @_ZN5AllocnaEmRKSt9nothrow_t(i64 noundef 808, {{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]191 // CHECK-NOT: icmp eq ptr [[P]], null192 // CHECK: store i64 200193 delete[] new (nothrow) Alloc[10][20];194 // CHECK: call noalias noundef nonnull ptr @_Znwm195 // CHECK: call void @_ZdlPvm(ptr noundef {{%.*}}, i64 noundef 1)196 delete new bool;197 // CHECK: ret void198}199 200namespace test15 {201 struct A { A(); ~A(); };202 203 // CHECK-LABEL: define{{.*}} void @_ZN6test156test0aEPv(204 // CHECK: [[P:%.*]] = load ptr, ptr205 // CHECK-NOT: icmp eq ptr [[P]], null206 // CHECK-NOT: br i1207 // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[P]])208 void test0a(void *p) {209 new (p) A();210 }211 212 // CHECK-LABEL: define{{.*}} void @_ZN6test156test0bEPv(213 // CHECK: [[P0:%.*]] = load ptr, ptr214 // CHECK: [[P:%.*]] = call noundef ptr @_ZnwmPvb(i64 noundef 1, ptr noundef [[P0]]215 // CHECK-NEXT: icmp eq ptr [[P]], null216 // CHECK-NEXT: br i1217 // CHECK: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[P]])218 void test0b(void *p) {219 new (p, true) A();220 }221 222 // CHECK-LABEL: define{{.*}} void @_ZN6test156test1aEPv(223 // CHECK: [[P:%.*]] = load ptr, ptr224 // CHECK-NOT: icmp eq ptr [[P]], null225 // CHECK-NOT: br i1226 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A:.*]], ptr [[P]], i64 5227 // CHECK-NEXT: br label228 // CHECK: [[CUR:%.*]] = phi ptr [ [[P]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]229 // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])230 // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], ptr [[CUR]], i64 1231 // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[END]]232 // CHECK-NEXT: br i1 [[DONE]]233 void test1a(void *p) {234 new (p) A[5];235 }236 237 // CHECK-LABEL: define{{.*}} void @_ZN6test156test1bEPv(238 // CHECK: [[P0:%.*]] = load ptr, ptr239 // CHECK: [[P:%.*]] = call noundef ptr @_ZnamPvb(i64 noundef 13, ptr noundef [[P0]]240 // CHECK-NEXT: icmp eq ptr [[P]], null241 // CHECK-NEXT: br i1242 // CHECK: [[AFTER_COOKIE:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8243 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[AFTER_COOKIE]], i64 5244 // CHECK-NEXT: br label245 // CHECK: [[CUR:%.*]] = phi ptr [ [[AFTER_COOKIE]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]246 // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])247 // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], ptr [[CUR]], i64 1248 // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[END]]249 // CHECK-NEXT: br i1 [[DONE]]250 void test1b(void *p) {251 new (p, true) A[5];252 }253 254 // TODO: it's okay if all these size calculations get dropped.255 // FIXME: maybe we should try to throw on overflow?256 // CHECK-LABEL: define{{.*}} void @_ZN6test155test2EPvi(257 // CHECK: [[N:%.*]] = load i32, ptr258 // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64259 // CHECK-NEXT: [[P:%.*]] = load ptr, ptr260 // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0261 // CHECK-NEXT: br i1 [[ISEMPTY]],262 // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[P]], i64 [[T0]]263 // CHECK-NEXT: br label264 // CHECK: [[CUR:%.*]] = phi ptr [ [[P]],265 // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])266 void test2(void *p, int n) {267 new (p) A[n];268 }269}270 271namespace PR10197 {272 // CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv()273 template<typename T>274 void f() {275 // CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm276 new T;277 // CHECK-NEXT: ret void278 }279 280 template void f<int>();281}282 283namespace PR11523 {284 class MyClass;285 typedef int MyClass::* NewTy;286 // CHECK-LABEL: define{{.*}} ptr @_ZN7PR115231fEv287 // CHECK: store i64 -1288 NewTy* f() { return new NewTy[2](); }289}290 291namespace PR11757 {292 // Make sure we elide the copy construction.293 struct X { X(); X(const X&); };294 X* a(X* x) { return new X(X()); }295 // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE296 // CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm297 // CHECK: ret {{.*}} [[CALL]]298}299 300namespace PR13380 {301 struct A { A() {} };302 struct B : public A { int x; };303 // CHECK-LABEL: define{{.*}} ptr @_ZN7PR133801fEv304 // CHECK: call noalias noundef nonnull ptr @_Znam(305 // CHECK: call void @llvm.memset.p0306 // CHECK-NEXT: call void @_ZN7PR133801BC1Ev307 void* f() { return new B[2](); }308}309 310struct MyPlacementType {} mpt;311void *operator new(size_t, MyPlacementType);312 313namespace N3664 {314 struct S { S() throw(int); };315 316 // CHECK-LABEL: define{{.*}} void @_ZN5N36641fEv317 void f() {318 // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]319 int *p = new int; // expected-note {{allocated with 'new' here}}320 // CHECK: call void @_ZdlPvm({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]321 delete p;322 323 // CHECK: call noalias noundef nonnull ptr @_Znam(i64 noundef 12) [[ATTR_BUILTIN_NEW]]324 int *q = new int[3];325 // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]326 delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}327 328 // CHECK: call noalias noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef 3, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]]329 (void) new (nothrow) S[3];330 331 // CHECK: call noundef ptr @_Znwm15MyPlacementType(i64 noundef 4){{$}}332 (void) new (mpt) int;333 }334 335 // CHECK: declare noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]]336 337 // CHECK-LABEL: define{{.*}} void @_ZN5N36641gEv338 void g() {339 // It's OK for there to be attributes here, so long as we don't have a340 // 'builtin' attribute.341 // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) {{#[^ ]*}}{{$}}342 int *p = (int*)operator new(4);343 // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]344 operator delete(p);345 346 // CHECK: call noalias noundef nonnull ptr @_Znam(i64 noundef 12) {{#[^ ]*}}{{$}}347 int *q = (int*)operator new[](12);348 // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]]349 operator delete [](p);350 351 // CHECK: call noalias noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef 3, {{.*}}) [[ATTR_NOUNWIND_ALLOCSIZE:#[^ ]*]]352 (void) operator new[](3, nothrow);353 }354}355 356namespace builtins {357 // CHECK-LABEL: define{{.*}} void @_ZN8builtins1fEv358 void f() {359 // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) [[ATTR_BUILTIN_NEW]]360 // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]361 __builtin_operator_delete(__builtin_operator_new(4));362 }363}364 365// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin allocsize(0) {{.*[}]}}366// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}367// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE]] = {{[{].*}} nobuiltin nounwind allocsize(0) {{.*[}]}}368 369// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}370// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}371 372// The ([^b}|...) monstrosity is matching a character that's not the start of 'builtin'.373// Add more letters if this matches some other attribute.374// CHECK-DAG: attributes [[ATTR_NOUNWIND]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind {{([^b]|b[^u]|bu[^i]|bui[^l])*$}}375// CHECK-DAG: attributes [[ATTR_NOUNWIND_ALLOCSIZE]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind allocsize(0) {{([^b]|b[^u]|bu[^i]|bui[^l])*$}}376