summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/condition.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-06 17:25:47 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-06 17:25:47 +0000
commit586596fd7f7a336a2847b300c80614dcf39ab6d5 (patch)
tree2921da607a64f6a81e89d4f8978990586e44c006 /test/CodeGenCXX/condition.cpp
parent97a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00 (diff)
Rework our handling of temporary objects within the conditions of
if/switch/while/do/for statements. Previously, we would end up either: (1) Forgetting to destroy temporaries created in the condition (!), (2) Destroying the temporaries created in the condition *before* converting the condition to a boolean value (or, in the case of a switch statement, to an integral or enumeral value), or (3) In a for statement, destroying the condition's temporaries at the end of the increment expression (!). We now destroy temporaries in conditions at the right times. This required some tweaking of the Parse/Sema interaction, since the parser was building full expressions too early in many places. Fixes PR7067. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103187 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/condition.cpp')
-rw-r--r--test/CodeGenCXX/condition.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index e435408aa8..0ebb22a6f9 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -23,6 +23,8 @@ struct Y {
~Y();
};
+X getX();
+
void if_destruct(int z) {
// Verify that the condition variable is destroyed at the end of the
// "if" statement.
@@ -44,6 +46,14 @@ void if_destruct(int z) {
// 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 {
@@ -52,6 +62,8 @@ struct ConvertibleToInt {
operator int();
};
+ConvertibleToInt getConvToInt();
+
void switch_destruct(int z) {
// CHECK: call void @_ZN16ConvertibleToIntC1Ev
switch (ConvertibleToInt conv = ConvertibleToInt()) {
@@ -68,6 +80,17 @@ void switch_destruct(int z) {
// 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();
@@ -88,6 +111,17 @@ void while_destruct(int z) {
// CHECK: {{while.end|:7}}
// CHECK: store i32 22
z = 22;
+
+ // CHECK: call void @_Z4getXv
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ while(getX()) { }
+
+ // CHECK: store i32 25
+ z = 25;
+
+ // CHECK: ret
}
void for_destruct(int z) {
@@ -107,4 +141,33 @@ void for_destruct(int z) {
// CHECK: call void @_ZN1YD1Ev
// CHECK: store i32 24
z = 24;
+
+ // CHECK: call void @_Z4getXv
+ // CHECK: call zeroext i1 @_ZN1XcvbEv
+ // CHECK: call void @_ZN1XD1Ev
+ // CHECK: br
+ // CHECK: call void @_Z4getXv
+ // CHECK: load
+ // CHECK: add
+ // CHECK: call void @_ZN1XD1Ev
+ int i = 0;
+ for(; getX(); getX(), ++i) { }
+ z = 26;
+ // CHECK: store i32 26
+ // CHECK: ret
+}
+
+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
}