Daniel Dunbar | 7bd1048 | 2009-11-30 18:17:34 +0000 | [diff] [blame^] | 1 | // Output file should have no calls to error() with folding. |
| 2 | // RUN: clang-cc -triple i386-unknown-unknown -O3 -emit-llvm -o %t %s |
| 3 | // RUN: FileCheck %s < %t |
| 4 | |
| 5 | static unsigned pow(unsigned Base, unsigned Power) { |
| 6 | unsigned Val = 1; |
| 7 | while (Power--) |
| 8 | Val *= Base; |
| 9 | return Val; |
| 10 | } |
| 11 | |
| 12 | struct TempTracker { |
| 13 | unsigned Product, Index; |
| 14 | |
| 15 | TempTracker() : Product(1), Index(0) {} |
| 16 | |
| 17 | }; |
| 18 | |
| 19 | // FIXME: This can be used to check elision as well, if P = 0 hacks are removed. |
| 20 | struct A { |
| 21 | TempTracker &TT; |
| 22 | mutable unsigned P; |
| 23 | bool Truth; |
| 24 | |
| 25 | A(TempTracker &_TT, unsigned _P, bool _Truth = true) |
| 26 | : TT(_TT), P(_P), Truth(_Truth) {} |
| 27 | A(const A &RHS) : TT(RHS.TT), P(RHS.P), Truth(RHS.Truth) { RHS.P = 0; } |
| 28 | ~A() { |
| 29 | if (P) |
| 30 | TT.Product *= pow(P, ++TT.Index); |
| 31 | } |
| 32 | |
| 33 | operator bool () { return Truth; } |
| 34 | }; |
| 35 | |
| 36 | // 3, 7, 2 |
| 37 | static unsigned f0(bool val = false) { |
| 38 | TempTracker tt; |
| 39 | { |
| 40 | A a(tt, 2); |
| 41 | if ((A(tt, 3), val)) |
| 42 | A b(tt, 5); |
| 43 | A c(tt, 7); |
| 44 | } |
| 45 | return tt.Product; |
| 46 | } |
| 47 | |
| 48 | // 3, 5, 7, 2 |
| 49 | static unsigned f1(bool val = true) { |
| 50 | TempTracker tt; |
| 51 | { |
| 52 | A a(tt, 2); |
| 53 | if ((A(tt, 3), val)) |
| 54 | A b(tt, 5); |
| 55 | A c(tt, 7); |
| 56 | } |
| 57 | return tt.Product; |
| 58 | } |
| 59 | |
| 60 | // 5, 3, 7, 2 |
| 61 | static unsigned f2() { |
| 62 | TempTracker tt; |
| 63 | { |
| 64 | A a(tt, 2); |
| 65 | if (A b = A(tt, 3)) |
| 66 | A c(tt, 5); |
| 67 | A d(tt, 7); |
| 68 | } |
| 69 | return tt.Product; |
| 70 | } |
| 71 | |
| 72 | // 7, 3, 11, 2 |
| 73 | static unsigned f3() { |
| 74 | TempTracker tt; |
| 75 | { |
| 76 | A a(tt, 2); |
| 77 | if (A b = A(tt, 3, false)) |
| 78 | A c(tt, 5); |
| 79 | else |
| 80 | A c(tt, 7); |
| 81 | A d(tt, 11); |
| 82 | } |
| 83 | return tt.Product; |
| 84 | } |
| 85 | |
| 86 | extern "C" void error(); |
| 87 | extern "C" void print(const char *Name, unsigned N); |
| 88 | |
| 89 | #define ORDER3(a, b, c) (pow(a, 1) * pow(b, 2) * pow(c, 3)) |
| 90 | #define ORDER4(a, b, c, d) (ORDER3(a, b, c) * pow(d, 4)) |
| 91 | void test() { |
| 92 | // CHECK: call void @print(i8* {{.*}}, i32 1176) |
| 93 | print("f0", f0()); |
| 94 | if (f0() != ORDER3(3, 7, 2)) |
| 95 | error(); |
| 96 | |
| 97 | // CHECK: call void @print(i8* {{.*}}, i32 411600) |
| 98 | print("f1", f1()); |
| 99 | if (f1() != ORDER4(3, 5, 7, 2)) |
| 100 | error(); |
| 101 | |
| 102 | // CHECK: call void @print(i8* {{.*}}, i32 246960) |
| 103 | print("f2", f2()); |
| 104 | if (f2() != ORDER4(5, 3, 7, 2)) |
| 105 | error(); |
| 106 | |
| 107 | // CHECK: call void @print(i8* {{.*}}, i32 1341648) |
| 108 | print("f3", f3()); |
| 109 | if (f3() != ORDER4(7, 3, 11, 2)) |
| 110 | error(); |
| 111 | } |
| 112 | |
| 113 | |
| 114 | |
| 115 | #ifdef HARNESS |
| 116 | |
| 117 | #include <cstdlib> |
| 118 | #include <cstdio> |
| 119 | |
| 120 | extern "C" void error() { |
| 121 | abort(); |
| 122 | } |
| 123 | |
| 124 | extern "C" void print(const char *name, unsigned N) { |
| 125 | printf("%s: %d\n", name, N); |
| 126 | } |
| 127 | |
| 128 | int main() { |
| 129 | test(); |
| 130 | return 0; |
| 131 | } |
| 132 | |
| 133 | #endif |