From: Fariborz Jahanian Date: Tue, 15 Sep 2009 22:15:23 +0000 (+0000) Subject: 1) don't do overload resolution in selecting conversion X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b915e7048b20b0feb60ec90c365a8eb68360cd4;p=clang 1) don't do overload resolution in selecting conversion to pointer function for delete expression. 2) Treat type conversion function and its 'const' version as identical in building the visible conversion list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81930 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 8755067137..c979acd6eb 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -314,7 +314,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) { else TConvType = getASTContext().getCanonicalType( - cast(TopConv)->getType()); + cast(TopConv)->getConversionType()); TopConversionsTypeSet.insert(TConvType); } } @@ -334,7 +334,8 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) { ConversionTemplate->getTemplatedDecl()->getType()); else ConvType = - getASTContext().getCanonicalType(cast(Conv)->getType()); + getASTContext().getCanonicalType( + cast(Conv)->getConversionType()); if (inTopClass || !TopConversionsTypeSet.count(ConvType)) { if (FunctionTemplateDecl *ConversionTemplate = dyn_cast(Conv)) diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 9005566ee4..0054af3493 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -736,7 +736,6 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, QualType Type = Ex->getType(); if (const RecordType *Record = Type->getAs()) { - OverloadCandidateSet CandidateSet; llvm::SmallVector ObjectPtrConversions; CXXRecordDecl *RD = cast(Record->getDecl()); OverloadedFunctionDecl *Conversions = @@ -755,32 +754,27 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, QualType ConvType = Conv->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs()) if (ConvPtrType->getPointeeType()->isObjectType()) - AddConversionCandidate(Conv, Ex, ConvType, CandidateSet); + ObjectPtrConversions.push_back(Conv); } - OverloadCandidateSet::iterator Best; - switch (BestViableFunction(CandidateSet, Ex->getLocStart(), Best)) { - case OR_Success: - { - Operand.release(); - CXXConversionDecl *Conversion - = cast(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(); + 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")) { + Operand = Owned(Ex); + Type = Ex->getType(); + } + } + else if (ObjectPtrConversions.size() > 1) { + Diag(StartLoc, diag::err_ambiguous_delete_operand) + << Type << Ex->getSourceRange(); + for (unsigned i= 0; i < ObjectPtrConversions.size(); i++) { + CXXConversionDecl *Conv = ObjectPtrConversions[i]; + Diag(Conv->getLocation(), diag::err_ovl_candidate); + } + return ExprError(); } } diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp index 63a9765396..708289c362 100644 --- a/test/SemaCXX/conversion-delete-expr.cpp +++ b/test/SemaCXX/conversion-delete-expr.cpp @@ -78,19 +78,18 @@ void f5(X1 x) { delete x; } // OK. In selecting a conversion to pointer functio // Test7 struct Base { - operator int*(); // expected-note {{candidate function}} + operator int*(); }; struct Derived : Base { // not the same function as Base's non-const operator int() - operator int*() const; // expected-note {{candidate function}} + operator int*() 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}} + delete d; } // Test8 diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp index e95ba22769..a9e2b2bb6e 100644 --- a/test/SemaCXX/direct-initializer.cpp +++ b/test/SemaCXX/direct-initializer.cpp @@ -36,15 +36,15 @@ void g() { } struct Base { - operator int*() const; // expected-note {{candidate function}} + operator int*() const; }; struct Derived : Base { - operator int*(); // expected-note {{candidate function}} + operator int*(); }; void foo(const Derived cd, Derived d) { - int *pi = cd; - int *ppi = d; // expected-error {{ambiguity in initializing value of type 'int *' with initializer of type 'struct Derived'}} + int *pi = cd; // expected-error {{incompatible type initializing 'struct Derived const', expected 'int *'}} + int *ppi = d; }