From patchwork Wed Jun 9 19:14:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 55119 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 E762FB7D29 for ; Thu, 10 Jun 2010 05:11:57 +1000 (EST) Received: (qmail 20418 invoked by alias); 9 Jun 2010 19:11:56 -0000 Received: (qmail 20389 invoked by uid 22791); 9 Jun 2010 19:11:53 -0000 X-SWARE-Spam-Status: No, hits=-6.0 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; Wed, 09 Jun 2010 19:11:49 +0000 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o59JBlsu001942 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 9 Jun 2010 15:11:47 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o59JBkRL010771 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 9 Jun 2010 15:11:47 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.3/8.14.3) with ESMTP id o59JEsjs015271; Wed, 9 Jun 2010 21:14:54 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.3/8.14.3/Submit) id o59JEsTi015270; Wed, 9 Jun 2010 21:14:54 +0200 Date: Wed, 9 Jun 2010 21:14:54 +0200 From: Jakub Jelinek To: Jason Merrill , Ian Lance Taylor Cc: gcc-patches@gcc.gnu.org, binutils@sources.redhat.com Subject: [PATCH] Fix DEMANGLE_COMPONENT_TEMPLATE_ARGLIST demangling (PR other/43838) Message-ID: <20100609191454.GG10293@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-08-17) 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 Hi! The dpi->len -= 2; trick to revert d_append_string (dpi, ", "); is too fragile, as can be seen on the testcase below. There are 2 problems: 1) the buffer can be flushed in the d_append_string (dpi, ", "); call. If the recursive call doesn't print anything, it can't undo the ", " char addition - dpi->len will go negative. 2) if a flush (or more) happens during the recursive d_print_comp call then dpi->len might be equal to the saved len, but some characters were actually printed (if it is a multiple of 255 chars). By decrementing dpi->len then we eat two last characters, which won't be ", ". 1) is fixed by flushing before the d_append_string call if the buffer is almost full. 2) is fixed by adding a counter how many flushes happened and comparing that to a saved value in addition to len. Ok for trunk/4.5/4.4? 2010-06-09 Jakub Jelinek PR other/43838 * cp-demangle.c (struct d_print_info): Add flush_count field. (d_print_init): Initialize it to 0. (d_print_flush): Increment it. (d_print_comp): If needed flush before appending ", ". Only decrement dpi->len if no flushes happened during the recursive call. * testsuite/demangle-expected: Add a test for this. Jakub --- libiberty/cp-demangle.c.jj 2010-05-07 09:17:47.000000000 +0200 +++ libiberty/cp-demangle.c 2010-06-09 20:19:56.000000000 +0200 @@ -302,6 +302,8 @@ struct d_print_info /* The current index into any template argument packs we are using for printing. */ int pack_index; + /* Number of d_print_flush calls so far. */ + unsigned long int flush_count; }; #ifdef CP_DEMANGLE_DEBUG @@ -3285,6 +3287,7 @@ d_print_init (struct d_print_info *dpi, dpi->last_char = '\0'; dpi->templates = NULL; dpi->modifiers = NULL; + dpi->flush_count = 0; dpi->callback = callback; dpi->opaque = opaque; @@ -3314,6 +3317,7 @@ d_print_flush (struct d_print_info *dpi) dpi->buf[dpi->len] = '\0'; dpi->callback (dpi->buf, dpi->len, dpi->opaque); dpi->len = 0; + dpi->flush_count++; } /* Append characters and buffers for printing. */ @@ -4047,12 +4051,18 @@ d_print_comp (struct d_print_info *dpi, if (d_right (dc) != NULL) { size_t len; + unsigned long int flush_count; + /* Make sure ", " isn't flushed by d_append_string, otherwise + dpi->len -= 2 wouldn't work. */ + if (dpi->len >= sizeof (dpi->buf) - 2) + d_print_flush (dpi); d_append_string (dpi, ", "); len = dpi->len; + flush_count = dpi->flush_count; d_print_comp (dpi, d_right (dc)); /* If that didn't print anything (which can happen with empty template argument packs), remove the comma and space. */ - if (dpi->len == len) + if (dpi->flush_count == flush_count && dpi->len == len) dpi->len -= 2; } return; --- libiberty/testsuite/demangle-expected.jj 2010-05-28 14:36:06.000000000 +0200 +++ libiberty/testsuite/demangle-expected 2010-06-09 20:36:34.000000000 +0200 @@ -3951,6 +3951,9 @@ decltype (({parm#1}.(operator-))()) h --format=gnu-v3 _Z1fDn f(decltype(nullptr)) +--format=gnu-v3 +_ZN5aaaaa6bbbbbb5cccccIN23ddddddddddddddddddddddd3eeeENS2_4ffff16ggggggggggggggggENS0_9hhhhhhhhhES6_S6_S6_S6_S6_S6_S6_EE +aaaaa::bbbbbb::ccccc # # Ada (GNAT) tests. #