From patchwork Fri Oct 18 15:35:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 1179467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-511301-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=oracle.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="mOUbFB5O"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="MhwkNO1Z"; dkim-atps=neutral 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 46vqrm6wNfz9sQq for ; Sat, 19 Oct 2019 02:35:29 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=ZCfRY3eorJjqsboQK9pwxwPMdO9IUOkqo5aC04GJ+CLFeAWqnw Xrp6n/vHVWZIw4pCX0EtlzOcBrg5juav/X8jrk8EHK9833Ymo/3cFtQFvmVpvMBT +WgNTaFjTXX3bpr80gZXRUif3+yPX+wrHH213rFdeC+WRdINRZfDhzc1c= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=HtBnWS1dzwAHdq57zbuGkrVQrWE=; b=mOUbFB5OW+4RsoQ752F0 SBGbZayVZQKYe0frwHphIKzf8EoL2KaX3BlBalWHOX8wuUG1ALoM2FyoefucLVsU MXf7C4Nt+PQqgnmPpzJRrmisNGkpKC0yH+YZsMwrDSLi8KCpAcHlVsQU3t+6OfZA K/dALgNHxmTx4I817vsziII= Received: (qmail 76142 invoked by alias); 18 Oct 2019 15:35:23 -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 76014 invoked by uid 89); 18 Oct 2019 15:35:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=issuing, declarator, reproducing X-HELO: userp2130.oracle.com Received: from userp2130.oracle.com (HELO userp2130.oracle.com) (156.151.31.86) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2019 15:35:21 +0000 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x9IFOFHg191162; Fri, 18 Oct 2019 15:35:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=to : cc : from : subject : message-id : date : mime-version : content-type; s=corp-2019-08-05; bh=q/yKaP/wkUbl5tMCExzUQYR3qmMvLil80P8n5IAy6j8=; b=MhwkNO1Z1cjZqv/2AQ7nKvLQXW4d/SG2piCQ3DHOuuo92hG0dP20MnQ+cJp/d6gOmTOL EEiohHbj9EMSk1bNGQQhr4NKMp2c4gg+6jDLU/CpDv5c7eDuQx4nf4hdRUijS9f45I2C hvwH8nAE79bTT97w5DOE9Wg9kJAZ+a2klH+gScy3SI1cC1W8cuTBPYu17EGtzb8sczIj xXq7yRyohXVJ04r5wSy80FLFM42IuHRk4PhqfW90vFgQOWizKqvt4FZY/LdkQ08css09 /ReaHNsTr6NPO/z5BAwz37KmEl2fFt/xLmZ3ZWtQt0tzy5lcdKVbpxlRuyoQZRhHtZ3F pQ== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2130.oracle.com with ESMTP id 2vq0q4cptj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 18 Oct 2019 15:35:19 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x9IFOEI1186544; Fri, 18 Oct 2019 15:35:18 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserp3030.oracle.com with ESMTP id 2vq0dy27nh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 18 Oct 2019 15:35:18 +0000 Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x9IFZH1e002442; Fri, 18 Oct 2019 15:35:17 GMT Received: from [192.168.1.4] (/79.18.213.139) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 18 Oct 2019 15:35:17 +0000 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill From: Paolo Carlini Subject: [C++ Patch] Improve cp_parser_class_head error recovery Message-ID: Date: Fri, 18 Oct 2019 17:35:14 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.1.1 MIME-Version: 1.0 X-IsSubscribed: yes Hi, a few days ago I noticed that for, say, g++.dg/parse/qualified2.C we were issuing two additional misleading errors after the first one, mentioning in particular a certain "unnamed class" (I'm reproducing only the error messages proper): namespace Glib {   template class Value {};   template <>         class Glib::Value {}; // { dg-error "" } } qualified2.C:3:29: error: extra qualification not allowed [\-fpermissive\] qualified2.C:3:46: error: explicit specialization of non-template ‘Glib::’ qualified2.C:3:47: error: abstract declarator ‘Glib::’ used as declaration Let's see if I can explain clearly enough what I think it's going on. In cp_parser_class_head, upon the permerror about the extra qualification, we try to do error recovery, which is particularly tricky, because we are dealing with a permerror thus we have to make sure that in case of -fpermissive everything remains internally consistent anyway. In this context, clearing 'nested_name_specifier' and 'num_templates' doesn't seem a good idea because it does *not* give us an internal state similar to the one normally obtained when the nested name specifier is not there, the reason being that, earlier in the function, when a nested name specifier really isn't there we try cp_parser_template_id or in case cp_parser_identifier, which set the locale 'id' and possibly 'template_id' and 'num_templates', whereas during error recovery we remain so to speak completely empty handed. Thus, what about not clearing anything? That seems to work at least for the two testcases below and doesn't cause regressions. Thanks, Paolo. ///////////////////////////// /cp 2019-10-18 Paolo Carlini * parser.c (cp_parser_class_head): Improve error recovery upon extra qualification error. /testsuite 2019-10-18 Paolo Carlini * g++.dg/parse/qualified2.C: Tighten dg-error directive. * g++.old-deja/g++.other/decl5.C: Don't expect redundant error. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 277149) +++ cp/parser.c (working copy) @@ -24178,12 +24178,8 @@ cp_parser_class_head (cp_parser* parser, ... [or] the definition or explicit instantiation of a class member of a namespace outside of its namespace. */ if (scope == nested_name_specifier) - { - permerror (nested_name_specifier_token_start->location, - "extra qualification not allowed"); - nested_name_specifier = NULL_TREE; - num_templates = 0; - } + permerror (nested_name_specifier_token_start->location, + "extra qualification not allowed"); } /* An explicit-specialization must be preceded by "template <>". If it is not, try to recover gracefully. */ Index: testsuite/g++.dg/parse/qualified2.C =================================================================== --- testsuite/g++.dg/parse/qualified2.C (revision 277144) +++ testsuite/g++.dg/parse/qualified2.C (working copy) @@ -1,4 +1,4 @@ namespace Glib { template class Value {}; - template <> class Glib::Value {}; // { dg-error "" } + template <> class Glib::Value {}; // { dg-error "29:extra qualification" } } Index: testsuite/g++.old-deja/g++.other/decl5.C =================================================================== --- testsuite/g++.old-deja/g++.other/decl5.C (revision 277144) +++ testsuite/g++.old-deja/g++.other/decl5.C (working copy) @@ -12,7 +12,6 @@ struct A { int A::m; // { dg-error "extra qualification" } struct e; struct A::e {int i;}; // { dg-error "extra qualification" "qual" } - // { dg-error "anonymous struct" "anon" { target *-*-* } .-1 } struct A::expand { // { dg-error "qualified name" } int m; };