This simple-minded patch extends the case where we report "no viable conversion from 'X' to 'Y'" to emit a more useful diagnostic "no viable conversion from returned value of type 'X' to function return type 'Y'" when used in that context.
In lieu of adding tests for this diagnostic explicitly, I've only updated the tests where the patch changes their result. Please review! Nick
Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td (revision 244522) +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy) @@ -5788,7 +5788,8 @@ def err_typecheck_ambiguous_condition : Error< "conversion %diff{from $ to $|between types}0,1 is ambiguous">; def err_typecheck_nonviable_condition : Error< - "no viable conversion%diff{ from $ to $|}0,1">; + "no viable conversion%select{%diff{ from $ to $|}1,2|" + "%diff{ from returned value of type $ to function return type $|}1,2}0">; def err_typecheck_nonviable_condition_incomplete : Error< "no viable conversion%diff{ from $ to incomplete type $|}0,1">; def err_typecheck_deleted_function : Error< Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp (revision 244522) +++ lib/Sema/SemaInit.cpp (working copy) @@ -6943,6 +6943,7 @@ diag::err_typecheck_nonviable_condition_incomplete, Args[0]->getType(), Args[0]->getSourceRange())) S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition) + << (Entity.getKind() == InitializedEntity::EK_Result) << Args[0]->getType() << Args[0]->getSourceRange() << DestType.getNonReferenceType(); Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp (revision 244522) +++ lib/Sema/SemaOverload.cpp (working copy) @@ -3212,7 +3212,7 @@ diag::err_typecheck_nonviable_condition_incomplete, From->getType(), From->getSourceRange())) Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition) - << From->getType() << From->getSourceRange() << ToType; + << false << From->getType() << From->getSourceRange() << ToType; } else return false; CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From); Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp =================================================================== --- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp (revision 244522) +++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp (working copy) @@ -49,7 +49,7 @@ static double dfi(int i) { return i + 3.14; } static Local localfi(int) { return Local{}; } }; - auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; //expected-error{{no viable conversion from 'Local' to 'int'}} + auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; //expected-error{{no viable conversion from returned value of type 'Local' to function return type 'int'}} l4(&Local::ifi); l4(&Local::cfi); l4(&Local::dfi); Index: test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp =================================================================== --- test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (revision 244522) +++ test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (working copy) @@ -38,7 +38,7 @@ template<typename T> int infer_result(T x, T y) { auto lambda = [=](bool b) { return x + y; }; - return lambda(true); // expected-error{{no viable conversion from 'X' to 'int'}} + return lambda(true); // expected-error{{no viable conversion from returned value of type 'X' to function return type 'int'}} } template int infer_result(int, int); Index: test/SemaCXX/rval-references.cpp =================================================================== --- test/SemaCXX/rval-references.cpp (revision 244522) +++ test/SemaCXX/rval-references.cpp (working copy) @@ -90,5 +90,5 @@ else if (0) // Copy from reference can't be elided return r; // expected-error {{call to deleted constructor}} else // Construction from different type can't be elided - return i; // expected-error {{no viable conversion from 'int' to 'MoveOnly'}} + return i; // expected-error {{no viable conversion from returned value of type 'int' to function return type 'MoveOnly'}} }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits