forked from OSchip/llvm-project
PR5941 - improve diagnostic for * vs & confusion when choosing overload candidate with a parameter of incomplete (ref or pointer) type
Reviewers: dblaikie Differential Revision: http://reviews.llvm.org/D16949 llvm-svn: 262752
This commit is contained in:
parent
a0c9f6e736
commit
ac92893a93
|
@ -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 |"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue