From patchwork Fri Sep 7 22:02:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 182468 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 A4D382C0088 for ; Sat, 8 Sep 2012 08:02:59 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1347660180; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=9dvp2qViMjtq2JGO+Eut1DBUgHI=; b=dhAy+OcM0RkFDY2zWuYw3zlCM2iA0jLID64ZHYYQfBHM7dFMJWq1xOFsq/fC4C sTq1IpHWfRW54l6wXq+w1kwWSy01anldsOLB0GxRsAuL7Z4xnoONyfC504A//eza tjTYXmSdIrrw4xFzhBpRTP7oBKJVMTvblejUOGwrZaAKw= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=JvMOVrgAuCgiEsBlJ/fUTIy5+fs01NSGwZhiI2FwWfUIBvKDSxtsVTVctRDcjQ ExB2JwwXBQyQ7w6OBov5//HR0WAxj2sWoNUz7/gjLYRLpW36r29+YJj8utvz6BxS zdIQMWxMqLn+b7cxZCXoRIQbrijfZrEIpVbBUIkQgomQc=; Received: (qmail 6316 invoked by alias); 7 Sep 2012 22:02:54 -0000 Received: (qmail 6302 invoked by uid 22791); 7 Sep 2012 22:02:52 -0000 X-SWARE-Spam-Status: No, hits=-7.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from acsinet15.oracle.com (HELO acsinet15.oracle.com) (141.146.126.227) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Sep 2012 22:02:36 +0000 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q87M2XEb022031 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 7 Sep 2012 22:02:34 GMT Received: from acsmt357.oracle.com (acsmt357.oracle.com [141.146.40.157]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q87M2WKK018587 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 7 Sep 2012 22:02:33 GMT Received: from abhmt112.oracle.com (abhmt112.oracle.com [141.146.116.64]) by acsmt357.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q87M2WU9006646; Fri, 7 Sep 2012 17:02:32 -0500 Received: from [192.168.1.4] (/79.33.216.149) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 07 Sep 2012 15:02:31 -0700 Message-ID: <504A6EF5.5010909@oracle.com> Date: Sat, 08 Sep 2012 00:02:29 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120825 Thunderbird/15.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: C++/24314 References: <50363851.9070205@oracle.com> <50364B47.3030809@redhat.com> <503651F7.8090601@oracle.com> <5036C601.8060400@oracle.com> <50412D7E.7010203@redhat.com> <504780C1.7090406@oracle.com> <5047835E.2020306@oracle.com> <5047971F.70905@oracle.com> <5047E859.4040109@redhat.com> <5048CCC4.1070908@oracle.com> <5048E1B1.2040205@redhat.com> <504923BE.8020709@oracle.com> <504A4E8B.10003@redhat.com> <504A6228.5030005@oracle.com> <504A68DE.1080007@redhat.com> In-Reply-To: <504A68DE.1080007@redhat.com> X-IsSubscribed: yes 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 Hi, On 09/07/2012 11:36 PM, Jason Merrill wrote: > On 09/07/2012 05:07 PM, Paolo Carlini wrote: >> the regression of template/crash83.C because of excess errors. The >> latter happens because we have code in cp_parser_class_head which >> tries to improve error recovery for cases of missing 'template <>' in >> explicit specializations, and, for that rather broken testcase, it >> confuses the code I'm tentatively adding, resulting in the additional >> error message below: >> >> crash83.C:5:27: error: an explicit specialization must be preceded by >> ‘template <>’ >> template: > struct B {}; // { dg-error >> "explicit specialization|expected" } >> ^ >> crash83.C:5:27: error: too many template-parameter-lists for A<0> >> (should be 1) > > So we're adding a second irrelevant diagnostic to go with the first > one. The error in this testcase is a simple stray ':' causing a > syntax error, it has nothing to do with explicit specialization. It > would be nice to improve this, but given that we're already not giving > the right error, adding a second wrong error doesn't seem like a big > problem. Yeah. I wasn't particularly worried by that regression. > >> More importantly, I'm having troubles removing the early >> cp_parser_check_template_parameters check in cp_parser_class_head: one >> issue is that it also checks for too few template-parameter-lists not >> just too many, and thus catches rather broken testcases like, eg, >> template/error7.C or template/class2.C: >> >> template >> struct A { >> struct B; >> struct A::B { }; // { dg-error "" } >> }; > > This testcase is indeed ill-formed, but its ill-formedness has nothing > to do with too few template-parameter-lists. The problem is that > clause 9 says > > If a class-head-name contains a nested-name-specifier, the > class-specifier shall refer to a class that was previously declared > directly in the class or namespace to which the nested-name-specifier > refers, ... and the class-specifier shall appear in a namespace > enclosing the previous declaration. > > The definition of A::B does not appear at namespace scope, so it is > ill-formed. Removing the incorrect error is an improvement, but then > we need to add the correct error rather than accept the testcase. > >> but there are definitely more problems with just checking >> template_header_count < wanted too in >> maybe_process_partial_specialization and removing the early check, I'm >> seeing many, many fails if I just try to extend "p4" like that... > > Like what? Like a nightmare ;) If I run the testsuite with the attached "p5" a lot is broken, with template templates, variadic templates, we have all sort of problems. The below is just the beginning, template/pr39425.C times out. I think we need something radically different / radically more complex. Paolo. //////////////////////// FAIL: g++.dg/abi/mangle34.C -std=c++98 (test for excess errors) FAIL: g++.dg/abi/mangle34.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/initlist48.C (test for excess errors) FAIL: g++.dg/cpp0x/lambda/lambda-pass.C (test for excess errors) WARNING: g++.dg/cpp0x/lambda/lambda-pass.C compilation failed to produce executable FAIL: g++.dg/cpp0x/lambda/lambda-recursive.C (test for excess errors) WARNING: g++.dg/cpp0x/lambda/lambda-recursive.C compilation failed to produce executable FAIL: g++.dg/cpp0x/lambda/lambda-std-function.C (test for excess errors) WARNING: g++.dg/cpp0x/lambda/lambda-std-function.C compilation failed to produce executable FAIL: g++.dg/cpp0x/pr31993.C (test for excess errors) FAIL: g++.dg/cpp0x/pr38646.C (test for excess errors) FAIL: g++.dg/cpp0x/pr47416.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic-104.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic-crash1.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic-lambda.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic129.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/variadic132.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/variadic19.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic20.C (test for errors, line 16) FAIL: g++.dg/cpp0x/variadic20.C (test for errors, line 27) FAIL: g++.dg/cpp0x/variadic20.C (test for errors, line 34) FAIL: g++.dg/cpp0x/variadic20.C bound (test for errors, line 40) FAIL: g++.dg/cpp0x/variadic20.C bound (test for errors, line 42) FAIL: g++.dg/cpp0x/variadic20.C incomplete (test for errors, line 40) FAIL: g++.dg/cpp0x/variadic20.C incomplete (test for errors, line 42) FAIL: g++.dg/cpp0x/variadic20.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic26.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic84.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic85.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic86.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic87.C (test for excess errors) FAIL: g++.dg/cpp0x/variadic89.C (test for excess errors) FAIL: g++.dg/ext/attrib9.C -std=c++98 (test for excess errors) FAIL: g++.dg/ext/attrib9.C -std=c++11 (test for excess errors) FAIL: g++.dg/ext/complex4.C -std=c++11 (test for excess errors) FAIL: g++.dg/init/new18.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/pr30965.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/pr30965.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/pr47615.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/pr47615.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/other/crash-10.C -std=c++98 (test for excess errors) FAIL: g++.dg/other/crash-10.C -std=c++11 (test for excess errors) FAIL: g++.dg/other/crash-11.C -std=c++98 (test for excess errors) FAIL: g++.dg/other/crash-11.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/class2.C -std=c++98 (test for errors, line 6) FAIL: g++.dg/template/class2.C -std=c++11 (test for errors, line 6) FAIL: g++.dg/template/crash104.C -std=c++98 (test for errors, line 25) FAIL: g++.dg/template/crash104.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/crash104.C -std=c++11 (test for errors, line 25) FAIL: g++.dg/template/crash104.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/crash83.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/crash83.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/crash95.C -std=c++98 (test for errors, line 11) FAIL: g++.dg/template/crash95.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/crash95.C -std=c++11 (test for errors, line 11) FAIL: g++.dg/template/crash95.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/ctor4.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/ctor4.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/defarg11.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/defarg11.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/error7.C -std=gnu++98 (internal compiler error) FAIL: g++.dg/template/error7.C -std=gnu++98 (test for errors, line 5) FAIL: g++.dg/template/error7.C -std=gnu++98 (test for errors, line 6) FAIL: g++.dg/template/error7.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/template/error7.C -std=gnu++11 (internal compiler error) FAIL: g++.dg/template/error7.C -std=gnu++11 (test for errors, line 5) FAIL: g++.dg/template/error7.C -std=gnu++11 (test for errors, line 6) FAIL: g++.dg/template/error7.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/template/mem-partial1.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/mem-partial1.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/mem-partial2.C -std=c++98 (test for excess errors) WARNING: g++.dg/template/mem-partial2.C -std=c++98 compilation failed to produce executable FAIL: g++.dg/template/mem-partial2.C -std=c++11 (test for excess errors) WARNING: g++.dg/template/mem-partial2.C -std=c++11 compilation failed to produce executable FAIL: g++.dg/template/mem-partial3.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/mem-partial3.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/partial13.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/partial13.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/partial2.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/partial2.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/partial4.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/partial4.C -std=c++11 (test for excess errors) WARNING: program timed out. FAIL: g++.dg/template/pr39425.C -std=c++98 (test for errors, line 18) FAIL: g++.dg/template/pr39425.C -std=c++98 (test for excess errors) Index: pt.c =================================================================== --- pt.c (revision 191082) +++ pt.c (working copy) @@ -835,6 +835,19 @@ maybe_process_partial_specialization (tree type) && !COMPLETE_TYPE_P (type)) { check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type)); + + int wanted = num_template_headers_for_class (type); + if (template_header_count != wanted) + { + if (template_header_count > wanted) + error ("too many template-parameter-lists for %E " + "(should be %d)", type, wanted); + else + error ("too few template-parameter-lists for %E " + "(should be %d)", type, wanted); + return error_mark_node; + } + SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); if (processing_template_decl) { @@ -882,6 +895,18 @@ maybe_process_partial_specialization (tree type) tree t; tree tmpl = CLASSTYPE_TI_TEMPLATE (type); + int wanted = num_template_headers_for_class (type); + if (template_header_count != wanted) + { + if (template_header_count > wanted) + error ("too many template-parameter-lists for %E " + "(should be %d)", type, wanted); + else + error ("too few template-parameter-lists for %E " + "(should be %d)", type, wanted); + return error_mark_node; + } + if (current_namespace != decl_namespace_context (tmpl)) { Index: parser.c =================================================================== --- parser.c (revision 191082) +++ parser.c (working copy) @@ -18528,7 +18528,7 @@ cp_parser_class_head (cp_parser* parser, use "goto done;" to return. */ /* Make sure that the right number of template parameters were present. */ - if (!cp_parser_check_template_parameters (parser, num_templates, + if (0 && !cp_parser_check_template_parameters (parser, num_templates, type_start_token->location, /*declarator=*/NULL)) {