From patchwork Mon Jun 27 15:04:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 102189 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]) by ozlabs.org (Postfix) with SMTP id 9E1D3B6F5C for ; Tue, 28 Jun 2011 01:04:57 +1000 (EST) Received: (qmail 7452 invoked by alias); 27 Jun 2011 15:04:55 -0000 Received: (qmail 7439 invoked by uid 22791); 27 Jun 2011 15:04:52 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 27 Jun 2011 15:04:38 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5RF4bJd017410 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 27 Jun 2011 11:04:37 -0400 Received: from host1.jankratochvil.net ([10.3.113.13]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p5RF4ZGp029065 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 27 Jun 2011 11:04:37 -0400 Received: from host1.jankratochvil.net (localhost [127.0.0.1]) by host1.jankratochvil.net (8.14.4/8.14.4) with ESMTP id p5RF4Y47024451; Mon, 27 Jun 2011 17:04:34 +0200 Received: (from jkratoch@localhost) by host1.jankratochvil.net (8.14.4/8.14.4/Submit) id p5RF4WAX024439; Mon, 27 Jun 2011 17:04:32 +0200 Date: Mon, 27 Jun 2011 17:04:32 +0200 From: Jan Kratochvil To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Gabriel Dos Reis , gdb-patches@sourceware.org Subject: [gcc patch] Re: C++ member function template id not matching linkage name (PR debug/49408) Message-ID: <20110627150431.GA24889@host1.jankratochvil.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4E020D6A.7030401@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 On Wed, 22 Jun 2011 17:42:34 +0200, Jason Merrill wrote: > Well, the basic issue is that the "linkage name" is produced by > libiberty/cp-demangle.c and the DW_AT_name is produced by > gcc/cp/error.c, and they don't always agree on the same > pretty-printed representation of a C++ expression. Filed cross-check RFE GCC PR debug/49537 for it. > >The function linkage name has prefix: K<&(S::m(int))> > > This isn't actually valid C++ syntax, so the demangler should be adjusted. Attached. No regressions on gcc-4.6.0-10.fc15.x86_64. OK for check it in? It fixes (and GDB commands start to work): K<&(S::m(int))>::f (this=0x7fffffffdcaf) at tmplmember.C:6 -> K<&S::m>::f (this=0x7fffffffdcaf) at tmplmember.C:6 BTW the above change is when using DW_AT_linkage_name; FSF GDB HEAD still uses physname computation but that is also not right: K<&(S::m)>::f (this=0x7fffffffdcaf) at tmplmember.C:6 ------------------------------------------------------------------------------ struct S { void m (int x) {} }; template struct K { void f () { S s; (s.*F) (5); } }; int main () { K<&S::m> k; k.f (); } ------------------------------------------------------------------------------ Filed as GCC PR debug/49546 that GDB still does not work (*) for: (*) without implementing - filed as GDB PR c++/12936: On Wed, 22 Jun 2011 17:42:34 +0200, Jason Merrill wrote: # > Or maybe it is not a bug and one just has to accept the function prefix may # > not match its struct/class name? # This would also be a good idea, for robustness when this kind of # issue crops up. ------------------------------------------------------------------------------ struct S { static void m (int x) {} }; template // or: template struct K { void f () { T (0); } }; int main () { K<&S::m> k; // or: K k; k.f (); } ------------------------------------------------------------------------------ DWARF is exactly the for all the four combination of alternative lines. In the member function pointer above no alternative source form gets compiled. As both K<&S::m>::f() functions have exactly the same mangled name _ZN1KIXadL_ZN1S1mEiEEE1fEv , the demangled names should match the source form and in the first example it is the only allowed form of the source the function should demangled to K<&S::m>::f() - as it is by the patch below. But in the second example the template instace `struct K' DW_AT_name is K so it cannot match the function K<&S::m>::f() prefix. But in the second case it also cannot always match the source form when multiple source notations compile into exactly the same output. FYI: _ZN1KIXadL_ZN1S1mEiEEE1fEv typed name qualified name template name 'K' template argument list unary operator operator & typed name qualified name name 'S' name 'm' function type argument list builtin type int name 'f' function type argument list For GDB this patch resolves a regression of combination: Re: [patch] Follow DW_AT_linkage_name for methods #2 http://sourceware.org/ml/gdb-patches/2011-06/msg00040.html and FYI: updates to temargs.exp http://sourceware.org/ml/gdb-patches/2011-06/msg00138.html On Wed, 22 Jun 2011 21:55:47 +0200, Gabriel Dos Reis wrote: > I agree this isn't valid C++ syntax. However, it is a syntax used in certain > popular frameworks, e.g. QT signal/slots, and it unambiguously tells in a > readable manner what function is intended from overload resolution perspective. There is now for some time for the template: <2><92>: Abbrev Number: 11 (DW_TAG_template_value_param) <93> DW_AT_name : F <95> DW_AT_type : <0x16f> pointing (<0x16f>) to the member function so it is more up to the debugger (or front-end) to show it. Had to file GDB PR c++/12933 for it, though. Had to restrict the patch very much for the template function reference case as otherwise the parameter types are required even in templates there. Thanks, Jan libiberty/ 2011-06-27 Jan Kratochvil * cp-demangle.c (d_print_comp): Suppress argument list for function references as template arguments. * testsuite/demangle-expected: 3 new testcases for it. --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -4095,7 +4095,56 @@ d_print_comp (struct d_print_info *dpi, int options, case DEMANGLE_COMPONENT_ARGLIST: case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: if (d_left (dc) != NULL) - d_print_comp (dpi, options, d_left (dc)); + { + const struct demangle_component *left = d_left (dc); + + if (dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST + && left->type == DEMANGLE_COMPONENT_UNARY + && d_left (left)->type == DEMANGLE_COMPONENT_OPERATOR + && d_left (left)->u.s_operator.op->len == 1 + && d_left (left)->u.s_operator.op->name[0] == '&' + && d_right (left)->type == DEMANGLE_COMPONENT_TYPED_NAME + && d_left (d_right (left))->type == DEMANGLE_COMPONENT_QUAL_NAME + && d_right (d_right (left))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + { + /* Address of a function in template argument list must have its + argument list suppressed. The resolution is already not + ambiguous due to the function type expected by the template. + + template argument list + unary operator ... left + operator & ... d_left (left) + typed name ... d_right (left) + qualified name ... d_left (d_right (left)) + + function type ... d_right (d_right (left)) + argument list + */ + + d_print_expr_op (dpi, options, d_left (left)); + d_print_comp (dpi, options, d_left (d_right (left))); + } + else if (dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST + && left->type == DEMANGLE_COMPONENT_UNARY + && d_left (left)->type == DEMANGLE_COMPONENT_OPERATOR + && d_left (left)->u.s_operator.op->len == 1 + && d_left (left)->u.s_operator.op->name[0] == '&' + && d_right (left)->type == DEMANGLE_COMPONENT_QUAL_NAME) + { + /* Keep also already processed variant without the argument list. + + template argument list + unary operator ... left + operator & ... d_left (left) + qualified name ... d_right (left) + */ + + d_print_expr_op (dpi, options, d_left (left)); + d_print_comp (dpi, options, d_right (left)); + } + else + d_print_comp (dpi, options, left); + } if (d_right (dc) != NULL) { size_t len; --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3990,6 +3990,18 @@ outer(short (*)(int), long) _Z6outer2IsEPFilES1_ outer2(int (*)(long)) # +--format=gnu-v3 --no-params +_ZN1KIXadL_ZN1S1mEiEEE1fEv +K<&S::m>::f() +K<&S::m>::f +--format=gnu-v3 +_ZN1KILi1EXadL_ZN1S1mEiEEE1fEv +K<1, &S::m>::f() +# Here the `(int)' argument list of `S::m' is already removed. +--format=gnu-v3 +_ZN1KILi1EXadL_ZN1S1mEEEE1fEv +K<1, &S::m>::f() +# # Ada (GNAT) tests. # # Simple test.