From patchwork Wed Jun 27 19:06:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 167731 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 84E34B6FAF for ; Thu, 28 Jun 2012 05:06:25 +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=1341428787; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=ueVQQYm NlrLvRf3qBPIgNB6yzTI=; b=iBcdGtQ+9J0a8q47f0OGHjNrPjW5mtRZWaa6KE5 b7Ja/o5eHeC8aztg4lX5762LC0WdmJJcBNGjDC2m3XPyIbDXfBX3iEcXCAeIxoWc CdkRrnp+eojtLwt3ESgtaDfmfo+RavHgSHuvd/GikqWvAPtZNlHeR3759Q/qGThv fBp8= 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:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=yPvPqVmLyZAGV63cv2lKL27zEsJ0/8PyOX+qFXQXsyJHQF9MgPh8u1hLhWybC3 KSV81j533+2yOT6+JJ85+m4J1uhKwzP5M2Aj/EAICUcR+SOBxCQx+k/YMZUH9hgs DZ64RztJovZhgfTew7mDexloYFQcu0gesnM44N3JkHJhU=; Received: (qmail 23229 invoked by alias); 27 Jun 2012 19:06:23 -0000 Received: (qmail 23210 invoked by uid 22791); 27 Jun 2012 19:06:21 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, 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; Wed, 27 Jun 2012 19:06:05 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5RJ65DR017393 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 27 Jun 2012 15:06:05 -0400 Received: from [10.3.113.5] ([10.3.113.5]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q5RJ641B008013 for ; Wed, 27 Jun 2012 15:06:04 -0400 Message-ID: <4FEB599B.3080806@redhat.com> Date: Wed, 27 Jun 2012 15:06:03 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/53563 (ice-on-invalid with s::s) 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 Here, we were parsing s::s wrong. When we've seen a class-key, an injected-class-name must be considered to name the class, not the constructor, because the class-key limits lookup to finding type names. Fixing that corrects the error message for this testcase, and avoids the ICE. Tested x86_64-pc-linux-gnu, applying to trunk. commit 62fa7b236eba79613821976219d952d1898f02df Author: Jason Merrill Date: Wed Jun 27 14:43:06 2012 -0400 * parser.c (cp_parser_check_for_invalid_template_id): tag_type parm. (cp_parser_simple_type_specifier, cp_parser_class_head): Adjust. (cp_parser_elaborated_type_specifier): Adjust. * decl.c (duplicate_decls): Return error_mark_node on template mismatch. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1346f92..ab56019 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1463,6 +1463,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { error ("declaration of template %q#D", newdecl); error ("conflicts with previous declaration %q+#D", olddecl); + return error_mark_node; } else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7012caa..027a7b9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2278,7 +2278,7 @@ static bool cp_parser_check_type_definition static void cp_parser_check_for_definition_in_return_type (cp_declarator *, tree, location_t type_location); static void cp_parser_check_for_invalid_template_id - (cp_parser *, tree, location_t location); + (cp_parser *, tree, enum tag_types, location_t location); static bool cp_parser_non_integral_constant_expression (cp_parser *, non_integral_constant); static void cp_parser_diagnose_invalid_type_name @@ -2551,7 +2551,9 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, static void cp_parser_check_for_invalid_template_id (cp_parser* parser, - tree type, location_t location) + tree type, + enum tag_types tag_type, + location_t location) { cp_token_position start = 0; @@ -2560,7 +2562,12 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, if (TYPE_P (type)) error_at (location, "%qT is not a template", type); else if (TREE_CODE (type) == IDENTIFIER_NODE) - error_at (location, "%qE is not a template", type); + { + if (tag_type != none_type) + error_at (location, "%qE is not a class template", type); + else + error_at (location, "%qE is not a template", type); + } else error_at (location, "invalid template-id"); /* Remember the location of the invalid "<". */ @@ -13668,7 +13675,8 @@ cp_parser_simple_type_specifier (cp_parser* parser, /* There is no valid C++ program where a non-template type is followed by a "<". That usually indicates that the user thought that the type was a template. */ - cp_parser_check_for_invalid_template_id (parser, type, token->location); + cp_parser_check_for_invalid_template_id (parser, type, none_type, + token->location); return TYPE_NAME (type); } @@ -13770,6 +13778,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, followed by a "<". That usually indicates that the user thought that the type was a template. */ cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type), + none_type, token->location); } @@ -14273,7 +14282,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, /* A "<" cannot follow an elaborated type specifier. If that happens, the user was probably trying to form a template-id. */ - cp_parser_check_for_invalid_template_id (parser, type, token->location); + cp_parser_check_for_invalid_template_id (parser, type, tag_type, + token->location); return type; } @@ -18429,6 +18439,7 @@ cp_parser_class_head (cp_parser* parser, if (id) { cp_parser_check_for_invalid_template_id (parser, id, + class_key, type_start_token->location); } virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); diff --git a/gcc/testsuite/g++.dg/cpp0x/override2.C b/gcc/testsuite/g++.dg/cpp0x/override2.C index 0d8871d..4d5a412 100644 --- a/gcc/testsuite/g++.dg/cpp0x/override2.C +++ b/gcc/testsuite/g++.dg/cpp0x/override2.C @@ -18,7 +18,7 @@ template struct B4 final {}; template struct B5 final {}; -struct undeclared final { }; // { dg-error "not a template" } +struct undeclared final { }; // { dg-error "not a class template" } struct D5 : B3 {}; diff --git a/gcc/testsuite/g++.dg/parse/crash28.C b/gcc/testsuite/g++.dg/parse/crash28.C index 67d78d6..68a9759 100644 --- a/gcc/testsuite/g++.dg/parse/crash28.C +++ b/gcc/testsuite/g++.dg/parse/crash28.C @@ -5,10 +5,10 @@ // Origin:Andrew Pinski // Volker Reichelt -template class insert_iterator > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } +template class insert_iterator > {}; // { dg-error "not a class template|not declared in this scope|expected unqualified-id|extra" } template class insert_iterator { // { dg-error "template" } hash_set<_Value>; }; -template struct A > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" } +template struct A > {}; // { dg-error "not a class template|not declared in this scope|expected unqualified-id|extra" } struct A {}; diff --git a/gcc/testsuite/g++.dg/template/error5.C b/gcc/testsuite/g++.dg/template/error5.C index 0c79350..72d3c29 100644 --- a/gcc/testsuite/g++.dg/template/error5.C +++ b/gcc/testsuite/g++.dg/template/error5.C @@ -1,6 +1,6 @@ template -struct X { // { dg-error "not a template" } +struct X { // { dg-error "not a class template" } typedef int Y; }; -extern struct Z s; // { dg-error "not a template" } +extern struct Z s; // { dg-error "not a class template" }