diff options
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 27 | ||||
-rw-r--r-- | test/SemaCXX/conditional-expr.cpp | 20 |
2 files changed, 45 insertions, 2 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 0737e9f151..62b7b4abbc 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2265,9 +2265,32 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // 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()) diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index f1fe8ba79b..a09ff2bd41 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -255,3 +255,23 @@ namespace test1 { 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()); + } +} |