From patchwork Thu Jun 6 13:00:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 1111117 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502483-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="OxCoZf9r"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="EVrifIv5"; 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 45KQlH2H4Mz9sNT for ; Thu, 6 Jun 2019 23:01:14 +1000 (AEST) 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=I40u5d/21rUWNSzyYsCSBNKuRrvQmtXXApxQNesriC+bBqi6OO bCMfkIwSkz0ZLoEvshCMRBh2dF7YbwObkZzfIWz9zp2E8UmQoViC26AtidoXXVAx SSXxWBbucxwjkRpuGxE5ZSiF2myI3oJUd1qfapv+jacHfwo4OSc6gC3YQ= 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=WswdGwBl2wNiG57n8R7prwdeeww=; b=OxCoZf9rL32g2ZlJjIO3 eU6trji9Km2HWDvvuPUd6kqZB9e46DdmvcW888mtOFt9qErYVDENKO5MVmxh7lPK B5Nd2VFrX3b9HAmeEkA76hEWoljcBum5zJvKwll8lP9Pzcw6sZXljf4CpyOgCzee SvNufLjScHVX/QK7fVe7cfM= Received: (qmail 64300 invoked by alias); 6 Jun 2019 13:01:08 -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 59429 invoked by uid 89); 6 Jun 2019 13:01:03 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 spammy=Further, qualifying, grokfield, decl_context 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; Thu, 06 Jun 2019 13:01:01 +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 x56Cs91M011286; Thu, 6 Jun 2019 13:00:59 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-2018-07-02; bh=buB0t1P22+hT3khcAV7f5prJN8aXEFgBwNdIP7OWLMI=; b=EVrifIv5vLrtE47thP9EJ1FdyQoPkhFLDVPqfnbj65Vmrk4L/amIU0tSbLwOi+wWi35c J6n//E0X3wQwqdqLX8SJeJQi57f15fRdV/i6GNxk8E25WrqiVlk+8nGRume3TaFKvupd E8Dv9XvIKQBV5yuDvsNTcnbw+tJP99ciCZQXILptKoy4UQV9stiUku+/7EgDjhjAHkng oFE+prhPgtRlF5xbQFSx7E6fZ9NB05NdFc/PzOhfJT12DIIGkw7DkiBqf75WnkVrh7Fy 6fvs2dJynuLo/znDv5BDgaRRE5nBHJRBDG9IV10xy11iij1Ag/1NvBXphEbAxC7fLKj3 hQ== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2130.oracle.com with ESMTP id 2sugstr8yx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 06 Jun 2019 13:00:59 +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 x56D0fSk092126; Thu, 6 Jun 2019 13:00:58 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3030.oracle.com with ESMTP id 2swnhcp0hx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 06 Jun 2019 13:00:58 +0000 Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x56D0vgq001932; Thu, 6 Jun 2019 13:00:58 GMT Received: from [192.168.1.4] (/79.42.221.26) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 06 Jun 2019 06:00:57 -0700 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill From: Paolo Carlini Subject: [C++ Patch] Further grokdeclarator locations work Message-ID: <30e4e1cf-ec56-52f2-9f3e-6942737db55e@oracle.com> Date: Thu, 6 Jun 2019 15:00:54 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, only minor functional changes here - more precise locations for two error messages  - but I think it's a step in the right direction: it moves the declaration of id_loc way up, near typespec_loc and as such id_loc is immediately used. Then its value is updated upon the loop over declarator in the middle of the function and used again in the final part of the function. That also "frees" the simple name loc for other local uses, allows to simplify those checks changed rather recently over (name && declarator). and (unqualified_id && declarator). Tested x86_64-linux. Thanks, Paolo. ////////////////////// /cp 2019-06-06 Paolo Carlini * decl.c (grokdeclarator): Move further up the declaration of id_loc, use it immediately, update its value after the loop over declarator, use it again in the final part of function; use id_loc in error messages about multiple data types and conflicting specifiers. /testsuite 2019-06-06 Paolo Carlini * g++.dg/diagnostic/conflicting-specifiers-1.C: New. * g++.dg/diagnostic/two-or-more-data-types-1.C: Likewise. Index: cp/decl.c =================================================================== --- cp/decl.c (revision 271974) +++ cp/decl.c (working copy) @@ -10456,6 +10456,8 @@ grokdeclarator (const cp_declarator *declarator, if (typespec_loc == UNKNOWN_LOCATION) typespec_loc = input_location; + location_t id_loc = declarator ? declarator->id_loc : input_location; + /* Look inside a declarator for the name being declared and get it as a string, for an error message. */ for (id_declarator = declarator; @@ -10620,8 +10622,7 @@ grokdeclarator (const cp_declarator *declarator, D1 ( parameter-declaration-clause) ... */ if (funcdef_flag && innermost_code != cdk_function) { - error_at (declarator->id_loc, - "function definition does not declare parameters"); + error_at (id_loc, "function definition does not declare parameters"); return error_mark_node; } @@ -10629,8 +10630,7 @@ grokdeclarator (const cp_declarator *declarator, && innermost_code != cdk_function && ! (ctype && !declspecs->any_specifiers_p)) { - error_at (declarator->id_loc, - "declaration of %qD as non-function", dname); + error_at (id_loc, "declaration of %qD as non-function", dname); return error_mark_node; } @@ -10639,8 +10639,7 @@ grokdeclarator (const cp_declarator *declarator, if (UDLIT_OPER_P (dname) && innermost_code != cdk_function) { - error_at (declarator->id_loc, - "declaration of %qD as non-function", dname); + error_at (id_loc, "declaration of %qD as non-function", dname); return error_mark_node; } @@ -10648,14 +10647,12 @@ grokdeclarator (const cp_declarator *declarator, { if (typedef_p) { - error_at (declarator->id_loc, - "declaration of %qD as %", dname); + error_at (id_loc, "declaration of %qD as %", dname); return error_mark_node; } else if (decl_context == PARM || decl_context == CATCHPARM) { - error_at (declarator->id_loc, - "declaration of %qD as parameter", dname); + error_at (id_loc, "declaration of %qD as parameter", dname); return error_mark_node; } } @@ -10705,13 +10702,13 @@ grokdeclarator (const cp_declarator *declarator, issue an error message. */ if (declspecs->multiple_types_p) { - error ("two or more data types in declaration of %qs", name); + error_at (id_loc, "two or more data types in declaration of %qs", name); return error_mark_node; } if (declspecs->conflicting_specifiers_p) { - error ("conflicting specifiers in declaration of %qs", name); + error_at (id_loc, "conflicting specifiers in declaration of %qs", name); return error_mark_node; } @@ -11861,6 +11858,8 @@ grokdeclarator (const cp_declarator *declarator, } } + id_loc = declarator ? declarator->id_loc : input_location; + /* A `constexpr' specifier used in an object declaration declares the object as `const'. */ if (constexpr_p && innermost_code != cdk_function) @@ -11884,8 +11883,6 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id = dname; } - location_t loc = declarator ? declarator->id_loc : input_location; - /* If TYPE is a FUNCTION_TYPE, but the function name was explicitly qualified with a class-name, turn it into a METHOD_TYPE, unless we know that the function is static. We take advantage of this @@ -11912,7 +11909,7 @@ grokdeclarator (const cp_declarator *declarator, friendp = 0; } else - permerror (loc, "extra qualification %<%T::%> on member %qs", + permerror (id_loc, "extra qualification %<%T::%> on member %qs", ctype, name); } else if (/* If the qualifying type is already complete, then we @@ -11941,7 +11938,7 @@ grokdeclarator (const cp_declarator *declarator, if (current_class_type && (!friendp || funcdef_flag || initialized)) { - error_at (loc, funcdef_flag || initialized + error_at (id_loc, funcdef_flag || initialized ? G_("cannot define member function %<%T::%s%> " "within %qT") : G_("cannot declare member function %<%T::%s%> " @@ -11952,7 +11949,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (typedef_p && current_class_type) { - error_at (loc, "cannot declare member %<%T::%s%> within %qT", + error_at (id_loc, "cannot declare member %<%T::%s%> within %qT", ctype, name, current_class_type); return error_mark_node; } @@ -12111,9 +12108,9 @@ grokdeclarator (const cp_declarator *declarator, } if (decl_context == FIELD) - decl = build_lang_decl_loc (loc, TYPE_DECL, unqualified_id, type); + decl = build_lang_decl_loc (id_loc, TYPE_DECL, unqualified_id, type); else - decl = build_decl (loc, TYPE_DECL, unqualified_id, type); + decl = build_decl (id_loc, TYPE_DECL, unqualified_id, type); if (decl_context != FIELD) { @@ -12398,8 +12395,8 @@ grokdeclarator (const cp_declarator *declarator, if (in_system_header_at (input_location)) /* Do not warn on flexible array members in system headers because glibc uses them. */; - else if (name && declarator) - pedwarn (declarator->id_loc, OPT_Wpedantic, + else if (name) + pedwarn (id_loc, OPT_Wpedantic, "ISO C++ forbids flexible array member %qs", name); else pedwarn (input_location, OPT_Wpedantic, @@ -12551,7 +12548,7 @@ grokdeclarator (const cp_declarator *declarator, initialized == SD_DELETED, sfk, funcdef_flag, late_return_type_p, template_count, in_namespace, - attrlist, declarator->id_loc); + attrlist, id_loc); decl = set_virt_specifiers (decl, virt_specifiers); if (decl == NULL_TREE) return error_mark_node; @@ -12584,8 +12581,7 @@ grokdeclarator (const cp_declarator *declarator, { if (unqualified_id) { - error_at (declarator->id_loc, - "field %qD has incomplete type %qT", + error_at (id_loc, "field %qD has incomplete type %qT", unqualified_id, type); cxx_incomplete_type_inform (strip_array_types (type)); } @@ -12600,8 +12596,8 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - if (unqualified_id && declarator) - error_at (declarator->id_loc, + if (unqualified_id) + error_at (id_loc, "%qE is neither function nor member function; " "cannot be declared friend", unqualified_id); else @@ -12645,7 +12641,7 @@ grokdeclarator (const cp_declarator *declarator, { /* C++ allows static class members. All other work for this is done by grokfield. */ - decl = build_lang_decl_loc (loc, VAR_DECL, + decl = build_lang_decl_loc (id_loc, VAR_DECL, unqualified_id, type); set_linkage_for_static_data_member (decl); if (concept_p) @@ -12693,7 +12689,7 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id); constexpr_p = false; } - decl = build_decl (loc, FIELD_DECL, unqualified_id, type); + decl = build_decl (id_loc, FIELD_DECL, unqualified_id, type); DECL_NONADDRESSABLE_P (decl) = bitfield; if (bitfield && !unqualified_id) { @@ -12811,7 +12807,7 @@ grokdeclarator (const cp_declarator *declarator, funcdef_flag, late_return_type_p, template_count, in_namespace, attrlist, - declarator->id_loc); + id_loc); if (decl == NULL_TREE) return error_mark_node; @@ -12858,7 +12854,7 @@ grokdeclarator (const cp_declarator *declarator, concept_p, template_count, ctype ? ctype : in_namespace, - loc); + id_loc); if (decl == NULL_TREE) return error_mark_node; @@ -12904,7 +12900,7 @@ grokdeclarator (const cp_declarator *declarator, if (innermost_code == cdk_decomp) { gcc_assert (declarator && declarator->kind == cdk_decomp); - DECL_SOURCE_LOCATION (decl) = declarator->id_loc; + DECL_SOURCE_LOCATION (decl) = id_loc; DECL_ARTIFICIAL (decl) = 1; fit_decomposition_lang_decl (decl, NULL_TREE); } Index: testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C =================================================================== --- testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/conflicting-specifiers-1.C (working copy) @@ -0,0 +1 @@ +static typedef int i __attribute__((unused)); // { dg-error "20:conflicting specifiers" } Index: testsuite/g++.dg/diagnostic/two-or-more-data-types-1.C =================================================================== --- testsuite/g++.dg/diagnostic/two-or-more-data-types-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/two-or-more-data-types-1.C (working copy) @@ -0,0 +1 @@ +char int i __attribute__((unused)); // { dg-error "10:two or more data types" }