[cfe-commits] r67487 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaNamedCast.cpp test/SemaCXX/rval-references.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Sun Mar 22 15:30:07 PDT 2009
Author: cornedbee
Date: Sun Mar 22 17:30:06 2009
New Revision: 67487
URL: http://llvm.org/viewvc/llvm-project?rev=67487&view=rev
Log:
Implement static_cast from lvalue to rvalue reference.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaNamedCast.cpp
cfe/trunk/test/SemaCXX/rval-references.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=67487&r1=67486&r2=67487&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Mar 22 17:30:06 2009
@@ -1010,6 +1010,9 @@
"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<
Modified: cfe/trunk/lib/Sema/SemaNamedCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaNamedCast.cpp?rev=67487&r1=67486&r2=67487&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaNamedCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaNamedCast.cpp Sun Mar 22 17:30:06 2009
@@ -39,6 +39,8 @@
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 @@
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 @@
<< 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,
Modified: cfe/trunk/test/SemaCXX/rval-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/rval-references.cpp?rev=67487&r1=67486&r2=67487&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/rval-references.cpp (original)
+++ cfe/trunk/test/SemaCXX/rval-references.cpp Sun Mar 22 17:30:06 2009
@@ -28,6 +28,8 @@
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);
More information about the cfe-commits
mailing list