summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/new.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/new.cpp')
-rw-r--r--test/CodeGenCXX/new.cpp106
1 files changed, 92 insertions, 14 deletions
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index e052390..91da77a 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -2,9 +2,24 @@
typedef __typeof__(sizeof(0)) size_t;
+// Ensure that this declaration doesn't cause operator new to lose its
+// 'noalias' attribute.
+void *operator new[](size_t);
+
void t1() {
- int* a = new int;
+ delete new int;
+ delete [] new int [3];
+}
+
+// CHECK: declare noalias i8* @_Znwm(i64) [[ATTR_NOBUILTIN:#[^ ]*]]
+// CHECK: declare void @_ZdlPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]
+// CHECK: declare noalias i8* @_Znam(i64) [[ATTR_NOBUILTIN]]
+// CHECK: declare void @_ZdaPv(i8*) [[ATTR_NOBUILTIN_NOUNWIND]]
+
+namespace std {
+ struct nothrow_t {};
}
+std::nothrow_t nothrow;
// Declare the reserved placement operators.
void *operator new(size_t, void*) throw();
@@ -12,6 +27,13 @@ void operator delete(void*, void*) throw();
void *operator new[](size_t, void*) throw();
void operator delete[](void*, void*) throw();
+// Declare the replaceable global allocation operators.
+void *operator new(size_t, const std::nothrow_t &) throw();
+void *operator new[](size_t, const std::nothrow_t &) throw();
+void operator delete(void *, const std::nothrow_t &) throw();
+void operator delete[](void *, const std::nothrow_t &) throw();
+
+
void t2(int* a) {
int* b = new (a) int;
}
@@ -77,10 +99,6 @@ void t8(int n) {
new U[n];
}
-// noalias
-// CHECK: declare noalias i8* @_Znam
-void *operator new[](size_t);
-
void t9() {
bool b;
@@ -98,7 +116,7 @@ A* t10() {
return new(1, 2, 3.45, 100) A;
}
-// CHECK: define void @_Z3t11i
+// CHECK-LABEL: define void @_Z3t11i
struct B { int a; };
struct Bmemptr { int Bmemptr::* memptr; int a; };
@@ -122,7 +140,7 @@ void t11(int n) {
struct Empty { };
// We don't need to initialize an empty class.
-// CHECK: define void @_Z3t12v
+// CHECK-LABEL: define void @_Z3t12v
void t12() {
// CHECK: call noalias i8* @_Znam
// CHECK-NOT: br
@@ -136,7 +154,7 @@ void t12() {
}
// Zero-initialization
-// CHECK: define void @_Z3t13i
+// CHECK-LABEL: define void @_Z3t13i
void t13(int n) {
// CHECK: call noalias i8* @_Znwm
// CHECK: store i32 0, i32*
@@ -171,7 +189,7 @@ void f() {
namespace test15 {
struct A { A(); ~A(); };
- // CHECK: define void @_ZN6test155test0EPv(
+ // CHECK-LABEL: define void @_ZN6test155test0EPv(
// CHECK: [[P:%.*]] = load i8*
// CHECK-NEXT: icmp eq i8* [[P]], null
// CHECK-NEXT: br i1
@@ -181,7 +199,7 @@ namespace test15 {
new (p) A();
}
- // CHECK: define void @_ZN6test155test1EPv(
+ // CHECK-LABEL: define void @_ZN6test155test1EPv(
// CHECK: [[P:%.*]] = load i8**
// CHECK-NEXT: icmp eq i8* [[P]], null
// CHECK-NEXT: br i1
@@ -199,7 +217,7 @@ namespace test15 {
// 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-LABEL: define void @_ZN6test155test2EPvi(
// CHECK: [[N:%.*]] = load i32*
// CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
// CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0
@@ -220,7 +238,7 @@ namespace test15 {
}
namespace PR10197 {
- // CHECK: define weak_odr void @_ZN7PR101971fIiEEvv()
+ // CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv()
template<typename T>
void f() {
// CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
@@ -235,7 +253,7 @@ namespace PR10197 {
namespace PR11523 {
class MyClass;
typedef int MyClass::* NewTy;
- // CHECK: define i64* @_ZN7PR115231fEv
+ // CHECK-LABEL: define i64* @_ZN7PR115231fEv
// CHECK: store i64 -1
NewTy* f() { return new NewTy[2](); }
}
@@ -254,9 +272,69 @@ namespace PR11757 {
namespace PR13380 {
struct A { A() {} };
struct B : public A { int x; };
- // CHECK: define i8* @_ZN7PR133801fEv
+ // CHECK-LABEL: define i8* @_ZN7PR133801fEv
// CHECK: call noalias i8* @_Znam(
// CHECK: call void @llvm.memset.p0i8
// CHECK-NEXT: call void @_ZN7PR133801BC1Ev
void* f() { return new B[2](); }
}
+
+struct MyPlacementType {} mpt;
+void *operator new(size_t, MyPlacementType);
+
+namespace N3664 {
+ struct S { S() throw(int); };
+
+ // CHECK-LABEL-LABEL: define void @_ZN5N36641fEv
+ void f() {
+ // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
+ int *p = new int;
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]
+ delete p;
+
+ // CHECK: call noalias i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]]
+ int *q = new int[3];
+ // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
+ delete [] p;
+
+ // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]]
+ (void) new (nothrow) S[3];
+
+ // CHECK: call i8* @_Znwm15MyPlacementType(i64 4){{$}}
+ (void) new (mpt) int;
+ }
+
+ // FIXME: Can we mark this noalias?
+ // CHECK: declare i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]]
+
+ // CHECK-LABEL-LABEL: define void @_ZN5N36641gEv
+ void g() {
+ // It's OK for there to be attributes here, so long as we don't have a
+ // 'builtin' attribute.
+ // CHECK: call noalias i8* @_Znwm(i64 4){{$}}
+ int *p = (int*)operator new(4);
+ // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]
+ operator delete(p);
+
+ // CHECK: call noalias i8* @_Znam(i64 12){{$}}
+ int *q = (int*)operator new[](12);
+ // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]]
+ operator delete [](p);
+
+ // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_NOUNWIND]]
+ (void) operator new[](3, nothrow);
+ }
+}
+
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}
+
+// CHECK: attributes [[ATTR_NOUNWIND]] =
+// CHECK-NOT: builtin
+// CHECK-NOT: attributes
+// CHECK: nounwind
+// CHECK-NOT: builtin
+// CHECK: attributes
+
+// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}
+// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}
OpenPOWER on IntegriCloud