From patchwork Mon Dec 12 13:53:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 705044 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 3tckpd5NKdz9t2b for ; Tue, 13 Dec 2016 00:54:17 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="AEkyRzZU"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=H6dtwa/4BFWoNvesW hvp0sfWGujHLi/bhfkkLVngRpxaDNU6KRm+Jk9vszlVqdhlNRJSsVhMngbcwpd2w KlciEMi1gUUyImtyB2NxJMvwwi/VAVxpkumYxEIN1mqq8pp2voRyhQTvCWs3Hv9A 5g8kLmWiuhjXvHwCCueQV7VSq0= 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=mUhHGfEewlfWlYG85EO8xEa IhPo=; b=AEkyRzZUTD55qatM8NF0YfquzM01uqih0I0jKmxgI9c6X7csCAcDLTX CCt/6OOkkRU1J48U+7UsK/cz4u4gY2lY1B8sGn9xqHTpUfPiiBVBm4x/qR7IO7CH PcxATNPC7bnK2oFT439NTnJGA+XeZqdDOdVo0JETnBGzGDCS0fvA= Received: (qmail 95825 invoked by alias); 12 Dec 2016 13:54:05 -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 95802 invoked by uid 89); 12 Dec 2016 13:54:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=displays, sidwell, Sidwell, short* X-HELO: mail-yw0-f195.google.com Received: from mail-yw0-f195.google.com (HELO mail-yw0-f195.google.com) (209.85.161.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 12 Dec 2016 13:53:54 +0000 Received: by mail-yw0-f195.google.com with SMTP id a10so7840915ywa.1 for ; Mon, 12 Dec 2016 05:53:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:subject:to:references:cc:from:message-id :date:user-agent:mime-version:in-reply-to; bh=23xI01Daba7kEEdIOPLbVDVxGwBI1boBbopSdIx5XFc=; b=RIMw5U/WoE5vEhNuHT0vC8URRJmeZeNg30MWImds+sRVJJ4xBxWgKGJZL3N7+3/+ph PRyC36ulJIR/yfhL6KCZklJBdrp471yFr19qDh3K4JLjdWIBrlsgVSW/oRbb/9HLOjGh Q8SfLErEbbaWVGFFajYnP/jcfw/iQZZuW6oCnLi2hXaTOrAApQR90PPnT2/jOD7V2/Lh DQimJMtDA5IZxM91jbhbHGQLfTHhDk4qtWD8PIv0j26UJC4z8yf8Oz/VTs4Z9dqGJw7x mc+xdIfyrDAZB8aZamdo828mi+DHbEgwDXM6JzbmPJFAR8Ri32SA6rtWiH/hRkAqufLk 0Tfw== X-Gm-Message-State: AKaTC032sF4Nw6zF9j5ZU12C93LXXGYx9jNMJ9otRIZsiNx1g5qcIpLNW6Jrrk3exgUrkw== X-Received: by 10.129.43.133 with SMTP id r127mr86340961ywr.213.1481550833125; Mon, 12 Dec 2016 05:53:53 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::a:6eb0]) by smtp.googlemail.com with ESMTPSA id l73sm18057815ywc.54.2016.12.12.05.53.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Dec 2016 05:53:52 -0800 (PST) Subject: Re: [C++/78252] libiberty demangler crash with lambda (auto) To: jason@redhat.com, iant@google.com References: <0cacb244-ba7b-c252-9958-3e30cdcea96a@acm.org> Cc: nickc@redhat.com, GCC Patches , binutils@sourceware.org, P@draigBrady.com From: Nathan Sidwell Message-ID: <36954543-3349-2eef-81f1-b8953407faf8@acm.org> Date: Mon, 12 Dec 2016 08:53:49 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <0cacb244-ba7b-c252-9958-3e30cdcea96a@acm.org> following discussion on the ABI list, here's an update to the generic lambda demangler patch. The guts of the patch are the same as before -- note when we're printing a generic lambda's parms and interpret template type parm references differently. however: 1) don't refer to this as a mangling bug, because it isn't 2) add a ':$n' suffix to each generic parm, as that's how g++ itself shows them in diagnostics and the like. I'll mark 78621 as not a bug too. ok? nathan 2016-12-12 Nathan Sidwell libiberty/ PR c++/78252 * cp-demangle.c (struct d_print_info): Add is_lambda_arg field. (d_print_init): Initialize it. (d_print_comp_inner) : Check is_lambda_arg for auto. : Skip smashing check when is_lambda_arg. : Increment is_lambda_arg around arg printing. * testsuite/demangle-expected: Add lambda auto mangling cases. gcc/testsuite/ PR c++/78252 * g++.dg/cpp1y/lambda-mangle-1.C: New. Index: libiberty/cp-demangle.c =================================================================== --- libiberty/cp-demangle.c (revision 243546) +++ libiberty/cp-demangle.c (working copy) @@ -343,6 +343,9 @@ struct d_print_info struct d_print_mod *modifiers; /* Set to 1 if we saw a demangling error. */ int demangle_failure; + /* Non-zero if we're printing a lambda argument. A template + parameter reference actually means 'auto'. */ + int is_lambda_arg; /* The current index into any template argument packs we are using for printing, or -1 to print the whole pack. */ int pack_index; @@ -4126,6 +4129,7 @@ d_print_init (struct d_print_info *dpi, dpi->opaque = opaque; dpi->demangle_failure = 0; + dpi->is_lambda_arg = 0; dpi->component_stack = NULL; @@ -4783,33 +4787,41 @@ d_print_comp_inner (struct d_print_info } case DEMANGLE_COMPONENT_TEMPLATE_PARAM: - { - struct d_print_template *hold_dpt; - struct demangle_component *a = d_lookup_template_argument (dpi, dc); - - if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) - a = d_index_template_argument (a, dpi->pack_index); + if (dpi->is_lambda_arg) + { + /* Show the template parm index, as that's how g++ displays + these, and future proofs us against potential + '[] (T *a, T *b) {...}'. */ + d_append_buffer (dpi, "auto:", 5); + d_append_num (dpi, dc->u.s_number.number + 1); + } + else + { + struct d_print_template *hold_dpt; + struct demangle_component *a = d_lookup_template_argument (dpi, dc); - if (a == NULL) - { - d_print_error (dpi); - return; - } + if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST) + a = d_index_template_argument (a, dpi->pack_index); - /* While processing this parameter, we need to pop the list of - templates. This is because the template parameter may - itself be a reference to a parameter of an outer - template. */ + if (a == NULL) + { + d_print_error (dpi); + return; + } - hold_dpt = dpi->templates; - dpi->templates = hold_dpt->next; + /* While processing this parameter, we need to pop the list + of templates. This is because the template parameter may + itself be a reference to a parameter of an outer + template. */ - d_print_comp (dpi, options, a); + hold_dpt = dpi->templates; + dpi->templates = hold_dpt->next; - dpi->templates = hold_dpt; + d_print_comp (dpi, options, a); - return; - } + dpi->templates = hold_dpt; + } + return; case DEMANGLE_COMPONENT_CTOR: d_print_comp (dpi, options, dc->u.s_ctor.name); @@ -4946,7 +4958,8 @@ d_print_comp_inner (struct d_print_info { /* Handle reference smashing: & + && = &. */ const struct demangle_component *sub = d_left (dc); - if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) + if (!dpi->is_lambda_arg + && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM) { struct d_saved_scope *scope = d_get_saved_scope (dpi, sub); struct demangle_component *a; @@ -5616,7 +5629,11 @@ d_print_comp_inner (struct d_print_info case DEMANGLE_COMPONENT_LAMBDA: d_append_string (dpi, "{lambda("); + /* Generic lambda auto parms are mangled as the template type + parm they are. */ + dpi->is_lambda_arg++; d_print_comp (dpi, options, dc->u.s_unary_num.sub); + dpi->is_lambda_arg--; d_append_string (dpi, ")#"); d_append_num (dpi, dc->u.s_unary_num.num + 1); d_append_char (dpi, '}'); Index: libiberty/testsuite/demangle-expected =================================================================== --- libiberty/testsuite/demangle-expected (revision 243546) +++ libiberty/testsuite/demangle-expected (working copy) @@ -4634,3 +4634,32 @@ _Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRp # ?: expression with missing third component could crash. AquT_quT_4mxautouT_4mxxx AquT_quT_4mxautouT_4mxxx + +# pr c++/78252 generic lambda mangling uses template parms, and leads +# to unbounded recursion if not dealt with properly +_Z7forwardIRZ3FoovEUlRT_E_EOS0_S1_ +Foo()::{lambda(auto:1&)#1}& forward(Foo()::{lambda(auto:1&)#1}&) + +_Z7forwardIZ3FoovEUlRiRT_E_EOS1_S2_ +Foo()::{lambda(int&, auto:1&)#1}&& forward(Foo()::{lambda(int&, auto:1&)#1}&) + +_Z7forwardIZ3FoovEUlRT_R1XIiEE0_EOS0_S1_ +Foo()::{lambda(auto:1&, X&)#2}&& forward&)#2}>(Foo()::{lambda(auto:1&, X&)#2}&) + +_Z7forwardIZ3FoovEUlPA5_T_E1_EOS0_RS0_ +Foo()::{lambda(auto:1 (*&&forward(auto:1&)) [5])#3} + +_Z3eatIZ3FoovEUlRiRT_E_EvS2_ +void eat(Foo()::{lambda(int&, auto:1&)#1}&) + +_Z3eatIZ3FoovEUlRT_R1XIiEE0_EvS1_ +void eat&)#2}>(Foo()::{lambda(auto:1&, X&)#2}&) + +_Z3eatIZ3FoovEUlPA5_T_E1_EvRS0_ +void eat(Foo()::{lambda(auto:1 (*&) [5])#3}) + +_Z3eatIPiZ3FoovEUlPT_PT0_E4_EvRS1_RS3_ +void eat(int*&, Foo()::{lambda(auto:1*, auto:2*)#6}&) + +_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_ +void eat()::{lambda(short*, auto:1*, auto:2*)#2}>(int*&, void Bar()::{lambda(short*, auto:1*, auto:2*)#2}&) Index: gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C =================================================================== --- gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C (revision 0) +++ gcc/testsuite/g++.dg/cpp1y/lambda-mangle-1.C (working copy) @@ -0,0 +1,88 @@ +// { dg-do compile { target c++14 } } + +// PRs 78621 + +// We erroneously mangled lambda auto parms as-if template parameters (T_), +// rather than auto (Da). Fixed in abi version 11 + +template class X; + +template +T &&forward (T &v) +{ + return static_cast (v); +} + +template +void eat (T &v) +{ +} + +template + void eat (S &, T &v) +{ +} + +void Foo () +{ + auto lam = [](auto &) { }; + auto lam_1 = [](int &, auto &) { }; + auto lam_2 = [](auto &, X &) { }; + auto lam_3 = [](auto (*)[5]) { }; + + forward (lam); + forward (lam_1); + forward (lam_2); + forward (lam_3); + + eat (lam); + eat (lam_1); + eat (lam_2); + eat (lam_3); + + // The auto lambda should mangle similarly to the non-auto one + auto lambda_1 = [](float *, float *) { }; + auto lambda_2 = [](auto *, auto *) { }; + auto lambda_3 = [](auto *, auto *) { }; + + int *i; + + eat (i, lambda_1); + eat (i, lambda_2); + + // The autos should squangle to the first one. + eat (lambda_2, lambda_3); +} + +template void Bar () +{ + auto lambda_1 = [](X *, float *, float *) { }; + auto lambda_2 = [](X *, auto *, auto *) { }; + auto lambda_3 = [](X *, auto *...) {}; + + int *i; + + eat (i, lambda_1); + eat (i, lambda_2); + eat (i, lambda_3); +} + +void Baz () +{ + Bar (); +} + +// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_E_EOS0_S1_:" } } +// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRiRT_E0_EOS1_S2_:" } } +// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlRT_R1XIiEE1_EOS0_S1_:" } } +// { dg-final { scan-assembler "_Z7forwardIZ3FoovEUlPA5_T_E2_EOS0_RS0_:" } } +// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_E_EvS1_:" } } +// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRiRT_E0_EvS2_:" } } +// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlRT_R1XIiEE1_EvS1_:" } } +// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPA5_T_E2_EvRS0_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPfS1_E3_EvRT_RT0_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3FoovEUlPT_PT0_E4_EvRS1_RS3_:" } } +// { dg-final { scan-assembler "_Z3eatIZ3FoovEUlPT_PT0_E4_Z3FoovEUlS1_S3_E5_EvRS0_RS2_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPfS3_E_EvRT_RT0_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_PT0_E0_EvRS3_RS5_:" } } +// { dg-final { scan-assembler "_Z3eatIPiZ3BarIsEvvEUlPsPT_zE1_EvRS3_RT0_:" } }