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.
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;
}
--- /dev/null
+// 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*>());
+}
--- /dev/null
+// 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>());
+}