diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-04-25 19:30:37 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-04-25 19:30:37 +0000 |
commit | 2414bcabd20b44e2ebf056d5479ebbfe68dced67 (patch) | |
tree | c4ef02b15c58630a1351313ca3b6d61d97f247f5 | |
parent | 2eba90e0dbe1bf846448bd6fa5b412b6a9ece817 (diff) | |
download | bcm5719-llvm-2414bcabd20b44e2ebf056d5479ebbfe68dced67.tar.gz bcm5719-llvm-2414bcabd20b44e2ebf056d5479ebbfe68dced67.zip |
Implement support for conditional between xvalues of reference-compatible
types. Patch by Erik Pilkington!
llvm-svn: 267454
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 22 | ||||
-rw-r--r-- | clang/test/SemaCXX/conditional-expr.cpp | 9 |
2 files changed, 22 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4c677e33e97..88f2bc798a2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4795,7 +4795,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, return Result; } -/// \brief Try to convert a type to another according to C++0x 5.16p3. +/// \brief Try to convert a type to another according to C++11 5.16p3. /// /// This is part of the parameter validation for the ? operator. If either /// value operand is a class type, the two operands are attempted to be @@ -4811,17 +4811,21 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, InitializationKind Kind = InitializationKind::CreateCopy(To->getLocStart(), SourceLocation()); - // C++0x 5.16p3 + // C++11 5.16p3 // The process for determining whether an operand expression E1 of type T1 // can be converted to match an operand expression E2 of type T2 is defined // as follows: - // -- If E2 is an lvalue: - bool ToIsLvalue = To->isLValue(); - if (ToIsLvalue) { - // E1 can be converted to match E2 if E1 can be implicitly converted to - // type "lvalue reference to T2", subject to the constraint that in the - // conversion the reference must bind directly to E1. - QualType T = Self.Context.getLValueReferenceType(ToType); + // -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be + // implicitly converted to type "lvalue reference to T2", subject to the + // constraint that in the conversion the reference must bind directly to + // an lvalue. + // -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be + // implicitly conveted to the type "rvalue reference to R2", subject to + // the constraint that the reference must bind directly. + if (To->isLValue() || To->isXValue()) { + QualType T = To->isLValue() ? Self.Context.getLValueReferenceType(ToType) + : Self.Context.getRValueReferenceType(ToType); + InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); InitializationSequence InitSeq(Self, Entity, Kind, From); diff --git a/clang/test/SemaCXX/conditional-expr.cpp b/clang/test/SemaCXX/conditional-expr.cpp index 538de5847de..c12efc0be7e 100644 --- a/clang/test/SemaCXX/conditional-expr.cpp +++ b/clang/test/SemaCXX/conditional-expr.cpp @@ -384,3 +384,12 @@ namespace PR17052 { int &test() { return b_ ? i_ : throw 1; } }; } + +namespace PR26448 { +struct Base {}; +struct Derived : Base {}; +Base b; +Derived d; +typedef decltype(true ? static_cast<Base&&>(b) : static_cast<Derived&&>(d)) x; +typedef Base &&x; +} |