зеркало из https://github.com/microsoft/clang-1.git
Extend the "cannot convert from base class pointer to derived class
pointer" diagnostic to handle references, too. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107372 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
63cbbeecba
Коммит
2f9d8740f5
|
@ -1203,14 +1203,16 @@ def note_ovl_candidate_bad_cvr : Note<"candidate "
|
||||||
"%select{const|volatile|const and volatile|restrict|const and restrict|"
|
"%select{const|volatile|const and volatile|restrict|const and restrict|"
|
||||||
"volatile and restrict|const, volatile, and restrict}3 qualifier"
|
"volatile and restrict|const, volatile, and restrict}3 qualifier"
|
||||||
"%select{||s||s|s|s}3">;
|
"%select{||s||s|s|s}3">;
|
||||||
def note_ovl_candidate_bad_base_to_derived_ptr_conv : Note<"candidate "
|
def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate "
|
||||||
"%select{function|function|constructor|"
|
"%select{function|function|constructor|"
|
||||||
"function |function |constructor |"
|
"function |function |constructor |"
|
||||||
"constructor (the implicit default constructor)|"
|
"constructor (the implicit default constructor)|"
|
||||||
"constructor (the implicit copy constructor)|"
|
"constructor (the implicit copy constructor)|"
|
||||||
"function (the implicit copy assignment operator)}0%1"
|
"function (the implicit copy assignment operator)}0%1"
|
||||||
" not viable: cannot convert from base class pointer %2 to derived class "
|
" not viable: cannot %select{convert from|convert from|bind}2 "
|
||||||
"pointer %3 for %ordinal4 argument">;
|
"%select{base class pointer|superclass|base class object of type}2 %3 to "
|
||||||
|
"%select{derived class pointer|subclass|derived class reference}2 %4 for "
|
||||||
|
"%ordinal5 argument">;
|
||||||
|
|
||||||
def note_ambiguous_type_conversion: Note<
|
def note_ambiguous_type_conversion: Note<
|
||||||
"because of ambiguity in conversion of %0 to %1">;
|
"because of ambiguity in conversion of %0 to %1">;
|
||||||
|
|
|
@ -5486,7 +5486,7 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diagnose base -> derived pointer conversions.
|
// Diagnose base -> derived pointer conversions.
|
||||||
bool IsBaseToDerivedConversion = false;
|
unsigned BaseToDerivedConversion = 0;
|
||||||
if (const PointerType *FromPtrTy = FromTy->getAs<PointerType>()) {
|
if (const PointerType *FromPtrTy = FromTy->getAs<PointerType>()) {
|
||||||
if (const PointerType *ToPtrTy = ToTy->getAs<PointerType>()) {
|
if (const PointerType *ToPtrTy = ToTy->getAs<PointerType>()) {
|
||||||
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
||||||
|
@ -5495,7 +5495,7 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
|
||||||
!ToPtrTy->getPointeeType()->isIncompleteType() &&
|
!ToPtrTy->getPointeeType()->isIncompleteType() &&
|
||||||
S.IsDerivedFrom(ToPtrTy->getPointeeType(),
|
S.IsDerivedFrom(ToPtrTy->getPointeeType(),
|
||||||
FromPtrTy->getPointeeType()))
|
FromPtrTy->getPointeeType()))
|
||||||
IsBaseToDerivedConversion = true;
|
BaseToDerivedConversion = 1;
|
||||||
}
|
}
|
||||||
} else if (const ObjCObjectPointerType *FromPtrTy
|
} else if (const ObjCObjectPointerType *FromPtrTy
|
||||||
= FromTy->getAs<ObjCObjectPointerType>()) {
|
= FromTy->getAs<ObjCObjectPointerType>()) {
|
||||||
|
@ -5506,13 +5506,21 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
|
||||||
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
if (ToPtrTy->getPointeeType().isAtLeastAsQualifiedAs(
|
||||||
FromPtrTy->getPointeeType()) &&
|
FromPtrTy->getPointeeType()) &&
|
||||||
FromIface->isSuperClassOf(ToIface))
|
FromIface->isSuperClassOf(ToIface))
|
||||||
IsBaseToDerivedConversion = true;
|
BaseToDerivedConversion = 2;
|
||||||
|
} else if (const ReferenceType *ToRefTy = ToTy->getAs<ReferenceType>()) {
|
||||||
|
if (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) &&
|
||||||
|
!FromTy->isIncompleteType() &&
|
||||||
|
!ToRefTy->getPointeeType()->isIncompleteType() &&
|
||||||
|
S.IsDerivedFrom(ToRefTy->getPointeeType(), FromTy))
|
||||||
|
BaseToDerivedConversion = 3;
|
||||||
}
|
}
|
||||||
if (IsBaseToDerivedConversion) {
|
|
||||||
|
if (BaseToDerivedConversion) {
|
||||||
S.Diag(Fn->getLocation(),
|
S.Diag(Fn->getLocation(),
|
||||||
diag::note_ovl_candidate_bad_base_to_derived_ptr_conv)
|
diag::note_ovl_candidate_bad_base_to_derived_conv)
|
||||||
<< (unsigned) FnKind << FnDesc
|
<< (unsigned) FnKind << FnDesc
|
||||||
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
|
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
|
||||||
|
<< (BaseToDerivedConversion - 1)
|
||||||
<< FromTy << ToTy << I+1;
|
<< FromTy << ToTy << I+1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,12 @@ void intref_test() {
|
||||||
float* ir2 = intref(5.5);
|
float* ir2 = intref(5.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void derived5(C&); // expected-note{{candidate function not viable: cannot bind base class object of type 'A' to derived class reference 'C &' for 1st argument}}
|
||||||
|
|
||||||
|
void test_base(A& a) {
|
||||||
|
derived5(a); // expected-error{{no matching function for call to 'derived5}}
|
||||||
|
}
|
||||||
|
|
||||||
// Test reference binding vs. standard conversions.
|
// Test reference binding vs. standard conversions.
|
||||||
int& bind_vs_conv(const double&);
|
int& bind_vs_conv(const double&);
|
||||||
float& bind_vs_conv(int);
|
float& bind_vs_conv(int);
|
||||||
|
|
|
@ -39,7 +39,7 @@ void foo(const I *p, I* sel) {
|
||||||
@interface DerivedFromI : I
|
@interface DerivedFromI : I
|
||||||
@end
|
@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 accept_derived(DerivedFromI*); // expected-note{{candidate function not viable: cannot convert from superclass 'I *' to subclass 'DerivedFromI *' for 1st argument}}
|
||||||
|
|
||||||
void test_base_to_derived(I* i) {
|
void test_base_to_derived(I* i) {
|
||||||
accept_derived(i); // expected-error{{no matching function for call to 'accept_derived'}}
|
accept_derived(i); // expected-error{{no matching function for call to 'accept_derived'}}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче