Skip to content

Commit

Permalink
PR5941 - improve diagnostic for * vs & confusion when choosing overlo…
Browse files Browse the repository at this point in the history
…ad candidate with a parameter of incomplete (ref or pointer) type

Reviewers: dblaikie

Differential Revision: http://reviews.llvm.org/D16949

llvm-svn: 262752
  • Loading branch information
dwblaikie committed Mar 4, 2016
1 parent a0c9f6e commit ac92893
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
7 changes: 6 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Expand Up @@ -3219,7 +3219,12 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
"function (the implicit move assignment operator)|"
"constructor (inherited)}0%1 "
"not viable: cannot convert argument of incomplete type "
"%diff{$ to $|to parameter type}2,3">;
"%diff{$ to $|to parameter type}2,3 for "
"%select{%ordinal5 argument|object argument}4"
"%select{|; dereference the argument with *|"
"; take the address of the argument with &|"
"; remove *|"
"; remove &}6">;
def note_ovl_candidate_bad_list_argument : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaOverload.cpp
Expand Up @@ -9131,10 +9131,13 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
if (const PointerType *PTy = TempFromTy->getAs<PointerType>())
TempFromTy = PTy->getPointeeType();
if (TempFromTy->isIncompleteType()) {
// Emit the generic diagnostic and, optionally, add the hints to it.
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
<< (unsigned) FnKind << FnDesc
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
<< FromTy << ToTy << (unsigned) isObjectArgument << I+1;
<< FromTy << ToTy << (unsigned) isObjectArgument << I+1
<< (unsigned) (Cand->Fix.Kind);

MaybeEmitInheritedConstructorNote(S, Fn);
return;
}
Expand Down
24 changes: 16 additions & 8 deletions clang/test/SemaCXX/overload-call.cpp
Expand Up @@ -375,16 +375,24 @@ namespace test2 {
}

// PR 6117
namespace test3 {
struct Base {};
namespace IncompleteConversion {
struct Complete {};
struct Incomplete;

void foo(Base *); // expected-note 2 {{cannot convert argument of incomplete type}}
void foo(Base &); // expected-note 2 {{cannot convert argument of incomplete type}}

void test(Incomplete *P) {
foo(P); // expected-error {{no matching function for call to 'foo'}}
foo(*P); // expected-error {{no matching function for call to 'foo'}}
void completeFunction(Complete *); // expected-note 2 {{cannot convert argument of incomplete type}}
void completeFunction(Complete &); // expected-note 2 {{cannot convert argument of incomplete type}}

void testTypeConversion(Incomplete *P) {
completeFunction(P); // expected-error {{no matching function for call to 'completeFunction'}}
completeFunction(*P); // expected-error {{no matching function for call to 'completeFunction'}}
}

void incompletePointerFunction(Incomplete *); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'IncompleteConversion::Incomplete' to 'IncompleteConversion::Incomplete *' for 1st argument; take the address of the argument with &}}
void incompleteReferenceFunction(Incomplete &); // expected-note {{candidate function not viable: cannot convert argument of incomplete type 'IncompleteConversion::Incomplete *' to 'IncompleteConversion::Incomplete &' for 1st argument; dereference the argument with *}}

void testPointerReferenceConversion(Incomplete &reference, Incomplete *pointer) {
incompletePointerFunction(reference); // expected-error {{no matching function for call to 'incompletePointerFunction'}}
incompleteReferenceFunction(pointer); // expected-error {{no matching function for call to 'incompleteReferenceFunction'}}
}
}

Expand Down

0 comments on commit ac92893

Please sign in to comment.