]> granicus.if.org Git - clang/commitdiff
[Sema] If lvalue to rvalue reference cast is valid don't emit diagnostic.
authorDavide Italiano <davide@freebsd.org>
Sun, 12 Jul 2015 22:10:56 +0000 (22:10 +0000)
committerDavide Italiano <davide@freebsd.org>
Sun, 12 Jul 2015 22:10:56 +0000 (22:10 +0000)
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

lib/Sema/SemaCast.cpp
test/SemaCXX/cast-lvalue-to-rvalue-reference.cpp [new file with mode: 0644]

index d9dc4df9f271a73570f78cde9d17699ceb4a027f..c0754ba7902a762947ce7164d46af456a41b4652 100644 (file)
@@ -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<RValueReferenceType>();
@@ -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 (file)
index 0000000..45e72d2
--- /dev/null
@@ -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<S&&>(x);
+S& z1 = (S&)x;