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
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index e4266cf..f5b43d2 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -14,6 +14,7 @@
 
 struct X {
   X();
+  X(const X&);
   ~X();
   operator bool();
 };
@@ -171,3 +172,81 @@
   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);