From patchwork Fri Jul 15 16:54:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 648905 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rrdwB6K7Yz9s6r for ; Sat, 16 Jul 2016 02:54:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Dd/Ypt5E; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=AwNAA20HbWXmGXsLrrqvL0UTnxyoZ5yWRRJVMrKlImflbw 0TOyNZ4kleMt9/COniQAU2L8BD/v30IJWP9YMwBDRrFiqgWTwdlXaEYML1+r3z+T g2MoIr0HYbi37ZAqaD6kV/XYtwJzvxeCSFCQd0NvPWsG8E6Bx4+7gPI0erlpE= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=7XNARzymM13GH7KbDEscRwBff+s=; b=Dd/Ypt5E1RxGEBTt8il8 DPNqCaGowZKDPDDrZw3Zw4c9Lc+wP8Pw2rpbggDXsM253K+PAlDoxBp+z2STOY/h Sps7mDka+m33Mzl5B/dE5WXNjO1oS32qk4OpHc0iXB6heJa2VOYHn8RmsS1K9zLl Uocm42hP9IeGsmf9KuaV7y8= Received: (qmail 118105 invoked by alias); 15 Jul 2016 16:54:42 -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 118082 invoked by uid 89); 15 Jul 2016 16:54:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=consumed, diagnose, error_mark_node X-HELO: mail-oi0-f48.google.com Received: from mail-oi0-f48.google.com (HELO mail-oi0-f48.google.com) (209.85.218.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 15 Jul 2016 16:54:41 +0000 Received: by mail-oi0-f48.google.com with SMTP id j185so165131390oih.0 for ; Fri, 15 Jul 2016 09:54:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=QG5jA8XnNP0nsHcYW3kRqb05+B6y92Ych+4zmQskM+E=; b=YGOmWGijV1hWIr1a15pe06mvo4eRNwU4/TZ35Zh3PsqpKIZyhkszgC5z2qf7DnOMQb Z7Bj8icwtnsuRen9TQejvVkVOkA3jpZw/8zsp/taRcWzlmgG6QTyNZyBuMgZiCsRUmv2 pILBebVE9tGDjBizJ95pDl5t8bDVsRrS4hgWD3nhzmMUIf4y1cBkEczxJw+Mtz107PIX vVoooHZd52cG+stoUCeRwNyqmRsN5varStLnBSwNwTh5CmOp13TJXZGTS2fn+pTF95US XfQqNx8n2GOQh4/6IFbaxn8I1CR3mbvvXHEYUCcgvXiIOV5mRzTJWxE2HpWN/mzI9OpO 0e5w== X-Gm-Message-State: ALyK8tJ87n297M82+dKLnaKbVoB9Hz07XhC5NGftMQtQBEJyNvAzeu7Lt8Ck5neHja0sqTANOkXTmeknouNF2l5z X-Received: by 10.157.11.182 with SMTP id 51mr13449236oth.82.1468601678869; Fri, 15 Jul 2016 09:54:38 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.105.170 with HTTP; Fri, 15 Jul 2016 09:54:19 -0700 (PDT) From: Jason Merrill Date: Fri, 15 Jul 2016 12:54:19 -0400 Message-ID: Subject: C++ PATCH for c++/71604 (type definition in range for) To: gcc-patches List X-IsSubscribed: yes This was crashing because the binding hijinks we do to handle the range-for-declaration weren't dealing well with a class definition. This patch fixes that, and also adds a diagnostic since that turns out to be ill-formed. Tested x86_64-pc-linux-gnu, applying to trunk. commit adb66c0085a034eddcb7d7467af372331c8db1be Author: Jason Merrill Date: Thu Jul 14 00:50:14 2016 -0400 PR c++/71604 - type definition in range-based for PR c++/54430 * parser.c (cp_parser_range_for): Modify IDENTIFIER_BINDING directly. (cp_parser_simple_declaration): Diagnose type definition in for-range-declaration. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ef35aa9..69fb060 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11187,11 +11187,17 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, bool ivdep) { tree stmt, range_expr; + cxx_binding *binding = NULL; + tree name = NULL_TREE; /* Get the range declaration momentarily out of the way so that the range expression doesn't clash with it. */ if (range_decl != error_mark_node) - pop_binding (DECL_NAME (range_decl), range_decl); + { + name = DECL_NAME (range_decl); + binding = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding->previous; + } if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { @@ -11203,7 +11209,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, /* Put the range declaration back into scope. */ if (range_decl != error_mark_node) - push_binding (DECL_NAME (range_decl), range_decl, current_binding_level); + { + binding->previous = IDENTIFIER_BINDING (name); + IDENTIFIER_BINDING (name) = binding; + } /* If in template, STMT is converted to a normal for-statement at instantiation. If not, it is done just ahead. */ @@ -12437,8 +12446,15 @@ cp_parser_simple_declaration (cp_parser* parser, if (token->type == CPP_COMMA) /* will be consumed next time around */; /* If it's a `;', we are done. */ - else if (token->type == CPP_SEMICOLON || maybe_range_for_decl) + else if (token->type == CPP_SEMICOLON) break; + else if (maybe_range_for_decl) + { + if (declares_class_or_enum && token->type == CPP_COLON) + permerror (decl_specifiers.locations[ds_type_spec], + "types may not be defined in a for-range-declaration"); + break; + } /* Anything else is an error. */ else { diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for31.C b/gcc/testsuite/g++.dg/cpp0x/range-for31.C new file mode 100644 index 0000000..833f510 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/range-for31.C @@ -0,0 +1,9 @@ +// PR c++/71604 +// { dg-do compile { target c++11 } } + +void foo () +{ + int a[2] = { 1, 2 }; + for (struct S { S (int) {} } S : a) // { dg-error "types may not be defined" } + ; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for8.C b/gcc/testsuite/g++.dg/cpp0x/range-for8.C index a389f66..38fe456 100644 --- a/gcc/testsuite/g++.dg/cpp0x/range-for8.C +++ b/gcc/testsuite/g++.dg/cpp0x/range-for8.C @@ -7,9 +7,9 @@ void test() { - for (struct S { } *x : { (S*)0, (S*)0 } ) + for (struct S { } *x : { (S*)0, (S*)0 } ) // { dg-error "types may not be defined" } ; - for (struct S { } x : { S(), S() } ) + for (struct S { } x : { S(), S() } ) // { dg-error "types may not be defined" } ; }