forked from OSchip/llvm-project
Update const_cast semantics for rvalue references. Add tests for
reinterpret_cast and const_cast using rvalue references. llvm-svn: 124007
This commit is contained in:
parent
465184ae10
commit
c1ed20cfba
|
@ -1050,9 +1050,8 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
|
|||
bool CStyle, unsigned &msg) {
|
||||
DestType = Self.Context.getCanonicalType(DestType);
|
||||
QualType SrcType = SrcExpr->getType();
|
||||
if (const LValueReferenceType *DestTypeTmp =
|
||||
DestType->getAs<LValueReferenceType>()) {
|
||||
if (!SrcExpr->isLValue()) {
|
||||
if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) {
|
||||
if (DestTypeTmp->isLValueReferenceType() && !SrcExpr->isLValue()) {
|
||||
// Cannot const_cast non-lvalue to lvalue reference type. But if this
|
||||
// is C-style, static_cast might find a way, so we simply suggest a
|
||||
// message and tell the parent to keep searching.
|
||||
|
@ -1156,8 +1155,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
|
|||
if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
|
||||
bool LValue = DestTypeTmp->isLValueReferenceType();
|
||||
if (LValue && !SrcExpr->isLValue()) {
|
||||
// Cannot cast non-lvalue to reference type. See the similar comment in
|
||||
// const_cast.
|
||||
// Cannot cast non-lvalue to lvalue reference type. See the similar
|
||||
// comment in const_cast.
|
||||
msg = diag::err_bad_cxx_cast_rvalue;
|
||||
return TC_NotApplicable;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
// The result of the expression const_cast<T>(v) is of type T. If T is
|
||||
// an lvalue reference to object type, the result is an lvalue; if T
|
||||
// is an rvalue reference to object type, the result is an xvalue;.
|
||||
|
||||
unsigned int f(int);
|
||||
|
||||
template<typename T> T& lvalue();
|
||||
template<typename T> T&& xvalue();
|
||||
template<typename T> T prvalue();
|
||||
|
||||
void test_classification(const int *ptr) {
|
||||
int *ptr0 = const_cast<int *&&>(ptr);
|
||||
int *ptr1 = const_cast<int *&&>(xvalue<const int*>());
|
||||
int *ptr2 = const_cast<int *&&>(prvalue<const int*>());
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
// If T is an lvalue reference type or an rvalue reference to function
|
||||
// type, the result is an lvalue; if T is an rvalue reference to
|
||||
// object type, the result is an xvalue;
|
||||
|
||||
unsigned int f(int);
|
||||
|
||||
template<typename T> T&& xvalue();
|
||||
void test_classification(char *ptr) {
|
||||
int (&fr0)(int) = reinterpret_cast<int (&&)(int)>(f);
|
||||
int &&ir0 = reinterpret_cast<int &&>(*ptr);
|
||||
int &&ir1 = reinterpret_cast<int &&>(0);
|
||||
int &&ir2 = reinterpret_cast<int &&>('a');
|
||||
int &&ir3 = reinterpret_cast<int &&>(xvalue<char>());
|
||||
}
|
Loading…
Reference in New Issue