Author: ericwf Date: Fri Feb 1 14:06:02 2019 New Revision: 352927 URL: http://llvm.org/viewvc/llvm-project?rev=352927&view=rev Log: Improve diagnostic to tell you a type is incomplete.
I recently ran into this code: ``` \#include <iostream> void foo(const std::string &s, const std::string& = ""); \#include <string> void test() { foo(""); } ``` The diagnostic produced said it can't bind char[1] to std::string const&. It didn't mention std::string is incomplete. The user had to infer that. This patch causes the diagnostic to now say "incomplete type". Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp cfe/trunk/test/SemaCXX/decl-init-ref.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=352927&r1=352926&r2=352927&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb 1 14:06:02 2019 @@ -1828,8 +1828,9 @@ def err_reference_bind_drops_quals : Err "'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|" "'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">; def err_reference_bind_failed : Error< - "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of " - "type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">; + "reference %diff{to %select{type|incomplete type}1 $ could not bind to an " + "%select{rvalue|lvalue}2 of type $|could not bind to %select{rvalue|lvalue}2 of " + "incompatible type}0,3">; def err_reference_bind_init_list : Error< "reference to type %0 cannot bind to an initializer list">; def err_init_list_bad_dest_type : Error< Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=352927&r1=352926&r2=352927&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Feb 1 14:06:02 2019 @@ -8450,6 +8450,7 @@ bool InitializationSequence::Diagnose(Se case FK_ReferenceInitFailed: S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) << DestType.getNonReferenceType() + << DestType.getNonReferenceType()->isIncompleteType() << OnlyArg->isLValue() << OnlyArg->getType() << Args[0]->getSourceRange(); Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=352927&r1=352926&r2=352927&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Fri Feb 1 14:06:02 2019 @@ -327,7 +327,7 @@ namespace update_rbrace_loc_crash { struct A {}; template <typename T, typename F, int... I> std::initializer_list<T> ExplodeImpl(F p1, A<int, I...>) { - // expected-error@+1 {{reference to type 'const update_rbrace_loc_crash::Incomplete' could not bind to an rvalue of type 'void'}} + // expected-error@+1 {{reference to incomplete type 'const update_rbrace_loc_crash::Incomplete' could not bind to an rvalue of type 'void'}} return {p1(I)...}; } template <typename T, int N, typename F> Modified: cfe/trunk/test/SemaCXX/decl-init-ref.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-init-ref.cpp?rev=352927&r1=352926&r2=352927&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/decl-init-ref.cpp (original) +++ cfe/trunk/test/SemaCXX/decl-init-ref.cpp Fri Feb 1 14:06:02 2019 @@ -36,3 +36,12 @@ namespace PR16502 { int f(); const A &c = { 10, ++c.temporary }; } + +namespace IncompleteTest { + struct String; + // expected-error@+1 {{reference to incomplete type 'const IncompleteTest::String' could not bind to an lvalue of type 'const char [1]'}} + void takeString(const String& = "") {} // expected-note {{passing argument to parameter here}} expected-note {{candidate function}} + void test() { + takeString(); // expected-error {{no matching function for call}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits