From patchwork Tue Apr 24 20:40:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 154760 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 3C48FB6FC4 for ; Wed, 25 Apr 2012 06:41:22 +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=1335904885; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=LfhKBFCmmApTZdS6pE84scz/rCk=; b=c/E3nOdWQ8bEgfD XzPQcGk8Ahv9HQDyIHHLca1fv2EmkmoeJzKGj1zhGXgQcRHaw6ScCGHcwXkoDqB9 /eVQZhIXXRg8Evex1Pr04thJXt0w2O1Z1KQiiPuBYfKKptU0XGDiE5mlBs2WVS8x sb0g7Y0nTGvL0MJp0q/TDIkQurwk= 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:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=S4H2p5/oBSdU5rjUJ3xAaV+eR9RXFw4tSPljq/CQxwSgWFiy63X7Fiq1+L6o6W BftYfP5Kc5+fyPWgL3zaqQ3BMkm4zj1PtvjEVPM6L2x2/BpRauSVN4t335L6a3cQ AK4jYDCe4rfUe5SXfWggwPzGaiM5hZw0lf1DUsEze9rDM=; Received: (qmail 23389 invoked by alias); 24 Apr 2012 20:41:19 -0000 Received: (qmail 23377 invoked by uid 22791); 24 Apr 2012 20:41:17 -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_NO, RCVD_IN_HOSTKARMA_W, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rcsinet15.oracle.com (HELO rcsinet15.oracle.com) (148.87.113.117) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 24 Apr 2012 20:41:02 +0000 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q3OKevob025824 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 24 Apr 2012 20:40:58 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q3OKevYD001527 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 24 Apr 2012 20:40:57 GMT Received: from abhmt105.oracle.com (abhmt105.oracle.com [141.146.116.57]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q3OKev02001737; Tue, 24 Apr 2012 15:40:57 -0500 Received: from [192.168.1.4] (/79.53.82.120) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 24 Apr 2012 13:40:56 -0700 Message-ID: <4F970FCB.7060308@oracle.com> Date: Tue, 24 Apr 2012 22:40:43 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120328 Thunderbird/11.0.1 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 39970 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, I'm trying to resolve this rather old PR, where we don't reject uses of the dot operator in default template arguments, eg: class blah { int member; }; blah global; template class template_blah; I'm enforcing the check by adding to cp_parser a new in_template_default_argument_p which can be set in cp_parser_default_argument. Then it's just matter of reading it (together with integral_constant_expression_p, otherwise we can make mistakes in the argument of eg, sizeof or decltype) exactly when parsing . -> .* and ->* in order to have a precise location for the error. Is this the way we can fix this or we can do better? Tested x86_64-linux. Thanks, Paolo. ////////////////////////////// /cp 2012-04-24 Paolo Carlini PR c++/39970 * parser.h (cp_parser::in_template_default_argument_p): Add. * parser.c (cp_parser_new): Initialize the latter. (cp_parser_default_argument): Set the latter to true when parsing the default argument for a non-type template parameter. (cp_parser_primary_expression): When in_template_default_argument_p && integral_constant_expression_p reject pointer-to-member operators. (cp_parser_postfix_expression): Likewise for class member access operators. /testsuite 2012-04-24 Paolo Carlini PR c++/39970 * g++.dg/parse/template27.C: New. Index: testsuite/g++.dg/parse/template27.C =================================================================== --- testsuite/g++.dg/parse/template27.C (revision 0) +++ testsuite/g++.dg/parse/template27.C (revision 0) @@ -0,0 +1,22 @@ +// PR c++/39970 + +struct blah { int member; }; +blah global; +blah* pglobal; + +template // { dg-error "class member access operator" } +class template1_blah; + +template // { dg-error "class member access operator" } +class template2_blah; + +template member> // { dg-error "class member access operator" } +class template3_blah; + +int blah::* pm = &blah::member; + +template // { dg-error "pointer-to-member operator" } +class template4_blah; + +template *pm> // { dg-error "pointer-to-member operator" } +class template5_blah; Index: cp/parser.c =================================================================== --- cp/parser.c (revision 186780) +++ cp/parser.c (working copy) @@ -503,6 +503,8 @@ cp_debug_parser (FILE *file, cp_parser *parser) cp_debug_print_flag (file, "Local names and 'this' forbidden in " "current context", parser->local_variables_forbidden_p); + cp_debug_print_flag (file, "In template default argument", + parser->in_template_default_argument_p); cp_debug_print_flag (file, "In unbraced linkage specification", parser->in_unbraced_linkage_specification_p); cp_debug_print_flag (file, "Parsing a declarator", @@ -3278,6 +3280,10 @@ cp_parser_new (void) /* Local variable names are not forbidden. */ parser->local_variables_forbidden_p = false; + /* We are not processing the default argument for + a non-type template parameter. */ + parser->in_template_default_argument_p = false; + /* We are not processing an `extern "C"' declaration. */ parser->in_unbraced_linkage_specification_p = false; @@ -4266,6 +4272,14 @@ cp_parser_primary_expression (cp_parser *parser, return error_mark_node; id_expr_token = token; token = cp_lexer_peek_token (parser->lexer); + if (parser->in_template_default_argument_p + && parser->integral_constant_expression_p + && (token->type == CPP_DOT_STAR || token->type == CPP_DEREF_STAR)) + { + error_at (token->location, + "pointer-to-member operator is not allowed here"); + return error_mark_node; + } done = (token->type != CPP_OPEN_SQUARE && token->type != CPP_OPEN_PAREN && token->type != CPP_DOT @@ -5776,6 +5790,11 @@ cp_parser_postfix_expression (cp_parser *parser, b postfix-expression -> template [opt] id-expression postfix-expression -> pseudo-destructor-name */ + if (parser->in_template_default_argument_p + && parser->integral_constant_expression_p) + error_at (token->location, + "class member access operator is not allowed here"); + /* Consume the `.' or `->' operator. */ cp_lexer_consume_token (parser->lexer); @@ -17372,6 +17391,7 @@ cp_parser_default_argument (cp_parser *parser, boo tree default_argument = NULL_TREE; bool saved_greater_than_is_operator_p; bool saved_local_variables_forbidden_p; + bool saved_in_template_default_argument_p; bool non_constant_p, is_direct_init; /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is @@ -17382,6 +17402,12 @@ cp_parser_default_argument (cp_parser *parser, boo appear in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; + if (template_parm_p) + { + saved_in_template_default_argument_p + = parser->in_template_default_argument_p; + parser->in_template_default_argument_p = true; + } /* Parse the assignment-expression. */ if (template_parm_p) push_deferring_access_checks (dk_no_deferred); @@ -17393,6 +17419,9 @@ cp_parser_default_argument (cp_parser *parser, boo pop_deferring_access_checks (); parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; + if (template_parm_p) + parser->in_template_default_argument_p + = saved_in_template_default_argument_p; return default_argument; } Index: cp/parser.h =================================================================== --- cp/parser.h (revision 186780) +++ cp/parser.h (working copy) @@ -282,6 +282,10 @@ typedef struct GTY(()) cp_parser { current context. */ bool local_variables_forbidden_p; + /* TRUE if we are parsing the default argument for a non-type + template parameter. */ + bool in_template_default_argument_p; + /* TRUE if the declaration we are parsing is part of a linkage-specification of the form `extern string-literal declaration'. */