diff options
author | Kaelyn Uhrain <rikka@google.com> | 2012-06-19 00:37:47 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2012-06-19 00:37:47 +0000 |
commit | 9ea8f7e6c53fa6b6fbfab811578ec0e16153707f (patch) | |
tree | c628e3dbcbec3682bae999f455bf2eb53fb3be6b /clang/lib | |
parent | 9dcc0325de8df0624591b0501ec8f6409d0a7777 (diff) | |
download | bcm5719-llvm-9ea8f7e6c53fa6b6fbfab811578ec0e16153707f.tar.gz bcm5719-llvm-9ea8f7e6c53fa6b6fbfab811578ec0e16153707f.zip |
Improve the error message when a function overload candidate is rejected
because it expects a reference and receives a non-l-value.
For example, given:
int foo(int &);
template<int x> void b() { foo(x); }
clang will now print "expects an l-value for 1st argument" instead of
"no known conversion from 'int' to 'int &' for 1st argument". The change
in wording (and associated code to detect the case) was prompted by
comment #5 in PR3104, and should be the last bit of work needed for the
bug.
llvm-svn: 158691
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f73c5c1f35d..6e62af5bfe4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8153,12 +8153,27 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) { FromIface->isSuperClassOf(ToIface)) 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 (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) && + !FromTy->isIncompleteType() && + !ToRefTy->getPointeeType()->isIncompleteType() && + S.IsDerivedFrom(ToRefTy->getPointeeType(), FromTy)) { + BaseToDerivedConversion = 3; + } else if (ToTy->isLValueReferenceType() && !FromExpr->isLValue() && + ToTy.getNonReferenceType().getCanonicalType() == + FromTy.getNonReferenceType().getCanonicalType()) { + QualType T1 = ToTy.getCanonicalType(); + QualType T2 = ToTy.getNonReferenceType(); + QualType T3 = T2.getUnqualifiedType(); + QualType T4 = FromTy.getCanonicalType(); + (void)T1; (void)T2; (void)T3; (void)T4; + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_lvalue) + << (unsigned) FnKind << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) + << (unsigned) isObjectArgument << I + 1; + MaybeEmitInheritedConstructorNote(S, Fn); + return; } + } if (BaseToDerivedConversion) { S.Diag(Fn->getLocation(), |