[cfe-commits] r104184 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/SemaCXX/conditional-expr.cpp

Douglas Gregor dgregor at apple.com
Wed May 19 16:40:50 PDT 2010


Author: dgregor
Date: Wed May 19 18:40:50 2010
New Revision: 104184

URL: http://llvm.org/viewvc/llvm-project?rev=104184&view=rev
Log:
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.


Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/conditional-expr.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=104184&r1=104183&r2=104184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed May 19 18:40:50 2010
@@ -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()) 

Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=104184&r1=104183&r2=104184&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Wed May 19 18:40:50 2010
@@ -255,3 +255,23 @@
     foo(a ? a->x() : 0);
   }
 }
+
+namespace rdar7998817 {
+  class X { 
+    X(X&); // expected-note{{declared private here}}
+
+    struct ref { };
+
+  public:
+    X();
+    X(ref);
+    
+    operator ref();
+  };
+
+  void f(bool B) {
+    X x;
+    (void)(B? x // expected-error{{calling a private constructor of class 'rdar7998817::X'}}
+           : X());
+  }
+}





More information about the cfe-commits mailing list