Hi,

Attached is a patch that fixes a few places where TryCopyInitialization is too lax and allows casts that it shouldn't. In particular, it would allow integral/floating/enum to enum, and - because isNullPointerConstant used C semantics and treated (void*)0 as a null pointer constant, it allowed the expression static_cast<some pointer type>((void*)0).

This patch is in preparation of my work on static_cast, which will follow as soon as I've got a few remaining points implemented.

Please approve for committing.

Sebastian
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp    (revision 58135)
+++ lib/AST/Expr.cpp    (working copy)
@@ -1045,15 +1045,17 @@
 /// integer constant expression with the value zero, or if this is one that is
 /// cast to void*.
 bool Expr::isNullPointerConstant(ASTContext &Ctx) const {
-  // Strip off a cast to void*, if it exists.
+  // Strip off a cast to void*, if it exists. Except in C++.
   if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
-    // Check that it is a cast to void*.
-    if (const PointerType *PT = CE->getType()->getAsPointerType()) {
-      QualType Pointee = PT->getPointeeType();
-      if (Pointee.getCVRQualifiers() == 0 && 
-          Pointee->isVoidType() &&                                 // to void*
-          CE->getSubExpr()->getType()->isIntegerType())            // from int.
-        return CE->getSubExpr()->isNullPointerConstant(Ctx);
+    if(!Ctx.getLangOptions().CPlusPlus) {
+      // Check that it is a cast to void*.
+      if (const PointerType *PT = CE->getType()->getAsPointerType()) {
+        QualType Pointee = PT->getPointeeType();
+        if (Pointee.getCVRQualifiers() == 0 && 
+            Pointee->isVoidType() &&                              // to void*
+            CE->getSubExpr()->getType()->isIntegerType())         // from int.
+          return CE->getSubExpr()->isNullPointerConstant(Ctx);
+      }
     }
   } else if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(this)) {
     // Ignore the ImplicitCastExpr type entirely.
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp   (revision 58135)
+++ lib/Sema/SemaOverload.cpp   (working copy)
@@ -447,8 +447,9 @@
     FromType = ToType.getUnqualifiedType();
   } 
   // Integral conversions (C++ 4.7).
+  // FIXME: isIntegralType shouldn't be true for enums in C++.
   else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
-           (ToType->isIntegralType() || ToType->isEnumeralType())) {
+           (ToType->isIntegralType() && !ToType->isEnumeralType())) {
     ICS.Standard.Second = ICK_Integral_Conversion;
     FromType = ToType.getUnqualifiedType();
   }
@@ -458,8 +459,10 @@
     FromType = ToType.getUnqualifiedType();
   }
   // Floating-integral conversions (C++ 4.9).
+  // FIXME: isIntegralType shouldn't be true for enums in C++.
   else if ((FromType->isFloatingType() &&
-            ToType->isIntegralType() && !ToType->isBooleanType()) ||
+            ToType->isIntegralType() && !ToType->isBooleanType() &&
+                                        !ToType->isEnumeralType()) ||
            ((FromType->isIntegralType() || FromType->isEnumeralType()) && 
             ToType->isFloatingType())) {
     ICS.Standard.Second = ICK_Floating_Integral;
@@ -507,13 +510,16 @@
 bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
 {
   const BuiltinType *To = ToType->getAsBuiltinType();
+  if (!To) {
+    return false;
+  }
 
   // An rvalue of type char, signed char, unsigned char, short int, or
   // unsigned short int can be converted to an rvalue of type int if
   // int can represent all the values of the source type; otherwise,
   // the source rvalue can be converted to an rvalue of type unsigned
   // int (C++ 4.5p1).
-  if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() && To) 
{
+  if (FromType->isPromotableIntegerType() && !FromType->isBooleanType()) {
     if (// We can promote any signed, promotable integer type to an int
         (FromType->isSignedIntegerType() ||
          // We can promote any unsigned integer type whose size is
@@ -635,7 +641,7 @@
     ConvertedType = ToType;
     return true;
   }
-  
+
   // An rvalue of type "pointer to cv T," where T is an object type,
   // can be converted to an rvalue of type "pointer to cv void" (C++
   // 4.10p2).
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to