From f7272c8a038847cf67e888828e58fc0e00d1f5d5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 21 May 2020 10:27:11 -0400 Subject: [PATCH] c++: Improve error-recovery for parms. If a parameter is erroneous, we currently drop it, leading to "too many arguments" errors later. Treating the function as (...) avoids those errors. gcc/cp/ChangeLog: * decl.c (grokparms): Return NULL_TREE if any parms were erroneous. gcc/testsuite/ChangeLog: * g++.dg/parse/error33.C: Adjust. --- gcc/cp/decl.c | 18 +++++++++++++----- gcc/testsuite/g++.dg/parse/error33.C | 4 ++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 024ddc88a4c..a389579ee52 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13961,7 +13961,10 @@ grokparms (tree parmlist, tree *parms) break; if (! decl || TREE_TYPE (decl) == error_mark_node) - continue; + { + any_error = 1; + continue; + } type = TREE_TYPE (decl); if (VOID_TYPE_P (type)) @@ -14014,7 +14017,8 @@ grokparms (tree parmlist, tree *parms) TREE_TYPE (decl) = type; } else if (abstract_virtuals_error (decl, type)) - any_error = 1; /* Seems like a good idea. */ + /* Ignore any default argument. */ + init = NULL_TREE; else if (cxx_dialect < cxx17 && INDIRECT_TYPE_P (type)) { /* Before C++17 DR 393: @@ -14043,9 +14047,7 @@ grokparms (tree parmlist, tree *parms) decl, t); } - if (any_error) - init = NULL_TREE; - else if (init && !processing_template_decl) + if (init && !processing_template_decl) init = check_default_argument (decl, init, tf_warning_or_error); } @@ -14058,6 +14060,12 @@ grokparms (tree parmlist, tree *parms) if (parm) result = chainon (result, void_list_node); *parms = decls; + if (any_error) + result = NULL_TREE; + + if (any_error) + /* We had parm errors, recover by giving the function (...) type. */ + result = NULL_TREE; return result; } diff --git a/gcc/testsuite/g++.dg/parse/error33.C b/gcc/testsuite/g++.dg/parse/error33.C index 0d25386a879..61b0cc3f2dc 100644 --- a/gcc/testsuite/g++.dg/parse/error33.C +++ b/gcc/testsuite/g++.dg/parse/error33.C @@ -8,9 +8,9 @@ struct A typedef void (A::T)(); /* { dg-error "15:typedef name may not be a nested" } */ -void bar(T); /* { dg-message "note: declared here" } */ +void bar(T); void baz() { - bar(&A::foo); /* { dg-error "too many arguments" } */ + bar(&A::foo); } -- 2.30.2