When a conditional operator is an rvalue of class type, we need to
create a temporary copy of both the "true" and "false" results. Fixes
the Boost.Interprocess failures.

Daniel did all the hard work of tracking down the issue, I get to type
up the trivial fix for this horrible miscompile.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104184 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0737e9f..62b7b4a 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2265,9 +2265,32 @@
 
   //   After those conversions, one of the following shall hold:
   //   -- The second and third operands have the same type; the result
-  //      is of that type.
-  if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy))
+  //      is of that type. If the operands have class type, the result
+  //      is a prvalue temporary of the result type, which is
+  //      copy-initialized from either the second operand or the third
+  //      operand depending on the value of the first operand.
+  if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) {
+    if (LTy->isRecordType()) {
+      // The operands have class type. Make a temporary copy.
+      InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
+      OwningExprResult LHSCopy = PerformCopyInitialization(Entity, 
+                                                           SourceLocation(), 
+                                                           Owned(LHS));
+      if (LHSCopy.isInvalid())
+        return QualType();
+        
+      OwningExprResult RHSCopy = PerformCopyInitialization(Entity, 
+                                                           SourceLocation(), 
+                                                           Owned(RHS));
+      if (RHSCopy.isInvalid())
+        return QualType();
+      
+      LHS = LHSCopy.takeAs<Expr>();
+      RHS = RHSCopy.takeAs<Expr>();
+    }
+
     return LTy;
+  }
 
   // Extension: conditional operator involving vector types.
   if (LTy->isVectorType() || RTy->isVectorType())