зеркало из https://github.com/microsoft/clang-1.git
Implement static_cast from lvalue to rvalue reference.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
21bab842fb
Коммит
157be839ad
|
@ -1010,6 +1010,9 @@ def err_ambiguous_base_to_derived_cast : Error<
|
|||
"ambiguous static_cast from base %0 to derived %1:%2">;
|
||||
def err_static_downcast_via_virtual : Error<
|
||||
"cannot cast %0 to %1 via virtual base %2">;
|
||||
def err_bad_lvalue_to_rvalue_cast : Error<
|
||||
"cannot cast from lvalue of type %0 to rvalue reference to %1; types are "
|
||||
"not compatible">;
|
||||
|
||||
// Other C++ expressions
|
||||
def err_need_header_before_typeid : Error<
|
||||
|
|
|
@ -39,6 +39,8 @@ static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
|
|||
const SourceRange &DestRange);
|
||||
|
||||
static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
|
||||
static TryStaticCastResult TryLValueToRValueCast(
|
||||
Sema &Self, Expr *SrcExpr, QualType DestType, const SourceRange &OpRange);
|
||||
static TryStaticCastResult TryStaticReferenceDowncast(
|
||||
Sema &Self, Expr *SrcExpr, QualType DestType, const SourceRange &OpRange);
|
||||
static TryStaticCastResult TryStaticPointerDowncast(
|
||||
|
@ -452,6 +454,13 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
|
|||
return;
|
||||
}
|
||||
|
||||
// N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
|
||||
// reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
|
||||
if (TryLValueToRValueCast(Self, SrcExpr, DestType, OpRange) >
|
||||
TSC_NotApplicable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// C++ 5.2.9p2: An expression e can be explicitly converted to a type T
|
||||
// [...] if the declaration "T t(e);" is well-formed, [...].
|
||||
if (TryStaticImplicitCast(Self, SrcExpr, DestType, OpRange) >
|
||||
|
@ -533,6 +542,36 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
|
|||
<< OpRange;
|
||||
}
|
||||
|
||||
/// Tests whether a conversion according to N2844 is valid.
|
||||
TryStaticCastResult
|
||||
TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
|
||||
const SourceRange &OpRange)
|
||||
{
|
||||
// N2844 5.2.9p3: An lvalue of type "cv1 T1" can be cast to type "rvalue
|
||||
// reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
|
||||
const RValueReferenceType *R = DestType->getAsRValueReferenceType();
|
||||
if (!R)
|
||||
return TSC_NotApplicable;
|
||||
|
||||
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid)
|
||||
return TSC_NotApplicable;
|
||||
|
||||
// Because we try the reference downcast before this function, from now on
|
||||
// this is the only cast possibility, so we issue an error if we fail now.
|
||||
bool DerivedToBase;
|
||||
if (Self.CompareReferenceRelationship(SrcExpr->getType(), R->getPointeeType(),
|
||||
DerivedToBase) <
|
||||
Sema::Ref_Compatible_With_Added_Qualification) {
|
||||
Self.Diag(OpRange.getBegin(), diag::err_bad_lvalue_to_rvalue_cast)
|
||||
<< SrcExpr->getType() << R->getPointeeType() << OpRange;
|
||||
return TSC_Failed;
|
||||
}
|
||||
|
||||
// FIXME: Similar to CheckReferenceInit, we actually need more AST annotation
|
||||
// than nothing.
|
||||
return TSC_Success;
|
||||
}
|
||||
|
||||
/// Tests whether a conversion according to C++ 5.2.9p5 is valid.
|
||||
TryStaticCastResult
|
||||
TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
|
||||
|
|
|
@ -28,6 +28,8 @@ void f() {
|
|||
int i1 = 0;
|
||||
int &&virr4 = i1; // expected-error {{rvalue reference cannot bind to lvalue}}
|
||||
int &&virr5 = ret_irr();
|
||||
int &&virr6 = static_cast<int&&>(i1);
|
||||
(void)static_cast<not_int&&>(i1); // expected-error {{types are not compatible}}
|
||||
|
||||
int i2 = over(i1);
|
||||
not_int ni1 = over(0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче