summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/condition.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-08 22:20:28 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-08 22:20:28 +0000
commiteaa18e449bb09c1e580aa35f9606ff2ca682f4cb (patch)
treefd01b5d2ed2b2e2754b3559c9429e709503760c9 /test/CodeGenCXX/condition.cpp
parent20fba8ad3fda19bd23d67c069f39080320d46fd5 (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.cpp79
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);