diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CodeGenCXX/new.cpp | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CodeGenCXX/new.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/new.cpp | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp new file mode 100644 index 0000000..8d9f641 --- /dev/null +++ b/clang/test/CodeGenCXX/new.cpp @@ -0,0 +1,252 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +typedef __typeof__(sizeof(0)) size_t; + +void t1() { + int* a = new int; +} + +// Declare the reserved placement operators. +void *operator new(size_t, void*) throw(); +void operator delete(void*, void*) throw(); +void *operator new[](size_t, void*) throw(); +void operator delete[](void*, void*) throw(); + +void t2(int* a) { + int* b = new (a) int; +} + +struct S { + int a; +}; + +// POD types. +void t3() { + int *a = new int(10); + _Complex int* b = new _Complex int(10i); + + S s; + s.a = 10; + S *sp = new S(s); +} + +// Non-POD +struct T { + T(); + int a; +}; + +void t4() { + // CHECK: call void @_ZN1TC1Ev + T *t = new T; +} + +struct T2 { + int a; + T2(int, int); +}; + +void t5() { + // CHECK: call void @_ZN2T2C1Eii + T2 *t2 = new T2(10, 10); +} + +int *t6() { + // Null check. + return new (0) int(10); +} + +void t7() { + new int(); +} + +struct U { + ~U(); +}; + +void t8(int n) { + new int[10]; + new int[n]; + + // Non-POD + new T[10]; + new T[n]; + + // Cookie required + new U[10]; + new U[n]; +} + +// noalias +// CHECK: declare noalias i8* @_Znam +void *operator new[](size_t); + +void t9() { + bool b; + + new bool(true); + new (&b) bool(true); +} + +struct A { + void* operator new(__typeof(sizeof(int)), int, float, ...); + A(); +}; + +A* t10() { + // CHECK: @_ZN1AnwEmifz + return new(1, 2, 3.45, 100) A; +} + +// CHECK: define void @_Z3t11i +struct B { int a; }; +struct Bmemptr { int Bmemptr::* memptr; int a; }; + +void t11(int n) { + // CHECK: call noalias i8* @_Znwm + // CHECK: call void @llvm.memset.p0i8.i64( + B* b = new B(); + + // CHECK: call noalias i8* @_Znam + // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}} + B *b2 = new B[n](); + + // CHECK: call noalias i8* @_Znam + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + // CHECK: br + Bmemptr *b_memptr = new Bmemptr[n](); + + // CHECK: ret void +} + +struct Empty { }; + +// We don't need to initialize an empty class. +// CHECK: define void @_Z3t12v +void t12() { + // CHECK: call noalias i8* @_Znam + // CHECK-NOT: br + (void)new Empty[10]; + + // CHECK: call noalias i8* @_Znam + // CHECK-NOT: br + (void)new Empty[10](); + + // CHECK: ret void +} + +// Zero-initialization +// CHECK: define void @_Z3t13i +void t13(int n) { + // CHECK: call noalias i8* @_Znwm + // CHECK: store i32 0, i32* + (void)new int(); + + // CHECK: call noalias i8* @_Znam + // CHECK: {{call void.*llvm.memset.p0i8.i64.*i8 0, i64 %}} + (void)new int[n](); + + // CHECK-NEXT: ret void +} + +struct Alloc{ + int x; + void* operator new[](size_t size); + void operator delete[](void* p); + ~Alloc(); +}; + +void f() { + // CHECK: call i8* @_ZN5AllocnaEm(i64 808) + // CHECK: store i64 200 + // CHECK: call void @_ZN5AllocD1Ev( + // CHECK: call void @_ZN5AllocdaEPv(i8* + delete[] new Alloc[10][20]; + // CHECK: call noalias i8* @_Znwm + // CHECK: call void @_ZdlPv(i8* + delete new bool; + // CHECK: ret void +} + +namespace test15 { + struct A { A(); ~A(); }; + + // CHECK: define void @_ZN6test155test0EPv( + // CHECK: [[P:%.*]] = load i8* + // CHECK-NEXT: icmp eq i8* [[P]], null + // CHECK-NEXT: br i1 + // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* + // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]]) + void test0(void *p) { + new (p) A(); + } + + // CHECK: define void @_ZN6test155test1EPv( + // CHECK: [[P:%.*]] = load i8** + // CHECK-NEXT: icmp eq i8* [[P]], null + // CHECK-NEXT: br i1 + // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 + // CHECK-NEXT: br label + // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] + // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]]) + // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 + // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] + // CHECK-NEXT: br i1 [[DONE]] + void test1(void *p) { + new (p) A[5]; + } + + // TODO: it's okay if all these size calculations get dropped. + // FIXME: maybe we should try to throw on overflow? + // CHECK: define void @_ZN6test155test2EPvi( + // CHECK: [[N:%.*]] = load i32* + // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64 + // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0 + // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]] + // CHECK-NEXT: [[P:%.*]] = load i8* + // CHECK-NEXT: icmp eq i8* [[P]], null + // CHECK-NEXT: br i1 + // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* + // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0 + // CHECK-NEXT: br i1 [[ISEMPTY]], + // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[T0]] + // CHECK-NEXT: br label + // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], + // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]]) + void test2(void *p, int n) { + new (p) A[n]; + } +} + +namespace PR10197 { + // CHECK: define weak_odr void @_ZN7PR101971fIiEEvv() + template<typename T> + void f() { + // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm + // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to + new T; + // CHECK-NEXT: ret void + } + + template void f<int>(); +} + +namespace PR11523 { + class MyClass; + typedef int MyClass::* NewTy; + // CHECK: define i64* @_ZN7PR115231fEv + // CHECK: store i64 -1 + NewTy* f() { return new NewTy[2](); } +} + +namespace PR11757 { + // Make sure we elide the copy construction. + struct X { X(); X(const X&); }; + X* a(X* x) { return new X(X()); } + // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE + // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm + // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to + // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]]) + // CHECK-NEXT: ret {{.*}} [[CASTED]] +} |