]> granicus.if.org Git - clang/commitdiff
Switch static_cast from the old reference-initialization code (via
authorDouglas Gregor <dgregor@apple.com>
Wed, 24 Mar 2010 23:38:29 +0000 (23:38 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 24 Mar 2010 23:38:29 +0000 (23:38 +0000)
CheckReferenceInit) over to the new initialization code
(InitializationSequence), which is better-tested and doesn't require
us to compute the entire conversion sequence twice.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99452 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCXXCast.cpp
test/SemaCXX/static-cast.cpp

index 014cec2b650c4439595114d2f41c4df7d49188d8..d3fe6aee5c9a1b8706682e88534833e9df7deec1 100644 (file)
@@ -913,27 +913,24 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
     // At this point of CheckStaticCast, if the destination is a reference,
     // this has to work. There is no other way that works.
     // On the other hand, if we're checking a C-style cast, we've still got
-    // the reinterpret_cast way. So in C-style mode, we first try the call
-    // with an ICS to suppress errors.
-    if (CStyle) {
-      ImplicitConversionSequence ICS;
-      if(Self.CheckReferenceInit(SrcExpr, DestType, OpRange.getBegin(),
-                                 /*SuppressUserConversions=*/false,
-                                 /*AllowExplicit=*/false, /*ForceRValue=*/false,
-                                 &ICS))
-        return TC_NotApplicable;
+    // the reinterpret_cast way.
+    InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
+    InitializationKind InitKind = InitializationKind::CreateCast(OpRange, 
+                                                                 CStyle);    
+    InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
+    if (InitSeq.getKind() == InitializationSequence::FailedSequence && CStyle)
+      return TC_NotApplicable;
+    
+    Sema::OwningExprResult Result
+      = InitSeq.Perform(Self, Entity, InitKind,
+                        Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
+    if (Result.isInvalid()) {
+      msg = 0;
+      return TC_Failed;
     }
-    // Now we're committed either way.
-    if(!Self.CheckReferenceInit(SrcExpr, DestType, OpRange.getBegin(),
-                                /*SuppressUserConversions=*/false,
-                                /*AllowExplicit=*/false,
-                                /*ForceRValue=*/false, 0,
-                                /*IgnoreBaseAccess=*/CStyle))
-      return TC_Success;
-
-    // We already got an error message.
-    msg = 0;
-    return TC_Failed;
+    
+    SrcExpr = Result.takeAs<Expr>();
+    return TC_Success;
   }
 
   if (DestType->isRecordType()) {
index 2630278d9f6b7ab61f57698b7af904f1300849eb..a5dd7e214dc288d34675718c855e64d2c122b730 100644 (file)
@@ -60,7 +60,7 @@ void t_529_2()
   (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
   (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
   (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'B **' to 'A **' is not allowed}}
-  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
+  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}}
 }
 
 // Anything to void
@@ -91,7 +91,7 @@ void t_529_5_8()
   (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *' is not allowed}}
-  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot be initialized with a value of type 'B'}}
+  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}}
 
   // TODO: Test inaccessible base in context where it's accessible, i.e.
   // member function and friend.