[cfe-commits] r81870 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp test/SemaCXX/conversion-delete-expr.cpp test/SemaCXX/new-delete.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Sep 15 10:21:47 PDT 2009


Author: fjahanian
Date: Tue Sep 15 12:21:47 2009
New Revision: 81870

URL: http://llvm.org/viewvc/llvm-project?rev=81870&view=rev
Log:
Perform overload resolution when selecting a pointer conversion
function for delete of a class expression and issue
good diagnostic when result is ambiguous.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
    cfe/trunk/test/SemaCXX/new-delete.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81870&r1=81869&r2=81870&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 15 12:21:47 2009
@@ -1558,6 +1558,8 @@
 def err_new_uninitialized_const : Error<
   "must provide an initializer if the allocated object is 'const'">;
 def err_delete_operand : Error<"cannot delete expression of type %0">;
+def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
+                                         "expression of type %0 to a pointer">;
 def warn_delete_incomplete : Warning<
   "deleting pointer to incomplete type %0 may cause undefined behaviour">;
 def err_decrement_bool : Error<"cannot decrement expression of type bool">;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Sep 15 12:21:47 2009
@@ -736,6 +736,7 @@
     QualType Type = Ex->getType();
 
     if (const RecordType *Record = Type->getAs<RecordType>()) {
+      OverloadCandidateSet CandidateSet;
       llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
       OverloadedFunctionDecl *Conversions = 
@@ -754,20 +755,32 @@
         QualType ConvType = Conv->getConversionType().getNonReferenceType();
         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
           if (ConvPtrType->getPointeeType()->isObjectType())
-            ObjectPtrConversions.push_back(Conv);
+            AddConversionCandidate(Conv, Ex, ConvType, CandidateSet);
       }
-      
-      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"))
+      OverloadCandidateSet::iterator Best;
+      switch (BestViableFunction(CandidateSet, Ex->getLocStart(), Best)) {
+        case OR_Success:
+          {
+            Operand.release();
+            CXXConversionDecl *Conversion
+              = cast<CXXConversionDecl>(Best->Function);
+            if (PerformImplicitConversion(Ex, 
+                                          Conversion->getConversionType(), 
+                                          "converting"))
+              return ExprError();
+            
+            Operand = Owned(Ex);
+            Type = Ex->getType();
+            break;
+          }
+        case OR_No_Viable_Function:
+        case OR_Deleted:
+          break;  // Will issue error below.
+        case OR_Ambiguous:
+          Diag(StartLoc, diag::err_ambiguous_delete_operand)
+                  << Type << Ex->getSourceRange();
+          PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
           return ExprError();
-        
-        Operand = Owned(Ex);
-        Type = Ex->getType();
       }
     }
 

Modified: cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp?rev=81870&r1=81869&r2=81870&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp Tue Sep 15 12:21:47 2009
@@ -2,16 +2,16 @@
 
 // Test1
 struct B {
-  operator char *();
+  operator char *(); // expected-note {{candidate function}}
 };
 
 struct D : B {
-  operator int *();
+  operator int *(); // expected-note {{candidate function}}
 };
 
 void f (D d)
 {
-   delete d; // expected-error {{cannot delete expression of type 'struct D'}}
+   delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D' to a pointer}}
 }
 
 // Test2
@@ -30,25 +30,25 @@
 
 // Test3
 struct B2 {
-  operator const int *();
+  operator const int *();	// expected-note {{candidate function}}
 };
 
 struct D2 : B2 {
-  operator int *();
+  operator int *();	// expected-note {{candidate function}}
 };
 
 void f2 (D2 d)
 {
-   delete d; // expected-error {{cannot delete expression of type 'struct D2'}}
+   delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D2' to a pointer}}
 }
 
 // Test4
 struct B3 {
-  operator const int *();
+  operator const int *();	// expected-note {{candidate function}}
 };
 
 struct A3 {
-  operator const int *();
+  operator const int *();	// expected-note {{candidate function}}
 };
 
 struct D3 : A3, B3 {
@@ -56,7 +56,7 @@
 
 void f3 (D3 d)
 {
-   delete d; // expected-error {{cannot delete expression of type 'struct D3'}}
+   delete d; // expected-error {{mbiguous conversion of delete expression of type 'struct D3' to a pointer}}
 }
 
 // Test5
@@ -78,16 +78,19 @@
 
 // Test7
 struct Base {
-   operator int*();
+   operator int*();	// expected-note {{candidate function}}
 };
 
 struct Derived : Base {
-   operator int*() const; // not the same function as Base's non-const operator int()
+   // not the same function as Base's non-const operator int()
+   operator int*() const;  // expected-note {{candidate function}}
 };
 
-void foo6(const Derived cd) {
-	// FIXME. overload resolution must select Derived::operator int*() const;
-	delete cd;	// expected-error {{cannot delete expression of type 'struct Derived const'}}
+void foo6(const Derived cd, Derived d) {
+	// overload resolution selects Derived::operator int*() const;
+	delete cd;
+
+	delete d;	// expected-error {{ambiguous conversion of delete expression of type 'struct Derived' to a pointer}}
 }
 
 // Test8
@@ -105,7 +108,3 @@
         // OK. In selecting a conversion to pointer function, template convesions are skipped.
 	delete d;
 }
-
-
-
-

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

==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Tue Sep 15 12:21:47 2009
@@ -104,12 +104,12 @@
 };
 
 struct X2 {
-  operator int*();
-  operator float*();
+  operator int*(); // expected-note {{candidate function}}
+  operator float*(); // expected-note {{candidate function}}
 };
 
 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
+  delete x2; // expected-error{{ambiguous conversion of delete expression of type 'struct X2' to a pointer}}
+}





More information about the cfe-commits mailing list