From 8ec14e605725a87991f622d63f547f877ba59fef Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 26 Jan 2011 21:04:06 +0000 Subject: [PATCH] Handle C-style casts to rvalue reference types that cast away constness. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124319 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaCXXCast.cpp | 18 ++++++++++++++---- test/CXX/expr/expr.cast/p4-0x.cpp | 11 +++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 test/CXX/expr/expr.cast/p4-0x.cpp diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 3a9ad5ff7f..c492c2ac7d 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -78,7 +78,8 @@ static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType); // %1: Source Type // %2: Destination Type static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, - QualType DestType, CastKind &Kind, + QualType DestType, bool CStyle, + CastKind &Kind, CXXCastPath &BasePath, unsigned &msg); static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, @@ -583,7 +584,8 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, // C++0x [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, DestType, Kind, BasePath, msg); + tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, CStyle, Kind, BasePath, + msg); if (tcr != TC_NotApplicable) return tcr; @@ -695,7 +697,8 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, /// Tests whether a conversion according to N2844 is valid. TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, - CastKind &Kind, CXXCastPath &BasePath, unsigned &msg) { + bool CStyle, CastKind &Kind, CXXCastPath &BasePath, + unsigned &msg) { // C++0x [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". @@ -711,8 +714,15 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, // FIXME: Should allow casting away constness if CStyle. bool DerivedToBase; bool ObjCConversion; + QualType FromType = SrcExpr->getType(); + QualType ToType = R->getPointeeType(); + if (CStyle) { + FromType = FromType.getUnqualifiedType(); + ToType = ToType.getUnqualifiedType(); + } + if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(), - R->getPointeeType(), SrcExpr->getType(), + ToType, FromType, DerivedToBase, ObjCConversion) < Sema::Ref_Compatible_With_Added_Qualification) { msg = diag::err_bad_lvalue_to_rvalue_cast; diff --git a/test/CXX/expr/expr.cast/p4-0x.cpp b/test/CXX/expr/expr.cast/p4-0x.cpp new file mode 100644 index 0000000000..5824cd21f1 --- /dev/null +++ b/test/CXX/expr/expr.cast/p4-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +struct X { }; +struct Y : X { }; + +void test_lvalue_to_rvalue_drop_cvquals(const X &x, const Y &y, const int &i) { + (void)(X&&)x; + (void)(int&&)i; + (void)(X&&)y; + (void)(Y&&)x; +} -- 2.40.0