From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lxmtout2.gsi.de (lxmtout2.gsi.de [140.181.3.112]) by sourceware.org (Postfix) with ESMTPS id E8170386EC52 for ; Thu, 27 May 2021 15:25:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E8170386EC52 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gsi.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=M.Kretz@gsi.de Received: from localhost (localhost [127.0.0.1]) by lxmtout2.gsi.de (Postfix) with ESMTP id 5C720203E808; Thu, 27 May 2021 17:25:38 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at lxmtout2.gsi.de Received: from lxmtout2.gsi.de ([127.0.0.1]) by localhost (lxmtout2.gsi.de [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Rw5FNisRnC2h; Thu, 27 May 2021 17:25:38 +0200 (CEST) Received: from srvex3.campus.gsi.de (unknown [10.10.4.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by lxmtout2.gsi.de (Postfix) with ESMTPS id 403B72038F79; Thu, 27 May 2021 17:25:38 +0200 (CEST) Received: from excalibur.localnet (140.181.3.12) by srvex3.campus.gsi.de (10.10.4.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2242.10; Thu, 27 May 2021 17:25:37 +0200 From: Matthias Kretz To: , Jason Merrill Subject: Re: [PATCH] c++: Output less irrelevant info for function template decl [PR100716] Date: Thu, 27 May 2021 17:25:37 +0200 Message-ID: <2898695.XZfK7fWzlU@excalibur> Organization: GSI Helmholtzzentrum =?UTF-8?B?ZsO8cg==?= Schwerionenforschung In-Reply-To: References: <3000132.OxmWWEHjG1@excalibur> <2208926.MkxnEukozC@excalibur> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart20278650.VrcE5JVWYd" Content-Transfer-Encoding: 7Bit X-Originating-IP: [140.181.3.12] X-ClientProxiedBy: SRVEX2.campus.gsi.de (10.10.4.15) To srvex3.campus.gsi.de (10.10.4.16) X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, BODY_8BITS, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_PASS, TXREP, T_SPF_HELO_PERMERROR, URIBL_SBL, URIBL_SBL_A autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 May 2021 15:25:42 -0000 --nextPart20278650.VrcE5JVWYd Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="UTF-8" On Thursday, 27 May 2021 17:07:40 CEST Jason Merrill wrote: > On 5/26/21 5:29 PM, Matthias Kretz wrote: > > New revision which can also be compiled with GCC 4.8. > >=20 > > From: Matthias Kretz > >=20 > > Ensure dump_template_decl for function templates never prints template > > parameters after the function name (it did with -fno-pretty-templates) > > and skip output of irrelevant & confusing "[with T =3D T]" in > > dump_substitution. > >=20 > > gcc/cp/ChangeLog: > > PR c++/100716 > > * error.c (dump_template_bindings): Include code to print > > "[with" and ']', conditional on whether anything is printed at > > all. This is tied to whether a semicolon is needed to separate > > multiple template parameters. If the template argument repeats > > the template parameter (T =3D T), then skip the parameter. >=20 > This description should really be in a comment in the code, rather than > the ChangeLog. OK either way. Added comments in the code. New patch below. =46rom: Matthias Kretz Ensure dump_template_decl for function templates never prints template parameters after the function name (it did with -fno-pretty-templates) and skip output of irrelevant & confusing "[with T =3D T]" in dump_substitution. gcc/cp/ChangeLog: PR c++/100716 * error.c (dump_template_bindings): Include code to print "[with" and ']', conditional on whether anything is printed at all. This is tied to whether a semicolon is needed to separate multiple template parameters. If the template argument repeats the template parameter (T =3D T), then skip the parameter. (dump_substitution): Moved code to print "[with" and ']' to dump_template_bindings. (dump_function_decl): Partial revert of PR50828, which masked TFF_TEMPLATE_NAME for all of dump_function_decl. Now TFF_TEMPLATE_NAME is masked for the scope of the function and only carries through to dump_function_name. (dump_function_name): Avoid calling dump_template_parms if TFF_TEMPLATE_NAME is set. gcc/testsuite/ChangeLog: PR c++/100716 * g++.dg/diagnostic/pr100716.C: New test. * g++.dg/diagnostic/pr100716-1.C: Same test with -fno-pretty-templates. =2D-- gcc/cp/error.c | 63 +++++++++++++++----- gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 +++++++++++++++++ gcc/testsuite/g++.dg/diagnostic/pr100716.C | 54 +++++++++++++++++ 3 files changed, 156 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C =2D- =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dr. Matthias Kretz https://mattkretz.github.io GSI Helmholtz Centre for Heavy Ion Research https://gsi.de std::experimental::simd https://github.com/VcDevel/std-simd =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 --nextPart20278650.VrcE5JVWYd Content-Disposition: inline; filename="0001-c-Output-less-irrelevant-info-for-function-template-.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="utf-8"; name="0001-c-Output-less-irrelevant-info-for-function-template-.patch" diff --git a/gcc/cp/error.c b/gcc/cp/error.c index a2f19d1a5c1..ade9b17e663 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -371,7 +371,35 @@ static void dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, vec *typenames) { - bool need_semicolon = false; + /* Print "[with" and ']', conditional on whether anything is printed at all. + This is tied to whether a semicolon is needed to separate multiple template + parameters. */ + struct prepost_semicolon + { + cxx_pretty_printer *pp; + bool need_semicolon; + + void operator()() + { + if (need_semicolon) + pp_separate_with_semicolon (pp); + else + { + pp_cxx_whitespace (pp); + pp_cxx_left_bracket (pp); + pp->translate_string ("with"); + pp_cxx_whitespace (pp); + need_semicolon = true; + } + } + + ~prepost_semicolon() + { + if (need_semicolon) + pp_cxx_right_bracket (pp); + } + } semicolon_or_introducer = {pp, false}; + int i; tree t; @@ -395,10 +423,20 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx) arg = TREE_VEC_ELT (lvl_args, arg_idx); - if (need_semicolon) - pp_separate_with_semicolon (pp); - dump_template_parameter (pp, TREE_VEC_ELT (p, i), - TFF_PLAIN_IDENTIFIER); + tree parm_i = TREE_VEC_ELT (p, i); + /* If the template argument repeats the template parameter (T = T), + skip the parameter.*/ + if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM + && TREE_CODE (parm_i) == TREE_LIST + && TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL + && TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i))) + == TEMPLATE_TYPE_PARM + && DECL_NAME (TREE_VALUE (parm_i)) + == DECL_NAME (TREE_CHAIN (arg))) + continue; + + semicolon_or_introducer(); + dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER); pp_cxx_whitespace (pp); pp_equal (pp); pp_cxx_whitespace (pp); @@ -414,7 +452,6 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, pp_string (pp, M_("")); ++arg_idx; - need_semicolon = true; } parms = TREE_CHAIN (parms); @@ -436,8 +473,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, FOR_EACH_VEC_SAFE_ELT (typenames, i, t) { - if (need_semicolon) - pp_separate_with_semicolon (pp); + semicolon_or_introducer(); dump_type (pp, t, TFF_PLAIN_IDENTIFIER); pp_cxx_whitespace (pp); pp_equal (pp); @@ -1599,12 +1635,7 @@ dump_substitution (cxx_pretty_printer *pp, && !(flags & TFF_NO_TEMPLATE_BINDINGS)) { vec *typenames = t ? find_typenames (t) : NULL; - pp_cxx_whitespace (pp); - pp_cxx_left_bracket (pp); - pp->translate_string ("with"); - pp_cxx_whitespace (pp); dump_template_bindings (pp, template_parms, template_args, typenames); - pp_cxx_right_bracket (pp); } } @@ -1645,7 +1676,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) bool constexpr_p; tree ret = NULL_TREE; - flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME); + int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME; + flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME; if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); @@ -1723,7 +1755,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) else dump_scope (pp, CP_DECL_CONTEXT (t), flags); - dump_function_name (pp, t, flags); + dump_function_name (pp, t, dump_function_name_flags); if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) { @@ -1937,6 +1969,7 @@ dump_function_name (cxx_pretty_printer *pp, tree t, int flags) dump_module_suffix (pp, t); if (DECL_TEMPLATE_INFO (t) + && !(flags & TFF_TEMPLATE_NAME) && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C new file mode 100644 index 00000000000..93490da6a83 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C @@ -0,0 +1,54 @@ +// { dg-options "-fno-pretty-templates" } + +template + struct A + { + template + void f() {} // { dg-line Af } + + template + void g(U) {} // { dg-line Ag } + }; + +template + struct B + { + template + void f(U) {} // { dg-line Bf } + + template + void g(U, T) {} // { dg-line Bg } + }; + +struct C +{ + template + void f(U) {} // { dg-line Cf } + + template + void g() {} // { dg-line Cg } +}; + +int main() +{ + A().f(0); // { dg-error "no matching function for call to 'A::f\\(int\\)'" } + // { dg-message "candidate: 'template void A::f\\(\\)'" "" { target *-*-* } Af } + + A().g(); // { dg-error "no matching function for call to 'A::g\\(\\)'" } + // { dg-message "candidate: 'template void A::g\\(U\\)'" "" { target *-*-* } Ag } + + B().f(); // { dg-error "no matching function for call to 'B::f\\(\\)'" } + // { dg-message "candidate: 'template void B::f\\(U\\)'" "" { target *-*-* } Bf } + + B().g(); // { dg-error "no matching function for call to 'B::g\\(\\)'" } + // { dg-message "candidate: 'template void B::g\\(U, int\\)'" "" { target *-*-* } Bg } + + B().g(0); // { dg-error "no matching function for call to 'B::g\\(int\\)'" } + // { dg-message "candidate: 'template void B::g\\(U, float\\)'" "" { target *-*-* } Bg } + + C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" } + // { dg-message "candidate: 'template void C::f\\(U\\)'" "" { target *-*-* } Cf } + + C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" } + // { dg-message "candidate: 'template void C::g\\(\\)'" "" { target *-*-* } Cg } +} diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716.C b/gcc/testsuite/g++.dg/diagnostic/pr100716.C new file mode 100644 index 00000000000..4a1f0a4e10a --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/pr100716.C @@ -0,0 +1,54 @@ +// { dg-options "-fpretty-templates" } + +template + struct A + { + template + void f() {} // { dg-line Af } + + template + void g(U) {} // { dg-line Ag } + }; + +template + struct B + { + template + void f(U) {} // { dg-line Bf } + + template + void g(U, T) {} // { dg-line Bg } + }; + +struct C +{ + template + void f(U) {} // { dg-line Cf } + + template + void g() {} // { dg-line Cg } +}; + +int main() +{ + A().f(0); // { dg-error "no matching function for call to 'A::f\\(int\\)'" } + // { dg-message "candidate: 'template void A::f\\(\\) \\\[with T = int\\\]'" "" { target *-*-* } Af } + + A().g(); // { dg-error "no matching function for call to 'A::g\\(\\)'" } + // { dg-message "candidate: 'template void A::g\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Ag } + + B().f(); // { dg-error "no matching function for call to 'B::f\\(\\)'" } + // { dg-message "candidate: 'template void B::f\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Bf } + + B().g(); // { dg-error "no matching function for call to 'B::g\\(\\)'" } + // { dg-message "candidate: 'template void B::g\\(U, T\\) \\\[with T = int\\\]'" "" { target *-*-* } Bg } + + B().g(0); // { dg-error "no matching function for call to 'B::g\\(int\\)'" } + // { dg-message "candidate: 'template void B::g\\(U, T\\) \\\[with T = float\\\]'" "" { target *-*-* } Bg } + + C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" } + // { dg-message "candidate: 'template void C::f\\(U\\)'" "" { target *-*-* } Cf } + + C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" } + // { dg-message "candidate: 'template void C::g\\(\\)'" "" { target *-*-* } Cg } +} --nextPart20278650.VrcE5JVWYd--