diff options
Diffstat (limited to 'clang/test/CodeGenCXX/condition.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/condition.cpp | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/condition.cpp b/clang/test/CodeGenCXX/condition.cpp new file mode 100644 index 0000000..cc2eaf5 --- /dev/null +++ b/clang/test/CodeGenCXX/condition.cpp @@ -0,0 +1,317 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +void *f(); + +template <typename T> T* g() { + if (T* t = f()) + return t; + + return 0; +} + +void h() { + void *a = g<void>(); +} + +struct X { + X(); + X(const X&); + ~X(); + operator bool(); +}; + +struct Y { + Y(); + ~Y(); +}; + +X getX(); + +// CHECK: define void @_Z11if_destructi( +void if_destruct(int z) { + // Verify that the condition variable is destroyed at the end of the + // "if" statement. + // CHECK: call void @_ZN1XC1Ev + // CHECK: call zeroext i1 @_ZN1XcvbEv + if (X x = X()) { + // CHECK: store i32 18 + z = 18; + } + // CHECK: call void @_ZN1XD1Ev + // CHECK: store i32 17 + z = 17; + + // CHECK: call void @_ZN1XC1Ev + if (X x = X()) + Y y; + // CHECK: br + // CHECK: call void @_ZN1YC1Ev + // CHECK: call void @_ZN1YD1Ev + // CHECK: br + // CHECK: call void @_ZN1XD1Ev + + // CHECK: call void @_Z4getXv + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + if (getX()) { } + + // CHECK: ret +} + +struct ConvertibleToInt { + ConvertibleToInt(); + ~ConvertibleToInt(); + operator int(); +}; + +ConvertibleToInt getConvToInt(); + +void switch_destruct(int z) { + // CHECK: call void @_ZN16ConvertibleToIntC1Ev + switch (ConvertibleToInt conv = ConvertibleToInt()) { + case 0: + break; + + default: + // CHECK: store i32 19 + z = 19; + break; + } + // CHECK: call void @_ZN16ConvertibleToIntD1Ev + // CHECK: store i32 20 + z = 20; + + // CHECK: call void @_Z12getConvToIntv + // CHECK: call i32 @_ZN16ConvertibleToIntcviEv + // CHECK: call void @_ZN16ConvertibleToIntD1Ev + switch(getConvToInt()) { + case 0: + break; + } + // CHECK: store i32 27 + z = 27; + // CHECK: ret +} + +int foo(); + +// CHECK: define void @_Z14while_destructi +void while_destruct(int z) { + // CHECK: [[Z:%.*]] = alloca i32 + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + while (X x = X()) { + // CHECK: call void @_ZN1XC1Ev + // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: br i1 [[COND]] + + // Loop-exit staging block. + // CHECK: store i32 3, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + + // While body. + // CHECK: store i32 21, i32* [[Z]] + // CHECK: store i32 0, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + z = 21; + + // Cleanup. + // CHECK: call void @_ZN1XD1Ev + // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: switch i32 [[DEST]] + } + + // CHECK: store i32 22, i32* [[Z]] + z = 22; + + // CHECK: call void @_Z4getXv + // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + while(getX()) { } + + // CHECK: store i32 25, i32* [[Z]] + z = 25; + + // CHECK: ret +} + +// CHECK: define void @_Z12for_destructi( +void for_destruct(int z) { + // CHECK: [[Z:%.*]] = alloca i32 + // CHECK: [[CLEANUPDEST:%.*]] = alloca i32 + // CHECK: [[I:%.*]] = alloca i32 + // CHECK: call void @_ZN1YC1Ev + // CHECK-NEXT: br + // -> %for.cond + + for(Y y = Y(); X x = X(); ++z) { + // %for.cond: The loop condition. + // CHECK: call void @_ZN1XC1Ev + // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv( + // CHECK-NEXT: br i1 [[COND]] + // -> %for.body, %for.cond.cleanup + + // %for.cond.cleanup: Exit cleanup staging. + // CHECK: store i32 2, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + // -> %cleanup + + // %for.body: + // CHECK: store i32 23, i32* [[Z]] + // CHECK-NEXT: br + // -> %for.inc + z = 23; + + // %for.inc: + // CHECK: [[TMP:%.*]] = load i32* [[Z]] + // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 + // CHECK-NEXT: store i32 [[INC]], i32* [[Z]] + // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]] + // CHECK-NEXT: br + // -> %cleanup + + // %cleanup: Destroys X. + // CHECK: call void @_ZN1XD1Ev + // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: switch i32 [[YDESTTMP]] + // 0 -> %cleanup.cont, default -> %cleanup1 + + // %cleanup.cont: (eliminable) + // CHECK: br + // -> %for.cond + + // %cleanup1: Destroys Y. + // CHECK: call void @_ZN1YD1Ev( + // CHECK-NEXT: br + // -> %for.end + } + + // %for.end: + // CHECK: store i32 24 + z = 24; + + // CHECK-NEXT: store i32 0, i32* [[I]] + // CHECK-NEXT: br + // -> %for.cond6 + + // %for.cond6: + // CHECK: call void @_Z4getXv + // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + // -> %for.body10, %for.end16 + + // %for.body10: + // CHECK: br + // -> %for.inc11 + + // %for.inc11: + // CHECK: call void @_Z4getXv + // CHECK-NEXT: load i32* [[I]] + // CHECK-NEXT: add + // CHECK-NEXT: store + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NEXT: br + // -> %for.cond6 + int i = 0; + for(; getX(); getX(), ++i) { } + + // %for.end16 + // CHECK: store i32 26 + z = 26; + + // CHECK-NEXT: ret void +} + +void do_destruct(int z) { + // CHECK: define void @_Z11do_destruct + do { + // CHECK: store i32 77 + z = 77; + // CHECK: call void @_Z4getXv + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + } while (getX()); + // CHECK: store i32 99 + z = 99; + // CHECK: ret +} + +int f(X); + +template<typename T> +int instantiated(T x) { + int result; + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 2 + // CHECK: br + // CHECK: store i32 3 + if (f(x)) { result = 2; } else { result = 3; } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 4 + // CHECK: br + while (f(x)) { result = 4; } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + // CHECK: store i32 6 + // CHECK: br + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: store i32 5 + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + for (; f(x); f(x), result = 5) { + result = 6; + } + + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: switch i32 + // CHECK: store i32 7 + // CHECK: store i32 8 + switch (f(x)) { + case 0: + result = 7; + break; + + case 1: + result = 8; + } + + // CHECK: store i32 9 + // CHECK: br + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call i32 @_Z1f1X + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + do { + result = 9; + } while (f(x)); + + // CHECK: store i32 10 + // CHECK: call void @_ZN1XC1ERKS_ + // CHECK: call zeroext i1 @_ZN1XcvbEv + // CHECK: call void @_ZN1XD1Ev + // CHECK: br + do { + result = 10; + } while (X(x)); + + // CHECK: ret i32 + return result; +} + +template int instantiated(X); |