summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-06-30 23:01:39 +0000
committerDouglas Gregor <dgregor@apple.com>2010-06-30 23:01:39 +0000
commit56f2e34a6a0810f28fa4d7ab171a9e12415e29a3 (patch)
tree2ecee8ce62922483ee92a4c57e232f624ae9d451 /clang/lib
parent781ad17ba98f8ce399fe3b93da6b6ede54fef4a1 (diff)
downloadbcm5719-llvm-56f2e34a6a0810f28fa4d7ab171a9e12415e29a3.tar.gz
bcm5719-llvm-56f2e34a6a0810f28fa4d7ab171a9e12415e29a3.zip
Improve diagnostic when we fail to pick an overload because it would
require a base-to-derived pointer conversion. llvm-svn: 107349
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 4f841b06518..6335cc1fcb7 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -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
OpenPOWER on IntegriCloud