[cfe-commits] r124189 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/CodeGenCXX/rvalue-references.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 25 08:13:26 PST 2011


Author: dgregor
Date: Tue Jan 25 10:13:26 2011
New Revision: 124189

URL: http://llvm.org/viewvc/llvm-project?rev=124189&view=rev
Log:
When performing a glvalue-to-xvalue static_cast that involves a
derived-to-base conversion, set the cast kind and base path
appropriately.

Added:
    cfe/trunk/test/CodeGenCXX/rvalue-references.cpp
Modified:
    cfe/trunk/lib/Sema/SemaCXXCast.cpp

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=124189&r1=124188&r2=124189&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Tue Jan 25 10:13:26 2011
@@ -78,7 +78,9 @@
 // %1: Source Type
 // %2: Destination Type
 static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
-                                           QualType DestType, unsigned &msg);
+                                           QualType DestType, CastKind &Kind,
+                                           CXXCastPath &BasePath,
+                                           unsigned &msg);
 static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
                                                QualType DestType, bool CStyle,
                                                const SourceRange &OpRange,
@@ -581,11 +583,9 @@
   // 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, msg);
-  if (tcr != TC_NotApplicable) {
-    Kind = CK_NoOp;
+  tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, Kind, BasePath, msg);
+  if (tcr != TC_NotApplicable)
     return tcr;
-  }
 
   // C++ 5.2.9p2: An expression e can be explicitly converted to a type T
   //   [...] if the declaration "T t(e);" is well-formed, [...].
@@ -695,7 +695,7 @@
 /// Tests whether a conversion according to N2844 is valid.
 TryCastResult
 TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
-                      unsigned &msg) {
+                      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".
@@ -719,6 +719,17 @@
     return TC_Failed;
   }
 
+  if (DerivedToBase) {
+    Kind = CK_DerivedToBase;
+    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                       /*DetectVirtual=*/true);
+    if (!Self.IsDerivedFrom(SrcExpr->getType(), R->getPointeeType(), Paths))
+      return TC_NotApplicable;
+  
+    Self.BuildBasePathArray(Paths, BasePath);
+  } else
+    Kind = CK_NoOp;
+  
   return TC_Success;
 }
 

Added: cfe/trunk/test/CodeGenCXX/rvalue-references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rvalue-references.cpp?rev=124189&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/rvalue-references.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/rvalue-references.cpp Tue Jan 25 10:13:26 2011
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+
+struct Spacer { int x; };
+struct A { double array[2]; };
+struct B : Spacer, A { };
+
+B &getB();
+
+// CHECK: define %struct.A* @_Z4getAv()
+// CHECK: call %struct.B* @_Z4getBv()
+// CHECK-NEXT: bitcast %struct.B*
+// CHECK-NEXT: getelementptr i8*
+// CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
+// CHECK-NEXT: ret %struct.A*
+A &&getA() { return static_cast<A&&>(getB()); }
+
+int &getIntLValue();
+int &&getIntXValue();
+int getIntPRValue();
+
+// CHECK: define i32* @_Z2f0v()
+// CHECK: call i32* @_Z12getIntLValuev()
+// CHECK-NEXT: ret i32*
+int &&f0() { return static_cast<int&&>(getIntLValue()); }
+
+// CHECK: define i32* @_Z2f1v()
+// CHECK: call i32* @_Z12getIntXValuev()
+// CHECK-NEXT: ret i32*
+int &&f1() { return static_cast<int&&>(getIntXValue()); }
+
+// CHECK: define i32* @_Z2f2v
+// CHECK: call i32 @_Z13getIntPRValuev()
+// CHECK-NEXT: store i32 {{.*}}, i32*
+// CHECK-NEXT: ret i32*
+int &&f2() { return static_cast<int&&>(getIntPRValue()); }





More information about the cfe-commits mailing list