diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-08 22:20:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-08 22:20:28 +0000 |
commit | eaa18e449bb09c1e580aa35f9606ff2ca682f4cb (patch) | |
tree | fd01b5d2ed2b2e2754b3559c9429e709503760c9 /test/CodeGenCXX/condition.cpp | |
parent | 20fba8ad3fda19bd23d67c069f39080320d46fd5 (diff) |
When instantiating statements that involve conditions (if, while, do,
for, and switch), be careful to construct the full expressions as soon
as we perform template instantation, so we don't either forget to call
temporary destructors or destroy temporaries at the wrong time. This
is the template-instantiation analogue to r103187, during which I
hadn't realized that the issue would affect the handling of these
constructs differently inside and outside of templates.
Fixes a regression in Boost.Function.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103357 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/condition.cpp')
-rw-r--r-- | test/CodeGenCXX/condition.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp index e4266cf502..f5b43d2ef4 100644 --- a/test/CodeGenCXX/condition.cpp +++ b/test/CodeGenCXX/condition.cpp @@ -14,6 +14,7 @@ void h() { struct X { X(); + X(const X&); ~X(); operator bool(); }; @@ -171,3 +172,81 @@ void do_destruct(int z) { 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); |