aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/exceptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/exceptions.cpp')
-rw-r--r--test/CodeGenCXX/exceptions.cpp69
1 files changed, 60 insertions, 9 deletions
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index 2337eee071..c60f2a1b45 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -164,26 +164,78 @@ namespace test2 {
namespace test3 {
struct A {
- A(int); A(int, int); ~A();
+ A(int); A(int, int); A(const A&); ~A();
void *p;
- void *operator new(size_t, void*, void*);
- void operator delete(void*, void*, void*);
+ void *operator new(size_t, void*, double);
+ void operator delete(void*, void*, double);
};
+ void *foo();
+ double bar();
+ A makeA(), *makeAPtr();
+
A *a() {
// CHECK: define [[A:%.*]]* @_ZN5test31aEv()
// CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
- // CHECK: [[BAR:%.*]] = call i8* @_ZN5test33barEv()
- // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
+ // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
+ // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
// CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
// CHECK: ret [[A]]* [[CAST]]
- // CHECK: invoke void @_ZN5test31AdlEPvS1_S1_(i8* [[NEW]], i8* [[FOO]], i8* [[BAR]])
+ // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
// CHECK: call void @_ZSt9terminatev()
- extern void *foo(), *bar();
-
return new(foo(),bar()) A(5);
}
+
+ // rdar://problem/8439196
+ A *b(bool cond) {
+
+ // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
+ // CHECK: [[SAVED0:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
+ // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
+ // CHECK: [[TMPACTIVE:%.*]] = alloca i1
+ // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
+ // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
+
+ // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
+ // CHECK-NEXT: br i1 [[COND]]
+ return (cond ?
+
+ // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
+ // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
+ // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
+ // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
+ // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
+ // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[TMP]])
+ // CHECK: store i1 true, i1* [[TMPACTIVE]]
+ // CHECK-NEXT: invoke void @_ZN5test31AC1ERKS0_([[A]]* [[CAST]], [[A]]* [[TMP]])
+ // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: br label
+ // -> cond.end
+ new(foo(),10.0) A(makeA()) :
+
+ // CHECK: [[MAKE:%.*]] = invoke [[A]]* @_ZN5test38makeAPtrEv()
+ // CHECK: br label
+ // -> cond.end
+ makeAPtr());
+
+ // cond.end:
+ // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
+ // CHECK-NEXT: [[ISACTIVE:%.*]] = load i1* [[TMPACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: invoke void @_ZN5test31AD1Ev
+ // CHECK: ret [[A]]* [[RESULT]]
+
+ // in the EH path:
+ // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]]
+ // CHECK-NEXT: br i1 [[ISACTIVE]]
+ // CHECK: [[V0:%.*]] = load i8** [[SAVED0]]
+ // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]]
+ // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
+ }
}
namespace test4 {
@@ -206,5 +258,4 @@ namespace test4 {
return new(foo(),bar()) A(5);
}
-
}