From patchwork Sun Jun 9 23:29:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 250158 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 6EF932C008A for ; Mon, 10 Jun 2013 09:29:47 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=Lxd9Igzol9p0yFcb2LkQ7FBBip36XXlIb/nazAFmTJi ohGJgc+0WeVsE71F7rBZhjQeq1t4l68iu1UxSWscN+39rNN9N2BLGKRbAd0sr6Vq hsQ5FWxYvTzwddB8V1rciWPSLyEdB9prlwmZWZ4MgcmG/zANSwISCr9Ozbo+32OE = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=FCPRgGUv+8nYZtt5CGeiQOVsGCk=; b=wvzMjaIDp+0lrqXBW /HLebu9y4QYaLmvlyI+AAoQ6cD0RX2QBqJ9Gz9BFrwUz9Fs/nkWJzbie7g8Wdv9v xaaP8eeauSOB//0KOW1SkOOcvisMzZ34osUWIBFlQCBn6jBh/STUVmgOaCq9GIkp P524cnpGtQi9iTZs+lA90jCf78= Received: (qmail 14983 invoked by alias); 9 Jun 2013 23:29:40 -0000 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 Received: (qmail 14970 invoked by uid 89); 9 Jun 2013 23:29:40 -0000 X-Spam-SWARE-Status: No, score=-5.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_MED, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, SPF_PASS, TW_YY, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sun, 09 Jun 2013 23:29:39 +0000 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r59NTaXw007136 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 9 Jun 2013 23:29:37 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r59NTZhD003138 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 9 Jun 2013 23:29:36 GMT Received: from abhmt110.oracle.com (abhmt110.oracle.com [141.146.116.62]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r59NTZpj003132; Sun, 9 Jun 2013 23:29:35 GMT Received: from poldo4.casa (/79.25.197.14) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 09 Jun 2013 16:29:35 -0700 Message-ID: <51B50FDD.8040100@oracle.com> Date: Mon, 10 Jun 2013 01:29:33 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130510 Thunderbird/17.0.6 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 38634 X-Virus-Found: No Hi, in this old issue, we ICE after having reported an error. The problem seems that start_preparsed_function doesn't directly inform the caller that push_template_decl failed. If we adjust for that and pass back a boolean to cp_parser_function_definition_from_specifiers_and_declarator via start_function, then the parser knows how to clean up, ie, skip the entire function, etc. Patch works well in terms of testsuite, I would ask you to double check in particular the pop_nested_class call which I added before the early return from start_preparsed_function to compensate for the preceding push_nested_class. Tested x86_64-linux. Thanks, Paolo. //////////////////////// /cp 2013-06-11 Paolo Carlini PR c++/38634 * decl.c (start_preparsed_function): Return a bool, false if push_template_decl fails. (start_function): Adjust. * cp-tree.h: Update. /testsuite 2013-06-11 Paolo Carlini PR c++/38634 * g++.dg/template/crash116.C: New. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 199868) +++ cp/cp-tree.h (working copy) @@ -5202,8 +5202,9 @@ extern void finish_enum_value_list (tree); extern void finish_enum (tree); extern void build_enumerator (tree, tree, tree, location_t); extern tree lookup_enumerator (tree, tree); -extern void start_preparsed_function (tree, tree, int); -extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); +extern bool start_preparsed_function (tree, tree, int); +extern bool start_function (cp_decl_specifier_seq *, + const cp_declarator *, tree); extern tree begin_function_body (void); extern void finish_function_body (tree); extern tree outer_curly_brace_block (tree); Index: cp/decl.c =================================================================== --- cp/decl.c (revision 199868) +++ cp/decl.c (working copy) @@ -13008,7 +13008,7 @@ check_function_type (tree decl, tree current_funct error_mark_node if the function has never been defined, or a BLOCK if the function has been defined somewhere. */ -void +bool start_preparsed_function (tree decl1, tree attrs, int flags) { tree ctype = NULL_TREE; @@ -13107,8 +13107,13 @@ start_preparsed_function (tree decl1, tree attrs, { /* FIXME: Handle error_mark_node more gracefully. */ tree newdecl1 = push_template_decl (decl1); - if (newdecl1 != error_mark_node) - decl1 = newdecl1; + if (newdecl1 == error_mark_node) + { + if (ctype || DECL_STATIC_FUNCTION_P (decl1)) + pop_nested_class (); + return false; + } + decl1 = newdecl1; } /* We are now in the scope of the function being defined. */ @@ -13219,7 +13224,7 @@ start_preparsed_function (tree decl1, tree attrs, /* This function may already have been parsed, in which case just return; our caller will skip over the body without parsing. */ if (DECL_INITIAL (decl1) != error_mark_node) - return; + return true; /* Initialize RTL machinery. We cannot do this until CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this @@ -13381,17 +13386,19 @@ start_preparsed_function (tree decl1, tree attrs, start_fname_decls (); store_parm_decls (current_function_parms); + + return true; } /* Like start_preparsed_function, except that instead of a FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR. - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. */ + Returns true on success. If the DECLARATOR is not suitable + for a function, we return false, which tells the parser to + skip the entire function. */ -int +bool start_function (cp_decl_specifier_seq *declspecs, const cp_declarator *declarator, tree attrs) @@ -13400,13 +13407,13 @@ start_function (cp_decl_specifier_seq *declspecs, decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs); if (decl1 == error_mark_node) - return 0; + return false; /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) { error ("invalid function declaration"); - return 0; + return false; } if (DECL_MAIN_P (decl1)) @@ -13415,9 +13422,7 @@ start_function (cp_decl_specifier_seq *declspecs, gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node)); - start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); - - return 1; + return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT); } /* Returns true iff an EH_SPEC_BLOCK should be created in the body of Index: testsuite/g++.dg/template/crash116.C =================================================================== --- testsuite/g++.dg/template/crash116.C (revision 0) +++ testsuite/g++.dg/template/crash116.C (working copy) @@ -0,0 +1,13 @@ +// PR c++/38634 + +template struct A +{ + A(); +}; + +template A::A() // { dg-error "template|required" } +{ + struct B {}; +} + +A<0> a;