forked from OSchip/llvm-project
Improve diagnostic when we fail to pick an overload because it would
require a base-to-derived pointer conversion. llvm-svn: 107349
This commit is contained in:
parent
781ad17ba9
commit
56f2e34a6a
|
@ -1203,6 +1203,15 @@ def note_ovl_candidate_bad_cvr : Note<"candidate "
|
|||
"%select{const|volatile|const and volatile|restrict|const and restrict|"
|
||||
"volatile and restrict|const, volatile, and restrict}3 qualifier"
|
||||
"%select{||s||s|s|s}3">;
|
||||
def note_ovl_candidate_bad_base_to_derived_ptr_conv : Note<"candidate "
|
||||
"%select{function|function|constructor|"
|
||||
"function |function |constructor |"
|
||||
"constructor (the implicit default constructor)|"
|
||||
"constructor (the implicit copy constructor)|"
|
||||
"function (the implicit copy assignment operator)}0%1"
|
||||
" not viable: cannot convert from base class pointer %2 to derived class "
|
||||
"pointer %3 for %ordinal4 argument">;
|
||||
|
||||
def note_ambiguous_type_conversion: Note<
|
||||
"because of ambiguity in conversion of %0 to %1">;
|
||||
def note_ovl_builtin_binary_candidate : Note<
|
||||
|
|
|
@ -5485,6 +5485,38 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Diagnose base -> derived pointer conversions.
|
||||
bool IsBaseToDerivedConversion = false;
|
||||
if (const PointerType *FromPtrTy = FromTy->getAs<PointerType>()) {
|
||||
if (const PointerType *ToPtrTy = ToTy->getAs<PointerType>()) {
|
||||
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
||||
FromPtrTy->getPointeeType()) &&
|
||||
!FromPtrTy->getPointeeType()->isIncompleteType() &&
|
||||
!ToPtrTy->getPointeeType()->isIncompleteType() &&
|
||||
S.IsDerivedFrom(ToPtrTy->getPointeeType(),
|
||||
FromPtrTy->getPointeeType()))
|
||||
IsBaseToDerivedConversion = true;
|
||||
}
|
||||
} else if (const ObjCObjectPointerType *FromPtrTy
|
||||
= FromTy->getAs<ObjCObjectPointerType>()) {
|
||||
if (const ObjCObjectPointerType *ToPtrTy
|
||||
= ToTy->getAs<ObjCObjectPointerType>())
|
||||
if (const ObjCInterfaceDecl *FromIface = FromPtrTy->getInterfaceDecl())
|
||||
if (const ObjCInterfaceDecl *ToIface = ToPtrTy->getInterfaceDecl())
|
||||
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
||||
FromPtrTy->getPointeeType()) &&
|
||||
FromIface->isSuperClassOf(ToIface))
|
||||
IsBaseToDerivedConversion = true;
|
||||
}
|
||||
if (IsBaseToDerivedConversion) {
|
||||
S.Diag(Fn->getLocation(),
|
||||
diag::note_ovl_candidate_bad_base_to_derived_ptr_conv)
|
||||
<< (unsigned) FnKind << FnDesc
|
||||
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
|
||||
<< FromTy << ToTy << I+1;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: specialize more based on the kind of mismatch
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
|
||||
<< (unsigned) FnKind << FnDesc
|
||||
|
|
|
@ -219,6 +219,12 @@ void test_derived(B* b, B const* bc, C* c, const C* cc, void* v, D* d) {
|
|||
char* d8 = derived3(d);
|
||||
}
|
||||
|
||||
void derived4(C*); // expected-note{{candidate function not viable: cannot convert from base class pointer 'A *' to derived class pointer 'C *' for 1st argument}}
|
||||
|
||||
void test_base(A* a) {
|
||||
derived4(a); // expected-error{{no matching function for call to 'derived4}}
|
||||
}
|
||||
|
||||
// Test overloading of references.
|
||||
// (FIXME: tests binding to determine candidate sets, not overload
|
||||
// resolution per se).
|
||||
|
|
|
@ -36,3 +36,11 @@ void foo(const I *p, I* sel) {
|
|||
Func(p); // expected-error {{no matching function for call to 'Func'}}
|
||||
}
|
||||
|
||||
@interface DerivedFromI : I
|
||||
@end
|
||||
|
||||
void accept_derived(DerivedFromI*); // expected-note{{candidate function not viable: cannot convert from base class pointer 'I *' to derived class pointer 'DerivedFromI *' for 1st argument}}
|
||||
|
||||
void test_base_to_derived(I* i) {
|
||||
accept_derived(i); // expected-error{{no matching function for call to 'accept_derived'}}
|
||||
}
|
||||
|
|
|
@ -590,8 +590,9 @@ void g(Base *base) {
|
|||
downcast.mm:6:3: error: no matching function for call to 'f'
|
||||
f(base);
|
||||
^
|
||||
downcast.mm:4:6: note: candidate function not viable: no known conversion from
|
||||
'Base *' to 'Derived *' for 1st argument
|
||||
downcast.mm:4:6: note: candidate function not viable: cannot convert from base
|
||||
class pointer 'Base *' to derived class pointer 'Derived *' for 1st
|
||||
argument
|
||||
void f(Derived *);
|
||||
^
|
||||
</pre>
|
||||
|
|
Loading…
Reference in New Issue