[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

Douglas Gregor dgregor at apple.com
Tue Sep 15 13:23:57 PDT 2009


On Sep 15, 2009, at 10:21 AM, Fariborz Jahanian wrote:

> 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();
>       }
>     }

Why are we trying to perform overload resolution here? C++  
[expr.delete]p1 is pretty clear that delete only works when there is a  
single conversion function to a pointer-to-object type; it doesn't  
mention overload resolution at all.

	- Doug



More information about the cfe-commits mailing list