From patchwork Tue Mar 15 17:37:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 87020 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 9CCD3B7090 for ; Wed, 16 Mar 2011 04:38:18 +1100 (EST) Received: (qmail 26889 invoked by alias); 15 Mar 2011 17:38:08 -0000 Received: (qmail 26764 invoked by uid 22791); 15 Mar 2011 17:38:05 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 Mar 2011 17:37:53 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p2FHbqJK026586 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 15 Mar 2011 13:37:52 -0400 Received: from [127.0.0.1] (ovpn-113-56.phx2.redhat.com [10.3.113.56]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p2FHbn3T028035; Tue, 15 Mar 2011 13:37:50 -0400 Message-ID: <4D7FA3ED.2050008@redhat.com> Date: Tue, 15 Mar 2011 13:37:49 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.7 MIME-Version: 1.0 To: gcc-patches List CC: =?ISO-8859-1?Q?Manuel_L=F3pez-Ib=E1=F1ez?= Subject: C++ PATCH for c++/34758 (unclear error message about circular dependency in default arg) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Looking at the previous discussion of this PR, it seemed that the patch review stalled on the exact wording of the error message. I thought I'd pick it up again and try my hand at new wording; my take is "call to %qD uses the default argument for parameter %P, which is not yet defined" This patch also sets the default arg context when doing deferred parsing so that we can detect the circular case specifically and give a different error in that case. Tested x86_64-pc-linux-gnu, applying to trunk. commit a2857c313c01f5bba07e58ab0ff68462bb630f0d Author: Jason Merrill Date: Mon Mar 14 10:06:03 2011 -0400 PR c++/34758 * call.c (convert_default_arg): Use DECL_ORIGIN of fn. Check for recursion first. (push_defarg_context, pop_defarg_context): New. * parser.c (cp_parser_late_parsing_default_args): Use them. * cp-tree.h: Declare them. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5953e35..499ed03 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5746,10 +5746,17 @@ cxx_type_promotes_to (tree type) } /* ARG is a default argument expression being passed to a parameter of - the indicated TYPE, which is a parameter to FN. Do any required - conversions. Return the converted value. */ + the indicated TYPE, which is a parameter to FN. PARMNUM is the + zero-based argument number. Do any required conversions. Return + the converted value. */ static GTY(()) VEC(tree,gc) *default_arg_context; +void +push_defarg_context (tree fn) +{ VEC_safe_push (tree, gc, default_arg_context, fn); } +void +pop_defarg_context (void) +{ VEC_pop (tree, default_arg_context); } tree convert_default_arg (tree type, tree arg, tree fn, int parmnum) @@ -5757,15 +5764,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) int i; tree t; - /* If the ARG is an unparsed default argument expression, the - conversion cannot be performed. */ - if (TREE_CODE (arg) == DEFAULT_ARG) - { - error ("the default argument for parameter %d of %qD has " - "not yet been parsed", - parmnum, fn); - return error_mark_node; - } + /* See through clones. */ + fn = DECL_ORIGIN (fn); /* Detect recursion. */ FOR_EACH_VEC_ELT (tree, default_arg_context, i, t) @@ -5774,7 +5774,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) error ("recursive evaluation of default argument for %q#D", fn); return error_mark_node; } - VEC_safe_push (tree, gc, default_arg_context, fn); + + /* If the ARG is an unparsed default argument expression, the + conversion cannot be performed. */ + if (TREE_CODE (arg) == DEFAULT_ARG) + { + error ("call to %qD uses the default argument for parameter %P, which " + "is not yet defined", fn, parmnum); + return error_mark_node; + } + + push_defarg_context (fn); if (fn && DECL_TEMPLATE_INFO (fn)) arg = tsubst_default_argument (fn, type, arg); @@ -5814,7 +5824,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) } pop_deferring_access_checks(); - VEC_pop (tree, default_arg_context); + pop_defarg_context (); return arg; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4b49046..6ef6e6e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4638,6 +4638,8 @@ extern bool can_convert (tree, tree); extern bool can_convert_arg (tree, tree, tree, int); extern bool can_convert_arg_bad (tree, tree, tree, int); extern bool enforce_access (tree, tree, tree); +extern void push_defarg_context (tree); +extern void pop_defarg_context (void); extern tree convert_default_arg (tree, tree, tree, int); extern tree convert_arg_to_ellipsis (tree); extern tree build_x_va_arg (tree, tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4260f6d..a9fd201 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -20521,6 +20521,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; + push_defarg_context (fn); + for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)), parmdecl = DECL_ARGUMENTS (fn); parm && parm != void_list_node; @@ -20579,6 +20581,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn) cp_parser_pop_lexer (parser); } + pop_defarg_context (); + /* Make sure no default arg is missing. */ check_default_args (fn); diff --git a/gcc/testsuite/g++.dg/parse/pr34758.C b/gcc/testsuite/g++.dg/parse/pr34758.C new file mode 100644 index 0000000..d694853 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr34758.C @@ -0,0 +1,28 @@ +// PR 34758 Bad diagnostic for circular dependency in constructor default argument +// { dg-do compile } +// { dg-options "" } +struct A +{ + A (const A& = A()); // { dg-error "recursive evaluation of default argument" } +}; + + +struct S { + S(const S& = f()); // { dg-error "default argument\[^\n\]*which is not yet defined" } + static const S& f(int i = 3); +}; + +struct J { + J(const J& = f(2)); // { dg-error "default argument.*which is not yet defined" } + static const J& f(int i = 3, int j = 4); +}; + +struct Z { + Z(const Z& = f(4)); + static const Z& f(int i = 3); +}; + +struct X { + X(const X& = g()); + static const X& g(void); +};