From: Davide Italiano Date: Sun, 12 Jul 2015 22:10:56 +0000 (+0000) Subject: [Sema] If lvalue to rvalue reference cast is valid don't emit diagnostic. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c377036ee1772a07c7e5ae030e35ee499880245;p=clang [Sema] If lvalue to rvalue reference cast is valid don't emit diagnostic. In the test, y1 is not reference compatible to y2 and we currently assume the cast is ill-formed so we emit a diagnostic. Instead, in order to honour the standard, if y1 it's not reference-compatible to y2 then it can't be converted using a static_cast, and a reinterpret_cast should be tried instead. Richard Smith provided the correct interpretation of the standard and explanation about the subtle difference between "can't be cast" and "the cast is ill-formed". The former applies in this case. PR: 23802 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241998 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index d9dc4df9f2..c0754ba790 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -975,7 +975,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, if (tcr != TC_NotApplicable) return tcr; - // C++0x [expr.static.cast]p3: + // C++11 [expr.static.cast]p3: // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2 // T2" if "cv2 T2" is reference-compatible with "cv1 T1". tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, @@ -1133,7 +1133,7 @@ TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, CastKind &Kind, CXXCastPath &BasePath, unsigned &msg) { - // C++0x [expr.static.cast]p3: + // C++11 [expr.static.cast]p3: // A glvalue 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->getAs(); @@ -1161,6 +1161,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, DerivedToBase, ObjCConversion, ObjCLifetimeConversion) < Sema::Ref_Compatible_With_Added_Qualification) { + if (CStyle) + return TC_NotApplicable; msg = diag::err_bad_lvalue_to_rvalue_cast; return TC_Failed; } diff --git a/test/SemaCXX/cast-lvalue-to-rvalue-reference.cpp b/test/SemaCXX/cast-lvalue-to-rvalue-reference.cpp new file mode 100644 index 0000000000..45e72d2924 --- /dev/null +++ b/test/SemaCXX/cast-lvalue-to-rvalue-reference.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// expected-no-diagnostics + +struct S {}; +int x; +S&& y1 = (S&&)x; +S&& y2 = reinterpret_cast(x); +S& z1 = (S&)x;