[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