From patchwork Tue Jun 19 20:55:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 931842 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-480062-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="mBmyR7Zp"; 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 419Kx70y69z9s1B for ; Wed, 20 Jun 2018 06:55:37 +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=EUWAohx3Y8PctTQ120VfA0ioUPZTDJDAGU0Xi9Er06oUWbFuUR 7aa3VRuqsrr72MUx//fKv0mG3OiWdykswIiZhkHymbYVVEeiUn6XIV1mw6cVc2Px OxsAo2SiMJhnyVEKvv0jTe9JKMS6FUMzl2sYRjTYtSSxjy2SUOrgPSv18= 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=CDc9ziWIrd40D2iTgSNkLCyNnqo=; b=mBmyR7ZpeHsg3JeXhN4S UkQyW9bLn64tmeDG6xZ/pi9+27Y/j1a5v3ZRPFVlJ514TZNinxC3zEESpZKfAbWz L44sb0r7/ANqqvqLH/8IMBs5tVe3S6KUOZg3PkZMiXdTrfvIgxfmu6CLN/rEKtfV x0NhKuYiAVjohPHI1yrx5T8= Received: (qmail 114660 invoked by alias); 19 Jun 2018 20:55:30 -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 112940 invoked by uid 89); 19 Jun 2018 20:55:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=paolo, Paolo, sk:paoloc, carlini X-HELO: aserp2130.oracle.com Received: from aserp2130.oracle.com (HELO aserp2130.oracle.com) (141.146.126.79) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 19 Jun 2018 20:55:27 +0000 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w5JKinWK126072; Tue, 19 Jun 2018 20:55:25 GMT Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2130.oracle.com with ESMTP id 2jmr2mj0su-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jun 2018 20:55:25 +0000 Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w5JKtNFI010829 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 19 Jun 2018 20:55:24 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w5JKtNOh013089; Tue, 19 Jun 2018 20:55:23 GMT Received: from [192.168.1.4] (/87.11.64.97) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 19 Jun 2018 13:55:22 -0700 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill From: Paolo Carlini Subject: [C++ Patch] Improve grokfndecl locations Message-ID: Date: Tue, 19 Jun 2018 22:55:19 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8929 signatures=668702 X-IsSubscribed: yes Hi, the below implements a couple of independent ideas. First, adds a const cp_decl_specifier_seq * parameter, similarly to grokvardecl: this way the function has available locations[ds_inline], locations[ds_constexpr], locations[ds_type_spec] which can use in some error messages. Second, the handling of an UNKNOWN_LOCATION as location_t argument is reworked a bit - in particular the "deprecated" build_lang_decl call is changed to build_lang_decl_loc: everything I already tweaked in the function about locations should be now 100% correct + the use of the location_t argument can be safely extended to a couple of additional places. Tested x86_64-linux. Thanks, Paolo. //////////////////////// /cp 2018-06-19 Paolo Carlini * decl.c (grokfndecl): Add const cp_decl_specifier_seq* parameter; tidy handling of a null location_t argument; use proper location information in a few additional error messages. (grokdeclarator): Update calls. /testsuite 2018-06-19 Paolo Carlini * g++.dg/template/friend65.C: New. * g++.dg/cpp0x/main1.C: Likewise. * g++.dg/other/main2.C: Likewise. * g++.dg/other/main3.C: Likewise. * g++.dg/warn/main-2.C: Update. Index: cp/decl.c =================================================================== --- cp/decl.c (revision 261732) +++ cp/decl.c (working copy) @@ -8591,6 +8591,7 @@ grokfndecl (tree ctype, tree declarator, tree parms, tree orig_declarator, + const cp_decl_specifier_seq *declspecs, tree decl_reqs, int virtualp, enum overload_flags flags, @@ -8614,6 +8615,9 @@ grokfndecl (tree ctype, int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; tree t; + if (location == UNKNOWN_LOCATION) + location = input_location; + // Was the concept specifier present? bool concept_p = inlinep & 4; @@ -8620,13 +8624,13 @@ grokfndecl (tree ctype, // Concept declarations must have a corresponding definition. if (concept_p && !funcdef_flag) { - error ("concept %qD has no definition", declarator); + error_at (location, "concept %qD has no definition", declarator); return NULL_TREE; } type = build_cp_fntype_variant (type, rqual, raises, late_return_type_p); - decl = build_lang_decl (FUNCTION_DECL, declarator, type); + decl = build_lang_decl_loc (location, FUNCTION_DECL, declarator, type); /* Set the constraints on the declaration. */ if (flag_concepts) @@ -8643,11 +8647,6 @@ grokfndecl (tree ctype, set_constraints (decl, ci); } - /* If we have an explicit location, use it, otherwise use whatever - build_lang_decl used (probably input_location). */ - if (location != UNKNOWN_LOCATION) - DECL_SOURCE_LOCATION (decl) = location; - if (TREE_CODE (type) == METHOD_TYPE) { tree parm = build_this_parm (decl, type, quals); @@ -8716,17 +8715,19 @@ grokfndecl (tree ctype, if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { - error ("default arguments are not allowed in declaration " - "of friend template specialization %qD", - decl); + error_at (location, + "default arguments are not allowed in declaration " + "of friend template specialization %qD", + decl); return NULL_TREE; } if (inlinep & 1) { - error ("% is not allowed in declaration of friend " - "template specialization %qD", - decl); + error_at (declspecs->locations[ds_inline], + "% is not allowed in declaration of friend " + "template specialization %qD", + decl); return NULL_TREE; } } @@ -8773,13 +8774,15 @@ grokfndecl (tree ctype, if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { if (PROCESSING_REAL_TEMPLATE_DECL_P()) - error ("cannot declare %<::main%> to be a template"); + error_at (location, "cannot declare %<::main%> to be a template"); if (inlinep & 1) - error ("cannot declare %<::main%> to be inline"); + error_at (declspecs->locations[ds_inline], + "cannot declare %<::main%> to be inline"); if (inlinep & 2) - error ("cannot declare %<::main%> to be %"); + error_at (declspecs->locations[ds_constexpr], + "cannot declare %<::main%> to be %"); if (!publicp) - error ("cannot declare %<::main%> to be static"); + error_at (location, "cannot declare %<::main%> to be static"); inlinep = 0; publicp = 1; } @@ -8992,7 +8995,8 @@ grokfndecl (tree ctype, { tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree newtype; - error ("%<::main%> must return %"); + error_at (declspecs->locations[ds_type_spec], + "%<::main%> must return %"); newtype = build_function_type (integer_type_node, oldtypeargs); TREE_TYPE (decl) = newtype; } @@ -12148,6 +12152,7 @@ grokdeclarator (const cp_declarator *declarator, ? unqualified_id : dname, parms, unqualified_id, + declspecs, reqs, virtualp, flags, memfn_quals, rqual, raises, friendp ? -1 : 0, friendp, publicp, @@ -12392,6 +12397,7 @@ grokdeclarator (const cp_declarator *declarator, || storage_class != sc_static); decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, + declspecs, reqs, virtualp, flags, memfn_quals, rqual, raises, 1, friendp, publicp, Index: testsuite/g++.dg/concepts/decl-diagnose.C =================================================================== --- testsuite/g++.dg/concepts/decl-diagnose.C (revision 261732) +++ testsuite/g++.dg/concepts/decl-diagnose.C (working copy) @@ -6,7 +6,7 @@ void f(concept int); // { dg-error "a parameter ca template concept int f2() { return 0; } // { dg-error "return type" } -concept bool f3(); // { dg-error "no definition" } +concept bool f3(); // { dg-error "14:concept .f3. has no definition" } struct X { Index: testsuite/g++.dg/cpp0x/main1.C =================================================================== --- testsuite/g++.dg/cpp0x/main1.C (nonexistent) +++ testsuite/g++.dg/cpp0x/main1.C (working copy) @@ -0,0 +1,3 @@ +// { dg-do compile { target c++11 } } + +constexpr int main(); // { dg-error "1:cannot declare .::main. to be .constexpr." } Index: testsuite/g++.dg/other/main2.C =================================================================== --- testsuite/g++.dg/other/main2.C (nonexistent) +++ testsuite/g++.dg/other/main2.C (working copy) @@ -0,0 +1 @@ +float main(); // { dg-error "1:.::main. must return .int." } Index: testsuite/g++.dg/other/main3.C =================================================================== --- testsuite/g++.dg/other/main3.C (nonexistent) +++ testsuite/g++.dg/other/main3.C (working copy) @@ -0,0 +1 @@ +inline int main(); // { dg-error "1:cannot declare .::main. to be inline" } Index: testsuite/g++.dg/template/friend65.C =================================================================== --- testsuite/g++.dg/template/friend65.C (nonexistent) +++ testsuite/g++.dg/template/friend65.C (working copy) @@ -0,0 +1,6 @@ +template void foo (int); + +template +class Q { + friend inline void foo (int); // { dg-error "10:.inline. is not allowed in declaration of friend" } +}; Index: testsuite/g++.dg/warn/main-2.C =================================================================== --- testsuite/g++.dg/warn/main-2.C (revision 261732) +++ testsuite/g++.dg/warn/main-2.C (working copy) @@ -7,8 +7,8 @@ void f1(); -void -main() /* { dg-error "must return" } */ +void /* { dg-error "1:.\:\:main. must return .int." } */ +main() { f1(); }