From e7555e42d0143f2a5ee50425902abde7c5091ad3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 13 Nov 2016 23:58:45 -0500 Subject: [PATCH] Improve various diagnostic issues. * call.c (build_new_method_call_1): Include template arguments in error message. (print_error_for_call_failure): Likewise. (build_new_function_call): Pass them in. * name-lookup.c (supplement_binding_1): Don't complain about a conflict with an erroneous declaration. * error.c (dump_decl): Fix printing of alias declaration. * decl.c (make_typename_type): Call cxx_incomplete_type_error. * parser.c (cp_parser_diagnose_invalid_type_name): Likewise. * semantics.c (perform_koenig_lookup): Don't wrap an error in TEMPLATE_ID_EXPR. From-SVN: r242376 --- gcc/cp/ChangeLog | 14 ++++++++++ gcc/cp/call.c | 31 +++++++++++++--------- gcc/cp/decl.c | 9 +++++-- gcc/cp/error.c | 4 ++- gcc/cp/name-lookup.c | 3 ++- gcc/cp/parser.c | 5 +++- gcc/cp/semantics.c | 2 +- gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C | 4 +++ gcc/testsuite/g++.dg/template/crash7.C | 2 +- gcc/testsuite/g++.dg/template/error56.C | 12 +++++++++ gcc/testsuite/g++.dg/warn/forward-inner.C | 4 +-- gcc/testsuite/g++.old-deja/g++.other/decl5.C | 2 +- .../make_signed/requirements/typedefs_neg.cc | 2 +- .../make_unsigned/requirements/typedefs_neg.cc | 2 +- 14 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C create mode 100644 gcc/testsuite/g++.dg/template/error56.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8683744..daeb517 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2016-11-13 Jason Merrill + + * call.c (build_new_method_call_1): Include template arguments in + error message. + (print_error_for_call_failure): Likewise. + (build_new_function_call): Pass them in. + * name-lookup.c (supplement_binding_1): Don't complain about a + conflict with an erroneous declaration. + * error.c (dump_decl): Fix printing of alias declaration. + * decl.c (make_typename_type): Call cxx_incomplete_type_error. + * parser.c (cp_parser_diagnose_invalid_type_name): Likewise. + * semantics.c (perform_koenig_lookup): Don't wrap an error in + TEMPLATE_ID_EXPR. + 2016-11-12 Jason Merrill CWG 2233 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0dcf322..f6f4590 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4146,8 +4146,16 @@ static void print_error_for_call_failure (tree fn, vec *args, struct z_candidate *candidates) { + tree targs = NULL_TREE; + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + { + targs = TREE_OPERAND (fn, 1); + fn = TREE_OPERAND (fn, 0); + } tree name = DECL_NAME (OVL_CURRENT (fn)); location_t loc = location_of (name); + if (targs) + name = lookup_template_function (name, targs); if (!any_strictly_viable (candidates)) error_at (loc, "no matching function for call to %<%D(%A)%>", @@ -4215,8 +4223,6 @@ build_new_function_call (tree fn, vec **args, bool koenig_p, return cp_build_function_call_vec (candidates->fn, args, complain); // Otherwise, emit notes for non-viable candidates. - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = TREE_OPERAND (fn, 0); print_error_for_call_failure (fn, *args, candidates); } result = error_mark_node; @@ -8649,19 +8655,20 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, TREE_TYPE (instance)); else { - char *pretty_name; - bool free_p; - tree arglist; - - pretty_name = name_as_c_string (name, basetype, &free_p); - arglist = build_tree_list_vec (user_args); + tree arglist = build_tree_list_vec (user_args); + tree errname = name; + if (IDENTIFIER_CTOR_OR_DTOR_P (errname)) + { + tree fn = DECL_ORIGIN (get_first_fn (fns)); + errname = DECL_NAME (fn); + } + if (explicit_targs) + errname = lookup_template_function (errname, explicit_targs); if (skip_first_for_error) arglist = TREE_CHAIN (arglist); - error ("no matching function for call to %<%T::%s(%A)%#V%>", - basetype, pretty_name, arglist, + error ("no matching function for call to %<%T::%E(%A)%#V%>", + basetype, errname, arglist, TREE_TYPE (instance)); - if (free_p) - free (pretty_name); } print_z_candidates (location_of (name), candidates); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6101504..ccd65b1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3756,8 +3756,13 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, if (!t) { if (complain & tf_error) - error (want_template ? G_("no class template named %q#T in %q#T") - : G_("no type named %q#T in %q#T"), name, context); + { + if (!COMPLETE_TYPE_P (context)) + cxx_incomplete_type_error (NULL_TREE, context); + else + error (want_template ? G_("no class template named %q#T in %q#T") + : G_("no type named %q#T in %q#T"), name, context); + } return error_mark_node; } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index aa92a7e..fe1f751 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1049,7 +1049,9 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) pp_cxx_whitespace (pp); pp_cxx_ws_string (pp, "="); pp_cxx_whitespace (pp); - dump_type (pp, DECL_ORIGINAL_TYPE (t), flags); + dump_type (pp, (DECL_ORIGINAL_TYPE (t) + ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)), + flags); break; } if ((flags & TFF_DECL_SPECIFIERS) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 8db6cfd..172ec82 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -565,7 +565,8 @@ supplement_binding_1 (cxx_binding *binding, tree decl) } else { - diagnose_name_conflict (decl, bval); + if (!error_operand_p (bval)) + diagnose_name_conflict (decl, bval); ok = false; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1efe4ea..e669c0d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3272,7 +3272,10 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, parser->scope, id, parser->scope); else if (TYPE_P (parser->scope)) { - if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) + if (!COMPLETE_TYPE_P (parser->scope)) + cxx_incomplete_type_error (location_of (id), NULL_TREE, + parser->scope); + else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) error_at (location_of (id), "%qE in %q#T does not name a template type", id, parser->scope); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1a7c478..d390bf4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2259,7 +2259,7 @@ perform_koenig_lookup (cp_expr fn, vec *args, } } - if (fn && template_id) + if (fn && template_id && fn != error_mark_node) fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args); return fn; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C new file mode 100644 index 0000000..7e894cd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-56.C @@ -0,0 +1,4 @@ +// { dg-do compile { target c++11 } } + +using I = int; // { dg-message "int" } +using I = float; // { dg-error "float" } diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C index 5bd275e..691628e 100644 --- a/gcc/testsuite/g++.dg/template/crash7.C +++ b/gcc/testsuite/g++.dg/template/crash7.C @@ -7,7 +7,7 @@ template struct A { - template A(typename A::X) {} // { dg-error "no type" } + template A(typename A::X) {} // { dg-error "incomplete" } }; // We currently don't give the "no match" error because we don't add the diff --git a/gcc/testsuite/g++.dg/template/error56.C b/gcc/testsuite/g++.dg/template/error56.C new file mode 100644 index 0000000..3eda04c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/error56.C @@ -0,0 +1,12 @@ +// Test that the error message mentions the template arguments. + +struct A +{ + template void f(T); + void f(); +}; + +int main() +{ + A().f<1>(); // { dg-error "f<1>" } +} diff --git a/gcc/testsuite/g++.dg/warn/forward-inner.C b/gcc/testsuite/g++.dg/warn/forward-inner.C index dae9948..5336d4e 100644 --- a/gcc/testsuite/g++.dg/warn/forward-inner.C +++ b/gcc/testsuite/g++.dg/warn/forward-inner.C @@ -3,13 +3,13 @@ // Verify warnings for and within classes, and by extension, struct and union. class C1; -class C1::C2; // { dg-error "does not name a type" } +class C1::C2; // { dg-error "incomplete" } class C1::C2::C3; // { dg-error "has not been declared" } class C1 { public: class C2; - class C2::C3; // { dg-error "does not name a type" } + class C2::C3; // { dg-error "incomplete" } class C2 { public: class C3; diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl5.C b/gcc/testsuite/g++.old-deja/g++.other/decl5.C index 2a7a5f2..aa2acf8 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/decl5.C +++ b/gcc/testsuite/g++.old-deja/g++.other/decl5.C @@ -19,7 +19,7 @@ struct A { struct Z; expand me; // { dg-error "'expand' does not name a type" } void foo(struct A::e); - void foo(struct A::z); // { dg-error "does not name a type" } + void foo(struct A::z); // { dg-error "incomplete" } }; struct Q; diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index 4f0720a..a659716 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -41,7 +41,7 @@ void test01() typedef make_signed::type test5_type; } -// { dg-error "does not name a type" "" { target *-*-* } 32 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 } // { dg-error "required from here" "" { target *-*-* } 34 } // { dg-error "required from here" "" { target *-*-* } 36 } // { dg-error "required from here" "" { target *-*-* } 39 } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index 8eea6b96..6a93e2f3 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -41,7 +41,7 @@ void test01() typedef make_unsigned::type test5_type; } -// { dg-error "does not name a type" "" { target *-*-* } 32 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 } // { dg-error "required from here" "" { target *-*-* } 34 } // { dg-error "required from here" "" { target *-*-* } 36 } // { dg-error "required from here" "" { target *-*-* } 39 } -- 2.7.4