[cfe-commits] r81401 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/SemaCXX/new-delete.cpp

Douglas Gregor dgregor at apple.com
Wed Sep 9 16:39:55 PDT 2009


Author: dgregor
Date: Wed Sep  9 18:39:55 2009
New Revision: 81401

URL: http://llvm.org/viewvc/llvm-project?rev=81401&view=rev
Log:
For a C++ delete expression where the operand is of class type that
has a single conversion to pointer-to-object type, implicitly convert
to that pointer-to-object type (C++ [expr.delete]p1).


Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/new-delete.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Sep  9 18:39:55 2009
@@ -717,9 +717,10 @@
 Action::OwningExprResult
 Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
                      bool ArrayForm, ExprArg Operand) {
-  // C++ 5.3.5p1: "The operand shall have a pointer type, or a class type
-  //   having a single conversion function to a pointer type. The result has
-  //   type void."
+  // C++ [expr.delete]p1:
+  //   The operand shall have a pointer type, or a class type having a single
+  //   conversion function to a pointer type. The result has type void.
+  //
   // DR599 amends "pointer type" to "pointer to object type" in both cases.
 
   FunctionDecl *OperatorDelete = 0;
@@ -728,8 +729,40 @@
   if (!Ex->isTypeDependent()) {
     QualType Type = Ex->getType();
 
-    if (Type->isRecordType()) {
-      // FIXME: Find that one conversion function and amend the type.
+    if (const RecordType *Record = Type->getAs<RecordType>()) {
+      // FIXME: Inherited conversion functions!
+      llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
+      
+      OverloadedFunctionDecl *Conversions
+        = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
+      for (OverloadedFunctionDecl::function_iterator
+             Func = Conversions->function_begin(),
+             FuncEnd = Conversions->function_end();
+           Func != FuncEnd; ++Func) {
+        // Skip over templated conversion functions; they aren't considered.
+        if (isa<FunctionTemplateDecl>(*Func))
+          continue;
+        
+        CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
+        
+        QualType ConvType = Conv->getConversionType().getNonReferenceType();
+        if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+          if (ConvPtrType->getPointeeType()->isObjectType())
+            ObjectPtrConversions.push_back(Conv);
+      }
+      
+      if (ObjectPtrConversions.size() == 1) {
+        // We have a single conversion to a pointer-to-object type. Perform
+        // that conversion.
+        Operand.release();
+        if (PerformImplicitConversion(Ex, 
+                            ObjectPtrConversions.front()->getConversionType(), 
+                                      "converting"))
+          return ExprError();
+        
+        Operand = Owned(Ex);
+        Type = Ex->getType();
+      }
     }
 
     if (!Type->isPointerType())

Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=81401&r1=81400&r2=81401&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Wed Sep  9 18:39:55 2009
@@ -95,3 +95,21 @@
   delete (T*)0; // expected-warning {{deleting pointer to incomplete type}}
   ::S::delete (int*)0; // expected-error {{expected unqualified-id}}
 }
+
+struct X0 { };
+
+struct X1 {
+  operator int*();
+  operator float();
+};
+
+struct X2 {
+  operator int*();
+  operator float*();
+};
+
+void test_delete_conv(X0 x0, X1 x1, X2 x2) {
+  delete x0; // expected-error{{cannot delete}}
+  delete x1;
+  delete x2; // expected-error{{cannot delete}}
+}
\ No newline at end of file





More information about the cfe-commits mailing list