aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-09-15 22:15:23 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-09-15 22:15:23 +0000
commit8b915e7048b20b0feb60ec90c365a8eb68360cd4 (patch)
tree10ef5cafce0554184195e95619ad0d59c898dd10
parent13392aa6895bcdbbec4aa4abe48fb3d709f1e596 (diff)
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
-rw-r--r--lib/AST/DeclCXX.cpp5
-rw-r--r--lib/Sema/SemaExprCXX.cpp46
-rw-r--r--test/SemaCXX/conversion-delete-expr.cpp7
-rw-r--r--test/SemaCXX/direct-initializer.cpp8
4 files changed, 30 insertions, 36 deletions
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<FunctionDecl>(TopConv)->getType());
+ cast<CXXConversionDecl>(TopConv)->getConversionType());
TopConversionsTypeSet.insert(TConvType);
}
}
@@ -334,7 +334,8 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
ConversionTemplate->getTemplatedDecl()->getType());
else
ConvType =
- getASTContext().getCanonicalType(cast<FunctionDecl>(Conv)->getType());
+ getASTContext().getCanonicalType(
+ cast<CXXConversionDecl>(Conv)->getConversionType());
if (inTopClass || !TopConversionsTypeSet.count(ConvType)) {
if (FunctionTemplateDecl *ConversionTemplate =
dyn_cast<FunctionTemplateDecl>(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<RecordType>()) {
- OverloadCandidateSet CandidateSet;
llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(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<PointerType>())
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<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();
+ 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;
}