From patchwork Tue May 27 11:57:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 352879 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 20BDC1400D2 for ; Tue, 27 May 2014 21:58:04 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=iWPXiX1MKA5mnbCLTQFBViuJAmpZJmanzDkcbvZDnIyR5ajqQHHmm Ke9Ny2Cz0iaSD5mH032tQJyPz5/mVF4KUQ8L2fdhTfv/vgaA4OLqrBmJVRKJhJ/B XkMy4V900rBDog2AlwbKSCnF8zz27eIf3eRVbuF7HTS/fJ8TpH/lzo= 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:from :to:subject:date:message-id:in-reply-to:references; s=default; bh=t1DbK+m7vCQfdpxg6bELSVg1hFw=; b=NdwyOpmi74ztQEjHYmuuSDtk2etx sWPMvYc46iTgjiEJAcKqqlUcz40ZdVsGy8OgcSCC92oTHoCbstvTOfbwC1231ef1 g1fjE7JQvcOCwvxhnLC9LyncmuiaWDszsLpKhBmS+Orw1rj5phULRFhpc3R6IWx9 YHz3L5xZbKMAp/o= Received: (qmail 5106 invoked by alias); 27 May 2014 11:57:44 -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 5006 invoked by uid 89); 27 May 2014 11:57:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.6 required=5.0 tests=AWL, BAYES_00, LIKELY_SPAM_BODY, RP_MATCHES_RCVD, SPAM_SUBJECT, SPF_HELO_PASS, SPF_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 May 2014 11:57:42 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4RBvfWV027299 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 27 May 2014 07:57:41 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4RBvape007322 for ; Tue, 27 May 2014 07:57:40 -0400 From: Pedro Alves To: gcc-patches@gcc.gnu.org Subject: [PATCH 3/3] mangler/demangler dogfooding Date: Tue, 27 May 2014 12:57:36 +0100 Message-Id: <1401191856-27585-4-git-send-email-palves@redhat.com> In-Reply-To: <1401191856-27585-1-git-send-email-palves@redhat.com> References: <1401191856-27585-1-git-send-email-palves@redhat.com> This patch teaches g++ to try to demangle any symbol it generates/mangles, when checking is enabled in the build, as soon as the symbol is mangled. The idea here is validate the demangling as close as possible to the generator as possible. This allows catching demangler bugs/crashes much earlier in the cycle, when building libstdc++ and friends, when running g++'s testsuite, and even potentially earlier than that, when developers work on new C++11/14-and-beyond features, which influence mangling, validating against some random test that's not in the testsuite yet (and sometimes doesn't make it there either), rather than much later in production when the user is trying to debug the code, or the program tries to generate a backtrace. Both libstdc++ and the testsuite include a good set of tricky symbols to demangle, and the latter naturally includes all sort of random, weird, code full of corner cases. And, I assume g++ maintainers once in a while run WIP g++ through some piles of very complicated C++ code. It seems clear to me that ideally we should be able to do assert (demangle (mangle (symbol)); But, unfortunately, we can't yet. I built g++ and ran the testsuite with a variant of this patch that would print the mangled symbol if the demangling fails, but would otherwise continue without aborting, and I found out that: - we can't demangle ~40 symbols generated while building libstdc++ and friends. E.g.: _ZN9__gnu_cxx13new_allocatorINSt13__future_base13_State_baseV2EE9constructIS2_IEEEvPT_DpOT0_ _ZNSt15_Sp_counted_ptrIDnLN9__gnu_cxx12_Lock_policyE1EEC1ERKS3_ - we can't demangle around ~2600 (!) symbols generated while running the g++ testsuite. E.g., _Z1f1SIXadL3FooEEE _ZZ4mainENKUlRT_E_clI1SEEDaS0_ Of course, these all may well be mangler bugs rather than demangler bugs. It's possible that these are already known mangler bugs even, that have been fixed, but require a higher -fabi-version=X. I didn't investigate that. Bootstrapped and regtested on x86_64 Fedora 20. gcc/ 2014-05-27 Pedro Alves * cp/mangle.c: Include demangle.h. (finish_mangling_internal) [ENABLE_CHECKING]: Demangle the just mangled symbol. --- gcc/cp/mangle.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 4205fec..c4eb5dc 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "wide-int.h" +#include "demangle.h" /* Debugging support. */ @@ -3367,6 +3368,35 @@ finish_mangling_internal (const bool warn) /* Null-terminate the string. */ write_char ('\0'); + +#if ENABLE_CHECKING + /* Make sure we can demangle what we just generated. */ + { + const char *str ATTRIBUTE_UNUSED; + const char *mangled_str; + int dmgl_opts; + + dmgl_opts = (DMGL_VERBOSE + | DMGL_ANSI + | DMGL_GNU_V3 + | DMGL_RET_POSTFIX + | DMGL_PARAMS); + + mangled_str = (const char *) obstack_base (mangle_obstack); + str = cplus_demangle_v3 (mangled_str, dmgl_opts); +#if 0 + /* XXX The above catches potential demangler crashes. And, + ideally, we'd also abort if demangling fails. However, we + can't do that because the demangler isn't able to demangle all + symbols we generate by default. Some failures might be + demangler bugs, others unknown mangler bugs, and others known + mangler bugs fixed with a higher -fabi-version, which the + demangler doesn't have a workaround for. */ + if ((str != NULL) != (mangled_str[0] == '_' && mangled_str[1] == 'Z')) + internal_error ("demangling failed for: %s", mangled_str); +#endif + } +#endif }