[cfe-commits] r58762 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/SemaCXX/static-cast.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Wed Nov 5 09:54:27 PST 2008


Author: cornedbee
Date: Wed Nov  5 11:54:26 2008
New Revision: 58762

URL: http://llvm.org/viewvc/llvm-project?rev=58762&view=rev
Log:
A small error message improvement and some comment cleanup for static_cast.

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/static-cast.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=58762&r1=58761&r2=58762&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Nov  5 11:54:26 2008
@@ -340,12 +340,18 @@
 Sema::CheckStaticCast(Expr *&SrcExpr, QualType DestType,
                       const SourceRange &OpRange)
 {
-  // Conversions are tried roughly in the order the standard specifies them.
-  // This is necessary because there are some conversions that can be
-  // interpreted in more than one way, and the order disambiguates.
-  // DR 427 specifies that paragraph 5 is to be applied before paragraph 2.
+  // The order the tests is not entirely arbitrary. There is one conversion
+  // that can be handled in two different ways. Given:
+  // struct A {};
+  // struct B : public A {
+  //   B(); B(const A&);
+  // };
+  // const A &a = B();
+  // the cast static_cast<const B&>(a) could be seen as either a static
+  // reference downcast, or an explicit invocation of the user-defined
+  // conversion using B's conversion constructor.
+  // DR 427 specifies that the downcast is to be applied here.
 
-  // This option is unambiguous and simple, so put it here.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   if (DestType->isVoidType()) {
     return;
@@ -353,6 +359,7 @@
 
   // C++ 5.2.9p5, reference downcast.
   // See the function for details.
+  // DR 427 specifies that this is to be applied before paragraph 2.
   if (IsStaticReferenceDowncast(SrcExpr, DestType)) {
     return;
   }
@@ -361,15 +368,17 @@
   //   [...] if the declaration "T t(e);" is well-formed, [...].
   ImplicitConversionSequence ICS = TryDirectInitialization(SrcExpr, DestType);
   if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion) {
-    if (ICS.ConversionKind == ImplicitConversionSequence::StandardConversion &&
-        ICS.Standard.First != ICK_Identity)
-    {
+    assert(ICS.ConversionKind != ImplicitConversionSequence::EllipsisConversion
+      && "Direct initialization cannot result in ellipsis conversion");
+    // UserDefinedConversionSequence has a StandardConversionSequence as a
+    // prefix. Accessing Standard is therefore safe.
+    // FIXME: Of course, this is definitely not enough.
+    if(ICS.Standard.First != ICK_Identity) {
       DefaultFunctionArrayConversion(SrcExpr);
     }
+    // FIXME: Test the details, such as accessible base.
     return;
   }
-  // FIXME: Missing the validation of the conversion, e.g. for an accessible
-  // base.
 
   // C++ 5.2.9p6: May apply the reverse of any standard conversion, except
   // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
@@ -419,9 +428,14 @@
     if (SrcPointee->isVoidType()) {
       if (const PointerType *DestPointer = DestType->getAsPointerType()) {
         QualType DestPointee = DestPointer->getPointeeType();
-        if (DestPointee->isObjectType() &&
-            DestPointee.isAtLeastAsQualifiedAs(SrcPointee))
-        {
+        if (DestPointee->isObjectType()) {
+          // This is definitely the intended conversion, but it might fail due
+          // to a const violation.
+          if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
+            Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away,
+              "static_cast", DestType.getAsString(),
+              OrigSrcType.getAsString(), OpRange);
+          }
           return;
         }
       }

Modified: cfe/trunk/test/SemaCXX/static-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/static-cast.cpp?rev=58762&r1=58761&r2=58762&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/static-cast.cpp (original)
+++ cfe/trunk/test/SemaCXX/static-cast.cpp Wed Nov  5 11:54:26 2008
@@ -113,7 +113,7 @@
 
   // Bad code below
 
-  (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' is not allowed}}
+  (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}}
   (void)static_cast<void (*)()>((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)(void)' is not allowed}}
 }
 





More information about the cfe-commits mailing list