From patchwork Mon Apr 1 02:17:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1072180 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-498676-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="MQE3rfU6"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="VOxaHbI3"; dkim-atps=neutral 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 44XbZr6CVcz9sQr for ; Mon, 1 Apr 2019 13:17:22 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=nJTfPmg7l58RhP/JWU83lbCyZghJg+zzv/RSDoTEIUFoPAw/Py DmkCrZ9x/dK3BE89eR9lOxTSRZiXtW/fI0JaQDaPjwHIpaIBeoUQLsK569FyA2zt ZVbYWZDtQ91FhDLl2rm6bqhzkvAbKoQeog8ut8nHutuBrDEnBjojmFB7Y= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=ZO4OuQebBZfUlUDIOixzl0ys0PI=; b=MQE3rfU6BQYa3sZQ/4mm to8ckLRa+22OaiBs8IZScgDicra5r8144hHK92/aDXOXguHReq9Y+dTuGjFDYk9+ u7jlEVfnVYZieGT7oyG/Wx0sua3I4l2+cWFRbRatLSOySBWrrqdjlsytXy3ItbjS GaYAhjC3CPFid9lKrGE57zY= Received: (qmail 72993 invoked by alias); 1 Apr 2019 02:17:11 -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 72840 invoked by uid 89); 1 Apr 2019 02:17:10 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=ftb, char*, sk:TREE_ST, sk:tree_st X-HELO: mail-qk1-f174.google.com Received: from mail-qk1-f174.google.com (HELO mail-qk1-f174.google.com) (209.85.222.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 01 Apr 2019 02:17:06 +0000 Received: by mail-qk1-f174.google.com with SMTP id c189so4706524qke.6 for ; Sun, 31 Mar 2019 19:17:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=+BA2C7uRDpNNB5Uy/KJpw1/c8XX/LH7Iusl2CLIj7G4=; b=VOxaHbI3v+RP4ks+j1VgE2RAjz4OmoRDa++aQ3w24zk4JE5EqkXdJZyqz6h7W3BMB9 zq5HCalm1mKFUjgEHLeIvMJMCG9Jz5wPhGhszGS2P9kUzjZ7CYqOHf6ZxB/bnMnL9TD3 KGlArxW9rJ6yL3TWcZEg2nfK/dtDP2YZz80ayU+M5I3Xgb80VPjbuBHZ0K/GQp5s3+0W nJfFAuZuRj7PH24E9NkksfjZ7e2NWV49vYLZVr4DyLXUEqikEu6BRqLYlUcAfa0B+vJU nCutP+JDgR75hq6rFMi8HsgfmvgSrFK3WM7FNmJXyzzHDzE0jif8bV0WJ5S9GxYfdO+O v+3w== Received: from [192.168.0.41] (75-166-119-163.hlrn.qwest.net. [75.166.119.163]) by smtp.gmail.com with ESMTPSA id s54sm5351186qtb.83.2019.03.31.19.17.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 31 Mar 2019 19:17:02 -0700 (PDT) To: Jason Merrill , gcc-patches From: Martin Sebor Subject: [PATCH] handle strings as template arguments (PR 47488, 89833, 89876) Message-ID: <1e94288b-f43d-9e24-40c2-880a36738771@gmail.com> Date: Sun, 31 Mar 2019 20:17:00 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 X-IsSubscribed: yes To fix PR 89833, a P1 regression, the attached patch tries to handle string literals as C++ 2a non-type template arguments by treating them the same as brace enclosed initializer lists (where the latter are handled correctly). The solution makes sure equivalent forms of array initializers such as for char[5]: "\0\1\2" "\0\1\2\0" { 0, 1, 2 } { 0, 1, 2, 0 } { 0, 1, 2, 0, 0 } are treated as the same, both for overloading and mangling. Ditto for the following equivalent forms: "" "\0" "\0\0\0\0" { } { 0 } { 0, 0, 0, 0, 0 } and for these of struct { char a[5], b[5], c[5]; }: { {0,0,0,0,0}, {0,0,0,0}, {0,0,0} } { { 0 }, { } } { "" } Since this is not handled correctly by the current code (see PR 89876 for a test case) the patch also fixes that. I'm not at all confident the handling of classes with user-defined constexpr ctors is 100% correct. (I use triviality to constrain the solution for strings but that was more of an off-the-cuff guess than a carefully considered decision). The g++.dg/abi/mangle71.C test is all I've got in terms of verifying it works correctly. I'm quite sure the C++ 2a testing could stand to be beefed up. The patch passes x86_64-linux bootstrap and regression tests. There are a few failures in check-c++-all tests that don't look related to the changes (I see them with an unpatched GCC as well): g++.dg/spellcheck-macro-ordering-2.C g++.dg/cpp0x/auto52.C g++.dg/cpp1y/auto-neg1.C g++.dg/other/crash-9.C Martin PR c++/89833 - sorry, unimplemented: string literal in function template signature gcc/cp/ChangeLog: PR c++/89833 * decl.c (reshape_init_array_1): Strip trailing zero-initializers from arrays of trivial type and known size. * mangle.c (write_expression): Convert braced initializer lists to STRING_CSTs. (write_expression): Trim trailing zero-initializers from arrays of trivial type. (write_template_arg_literal): Mangle strings the same as braced initializer lists. Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 270037) +++ gcc/cp/decl.c (working copy) @@ -5799,6 +5799,9 @@ reshape_init_array_1 (tree elt_type, tree max_inde max_index_cst = tree_to_uhwi (fold_convert (size_type_node, max_index)); } + /* Set to the index of the last element with a non-zero initializer. + Initializers for elements past this one can be dropped. */ + unsigned HOST_WIDE_INT last_nonzero = -1; /* Loop until there are no more initializers. */ for (index = 0; d->cur != d->end && (!sized_array_p || index <= max_index_cst); @@ -5817,11 +5820,28 @@ reshape_init_array_1 (tree elt_type, tree max_inde if (!TREE_CONSTANT (elt_init)) TREE_CONSTANT (new_init) = false; + if (!initializer_zerop (elt_init)) + last_nonzero = index; + /* This can happen with an invalid initializer (c++/54501). */ if (d->cur == old_cur && !sized_array_p) break; } + if (sized_array_p && trivial_type_p (elt_type)) + { + /* Strip trailing zero-initializers from an array of a trivial + type of known size. They are redundant and get in the way + of telling them apart from those with implicit zero value. */ + unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (new_init); + if (last_nonzero > nelts) + nelts = 0; + else if (last_nonzero < nelts - 1) + nelts = last_nonzero + 1; + + vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts); + } + return new_init; } Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 270037) +++ gcc/cp/mangle.c (working copy) @@ -3136,18 +3136,48 @@ write_expression (tree expr) } else if (code == CONSTRUCTOR) { - vec *elts = CONSTRUCTOR_ELTS (expr); - unsigned i; tree val; + bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr); + tree etype = TREE_TYPE (expr); - if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + if (braced_init) write_string ("il"); else { write_string ("tl"); - write_type (TREE_TYPE (expr)); + write_type (etype); } - FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) - write_expression (val); + + if (!initializer_zerop (expr) || !trivial_type_p (etype)) + { + /* Convert braced initializer lists to STRING_CSTs so that + A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while + still using the latter mangling for strings that + originated as braced initializer lists. */ + expr = braced_lists_to_strings (etype, expr); + + if (TREE_CODE (expr) == CONSTRUCTOR) + { + vec *elts = CONSTRUCTOR_ELTS (expr); + unsigned last_nonzero = -1, i; + tree val; + + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + if (!initializer_zerop (val)) + last_nonzero = i; + + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + { + if (i > last_nonzero) + break; + write_expression (val); + } + } + else + { + gcc_assert (TREE_CODE (expr) == STRING_CST); + write_expression (expr); + } + } write_char ('E'); } else if (code == LAMBDA_EXPR) @@ -3353,9 +3383,15 @@ write_expression (tree expr) static void write_template_arg_literal (const tree value) { - write_char ('L'); - write_type (TREE_TYPE (value)); + if (TREE_CODE (value) == STRING_CST) + /* Temporarily mangle strings as braced initializer lists. */ + write_string ("tl"); + else + write_char ('L'); + tree valtype = TREE_TYPE (value); + write_type (valtype); + /* Write a null member pointer value as (type)0, regardless of its real representation. */ if (null_member_pointer_value_p (value)) @@ -3397,9 +3433,36 @@ write_template_arg_literal (const tree value) break; case STRING_CST: - sorry ("string literal in function template signature"); - break; + { + /* Mangle strings the same as braced initializer lists. */ + unsigned n = TREE_STRING_LENGTH (value); + const char *str = TREE_STRING_POINTER (value); + /* Count the number of trailing nuls and subtract them from + STRSIZE because they don't need to be mangled. */ + tree strsizenode = TYPE_SIZE_UNIT (TREE_TYPE (value)); + unsigned strsize = tree_to_uhwi (strsizenode); + if (strsize > n) + strsize = n; + for (const char *p = str + strsize - 1; ; --p) + { + if (*p || p == str) + { + strsize -= str + strsize - !!*p - p; + break; + } + } + tree eltype = TREE_TYPE (valtype); + for (const char *p = str; strsize--; ++p) + { + write_char ('L'); + write_type (eltype); + write_unsigned_number (*(const unsigned char*)p); + write_string ("E"); + } + break; + } + default: gcc_unreachable (); } Index: gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C (working copy) @@ -0,0 +1,137 @@ +// PR c++/89833 +// Test to verify that constant array elements initialized to zero +// evaluate to zero regardless of the form of their initilizer, +// and irrespective whether it's explicit or implicit. + +// { dg-do compile { target c++11 } } +// { dg-options "-Wall" } + +static const char all_zero[1024] = { }; + +namespace test_int +{ +constexpr int a[][3] = { { 0, 0 }, { 0 }, { } }; + +static_assert (sizeof a == sizeof (int) * 3 * 3); + +static_assert ( a[0][0] == 0 && a[0][1] == 0 && a[0][2] == 0 + && a[1][0] == 0 && a[1][1] == 0 && a[1][2] == 0 + && a[2][0] == 0 && a[2][1] == 0 && a[2][2] == 0); + +constexpr int b[3][3] = { { 0, 0 }, { 0 } }; + +static_assert (sizeof b == sizeof (int) * 3 * 3); + +static_assert ( b[0][0] == 0 && b[0][1] == 0 && b[0][2] == 0 + && b[1][0] == 0 && b[1][1] == 0 && b[1][2] == 0 + && b[2][0] == 0 && b[2][1] == 0 && b[2][2] == 0); + +constexpr int c[3][3] = { { } }; + +static_assert (sizeof c == sizeof (int) * 3 * 3); + +static_assert ( c[0][0] == 0 && c[0][1] == 0 && c[0][2] == 0 + && c[1][0] == 0 && c[1][1] == 0 && c[1][2] == 0 + && c[2][0] == 0 && c[2][1] == 0 && c[2][2] == 0); + +} + +namespace test_char +{ +constexpr char a[][3] = { { 0, 0 }, { 0 }, { } }; + +static_assert (sizeof a == sizeof (char) * 3 * 3); + +static_assert ( a[0][0] == 0 && a[0][1] == 0 && a[0][2] == 0 + && a[1][0] == 0 && a[1][1] == 0 && a[1][2] == 0 + && a[2][0] == 0 && a[2][1] == 0 && a[2][2] == 0); + +constexpr char b[3][3] = { { 0, 0 }, { 0 } }; + +static_assert (sizeof b == sizeof (char) * 3 * 3); + +static_assert ( b[0][0] == 0 && b[0][1] == 0 && b[0][2] == 0 + && b[1][0] == 0 && b[1][1] == 0 && b[1][2] == 0 + && b[2][0] == 0 && b[2][1] == 0 && b[2][2] == 0); + +constexpr char c[3][3] = { { } }; + +static_assert (sizeof c == sizeof (char) * 3 * 3); + +static_assert ( c[0][0] == 0 && c[0][1] == 0 && c[0][2] == 0 + && c[1][0] == 0 && c[1][1] == 0 && c[1][2] == 0 + && c[2][0] == 0 && c[2][1] == 0 && c[2][2] == 0); +} + +namespace test_string +{ +constexpr char a[][3] = { "\0", "", { } }; + +static_assert (sizeof a == sizeof (char) * 3 * 3); + +static_assert ( a[0][0] == 0 && a[0][1] == 0 && a[0][2] == 0 + && a[1][0] == 0 && a[1][1] == 0 && a[1][2] == 0 + && a[2][0] == 0 && a[2][1] == 0 && a[2][2] == 0); + +constexpr char b[3][3] = { "\0", "" }; + +static_assert (sizeof b == sizeof (char) * 3 * 3); + +static_assert ( b[0][0] == 0 && b[0][1] == 0 && b[0][2] == 0 + && b[1][0] == 0 && b[1][1] == 0 && b[1][2] == 0 + && b[2][0] == 0 && b[2][1] == 0 && b[2][2] == 0); + +constexpr char c[3][3] = { }; + +static_assert (sizeof c == sizeof (char) * 3 * 3); + +static_assert ( c[0][0] == 0 && c[0][1] == 0 && c[0][2] == 0 + && c[1][0] == 0 && c[1][1] == 0 && c[1][2] == 0 + && c[2][0] == 0 && c[2][1] == 0 && c[2][2] == 0); +} + +namespace test_string_member +{ +struct B { struct A { char a[5]; } a[2]; }; + +constexpr B b[3] = + { + /* [0] */ + { + /* a = */ + { + /* a[0] */ { { 0, 0, 0, 0, 0 } }, + /* a[1] */ { { 0, 0 } } + } + }, + /* [1] */ + { + /* a */ + { + /* a[0] */ { "\0\0\0\0" }, + /* a[0] */ { "" } + } + }, + }; + +static_assert ( b[0].a[0].a[0] == 0 + && b[0].a[0].a[1] == 0 + && b[0].a[0].a[2] == 0 + && b[0].a[0].a[3] == 0 + && b[0].a[0].a[4] == 0 + && b[0].a[1].a[0] == 0 + && b[0].a[1].a[1] == 0 + && b[0].a[1].a[2] == 0 + && b[0].a[1].a[3] == 0 + && b[0].a[1].a[4] == 0 + && b[1].a[0].a[0] == 0 + && b[1].a[0].a[1] == 0 + && b[1].a[0].a[2] == 0 + && b[1].a[0].a[3] == 0 + && b[1].a[0].a[4] == 0 + && b[2].a[0].a[0] == 0 + && b[2].a[0].a[1] == 0 + && b[2].a[0].a[2] == 0 + && b[2].a[0].a[3] == 0 + && b[2].a[0].a[4] == 0); +} Index: gcc/testsuite/g++.dg/cpp2a/nontype-class15.C =================================================================== --- gcc/testsuite/g++.dg/cpp2a/nontype-class15.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp2a/nontype-class15.C (working copy) @@ -0,0 +1,222 @@ +// PR c++/89833 +// Test to verify that the same specializations on non-type template +// parameters of class types are in fact treated as the same. +// { dg-do compile { target c++2a } } + +struct A1 { char c[5]; }; + +template struct B { }; + +// All of the following name the same type. +typedef B A______; +typedef B A_Z____; +typedef B A_ZZ___; +typedef B A_ZZZ__; +typedef B A_ZZZZ_; +typedef B A_ZZZZZ; + +// Verify the types are indeed the same by redeclaring the same identifier +// of each of them. +extern A______ same_type_B_A1; +extern A_Z____ same_type_B_A1; +extern A_ZZ___ same_type_B_A1; +extern A_ZZZ__ same_type_B_A1; +extern A_ZZZZ_ same_type_B_A1; +extern A_ZZZZZ same_type_B_A1; + + +// All of the following use a string to initialize the array but +// also name the same type as the above. +typedef B S_z____; +typedef B S_Zz___; +typedef B S_ZZz__; +typedef B S_ZZZz_; +typedef B S_ZZZZz; + +// Verify the types are indeed the same by redeclaring the same identifier +// of each of them. +extern S_z____ same_type_B_A1; +extern S_Zz___ same_type_B_A1; +extern S_Zz___ same_type_B_A1; +extern S_ZZz__ same_type_B_A1; +extern S_ZZZz_ same_type_B_A1; +extern S_ZZZZz same_type_B_A1; + + +// All of the following also name the same type (distinct from +// the above). +typedef B A_A____; +typedef B A_AZ___; +typedef B A_AZZ__; +typedef B A_AZZZ_; +typedef B A_AZZZZ; + +extern A_A____ same_type_B_A1_A; +extern A_AZ___ same_type_B_A1_A; +extern A_AZZ__ same_type_B_A1_A; +extern A_AZZZ_ same_type_B_A1_A; +extern A_AZZZZ same_type_B_A1_A; + + +struct A3 { char a[5], b[5], c[5]; }; +template struct B3 { }; + +// These all name the same type. +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; + +// These all name the same type. +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; +typedef B3 B3_A3_AB________IJKL_; + +// Types with the same name must be the same (and so redefinitions +// must be accepted). Likewise, overloads on distinct types must +// be accepted. +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3_______________1; +typedef B3 B3_A3______________1_; +typedef B3 B3_A3______________1_; +typedef B3 B3_A3_____________1__; +typedef B3 B3_A3_____________1__; +typedef B3 B3_A3____________1___; +typedef B3 B3_A3____________1___; +typedef B3 B3_A3___________1____; +typedef B3 B3_A3__________1_____; +typedef B3 B3_A3__________1_____; +typedef B3 B3_A3__________1_____; +typedef B3 B3_A3_________1______; +typedef B3 B3_A3________1_______; +typedef B3 B3_A3_______1________; +typedef B3 B3_A3______1_________; +typedef B3 B3_A3_____1__________; +typedef B3 B3_A3_____1__________; +typedef B3 B3_A3_____1__________; +typedef B3 B3_A3____1___________; +typedef B3 B3_A3___1____________; +typedef B3 B3_A3__1_____________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; +typedef B3 B3_A3_1______________; + +typedef B3 B3_A3_1_____________1; +typedef B3 B3_A3_1_____________1; +typedef B3 B3_A3_1_____________1; +typedef B3 B3_A3__1___________1_; +typedef B3 B3_A3__1___________1_; +typedef B3 B3_A3__1___________1_; + +// Same as above. +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; +typedef B3 B3_A3________________; + +typedef B3 B3_A3_______________1; +typedef B3 B3_A3______________1_; +typedef B3 B3_A3_____________1__; +typedef B3 B3_A3____________1___; +typedef B3 B3_A3___________1____; +typedef B3 B3_A3__________1_____; +typedef B3 B3_A3_________1______; +typedef B3 B3_A3________1_______; +typedef B3 B3_A3_______1________; +typedef B3 B3_A3______1_________; +typedef B3 B3_A3_____1__________; +typedef B3 B3_A3____1___________; +typedef B3 B3_A3___1____________; +typedef B3 B3_A3__1_____________; +typedef B3 B3_A3_1______________; + +typedef B3 B3_A3_1_____________1; +typedef B3 B3_A3_1_____________1; +typedef B3 B3_A3__1___________1_; +typedef B3 B3_A3__1___________1_; +typedef B3 B3_A3__1___________1_; + +void f_b3_a3 (B3_A3________________) { } +void f_b3_a3 (B3_A3_______________1) { } +void f_b3_a3 (B3_A3______________1_) { } +void f_b3_a3 (B3_A3_____________1__) { } +void f_b3_a3 (B3_A3____________1___) { } +void f_b3_a3 (B3_A3___________1____) { } +void f_b3_a3 (B3_A3__________1_____) { } +void f_b3_a3 (B3_A3_________1______) { } +void f_b3_a3 (B3_A3________1_______) { } +void f_b3_a3 (B3_A3_______1________) { } +void f_b3_a3 (B3_A3______1_________) { } +void f_b3_a3 (B3_A3_____1__________) { } +void f_b3_a3 (B3_A3____1___________) { } +void f_b3_a3 (B3_A3___1____________) { } +void f_b3_a3 (B3_A3__1_____________) { } +void f_b3_a3 (B3_A3_1______________) { } +void f_b3_a3 (B3_A3_1_____________1) { } +void f_b3_a3 (B3_A3__1___________1_) { } + +typedef B3 B3_A3_ABZDZZZZZZIJKLZ; +typedef B3 B3_A3_ABZDZZZ1ZZIJKLZ; +typedef B3 B3_A3_ABZDZZ1ZZZIJKLZ; + +void f (B3_A3_ABZDZZZZZZIJKLZ) { } +void f (B3_A3_ABZDZZZ1ZZIJKLZ) { } +void f (B3_A3_ABZDZZ1ZZZIJKLZ) { } Index: gcc/testsuite/g++.dg/abi/mangle69.C =================================================================== --- gcc/testsuite/g++.dg/abi/mangle69.C (nonexistent) +++ gcc/testsuite/g++.dg/abi/mangle69.C (working copy) @@ -0,0 +1,164 @@ +// { dg-do compile { target c++2a } } + +struct A1 { char c[5]; }; + +template struct B { }; + +// All of the following name the same type. +typedef B A______; +typedef B A_Z____; +typedef B A_ZZ___; +typedef B A_ZZZ__; +typedef B A_ZZZZ_; +typedef B A_ZZZZZ; + +// Verify that the types mangle the same. +void a______ (A______) { } +// { dg-final { scan-assembler "_Z7a______1BIXtl2A1EEE" } } + +void a_z____ (A_Z____) { } +// { dg-final { scan-assembler "_Z7a_z____1BIXtl2A1EEE" } } + +void a_zz___ (A_ZZ___) { } +// { dg-final { scan-assembler "_Z7a_zz___1BIXtl2A1EEE" } } + +void a_zzz__ (A_ZZZ__) { } +// { dg-final { scan-assembler "_Z7a_zzz__1BIXtl2A1EEE" } } + +void a_zzzz_ (A_ZZZZ_) { } +// { dg-final { scan-assembler "_Z7a_zzzz_1BIXtl2A1EEE" } } + +void a_zzzzz (A_ZZZZZ) { } +// { dg-final { scan-assembler "_Z7a_zzzzz1BIXtl2A1EEE" } } + + +// All of the following use a string to initialize the array but +// also name the same type as the above. +typedef B S_z____; +typedef B S_Zz___; +typedef B S_ZZz__; +typedef B S_ZZZz_; +typedef B S_ZZZZz; + +// Verify that the types mangle the same. +void s_z____ (S_z____) { } +// { dg-final { scan-assembler "_Z7s_z____1BIXtl2A1EEE" } } + +void s_Zz___ (S_Zz___) { } +// { dg-final { scan-assembler "_Z7s_Zz___1BIXtl2A1EEE" } } + +void s_ZZz__ (S_ZZz__) { } +// { dg-final { scan-assembler "_Z7s_ZZz__1BIXtl2A1EEE" } } + +void s_ZZZz_ (S_ZZZz_) { } +// { dg-final { scan-assembler "_Z7s_ZZZz_1BIXtl2A1EEE" } } + +void s_ZZZZz (S_ZZZZz) { } +// { dg-final { scan-assembler "_Z7s_ZZZZz1BIXtl2A1EEE" } } + + +// All of the following also name the same type (distinct from +// the above). +typedef B A_A____; +typedef B A_AZ___; +typedef B A_AZZ__; +typedef B A_AZZZ_; +typedef B A_AZZZZ; + +void a_A____ (A_A____) { } +// { dg-final { scan-assembler "_Z7a_A____1BIXtl2A1tlA5_cLc65EEEEE" } } + +void a_AZ___ (A_AZ___) { } +// { dg-final { scan-assembler "_Z7a_AZ___1BIXtl2A1tlA5_cLc65EEEEE" } } + +void a_AZZ__ (A_AZZ__) { } +// { dg-final { scan-assembler "_Z7a_AZZ__1BIXtl2A1tlA5_cLc65EEEEE" } } + +void a_AZZZ_ (A_AZZZ_) { } +// { dg-final { scan-assembler "_Z7a_AZZZ_1BIXtl2A1tlA5_cLc65EEEEE" } } + +void a_AZZZZ (A_AZZZZ) { } +// { dg-final { scan-assembler "_Z7a_AZZZZ1BIXtl2A1tlA5_cLc65EEEEE" } } + + +typedef B S_Az___; +typedef B S_AZz__; +typedef B S_AZZz_; +typedef B S_AZZZz; + +void s_Az___ (S_Az___) { } +// { dg-final { scan-assembler "_Z7s_Az___1BIXtl2A1tlA5_cLc65EEEEE" } } + +void s_AZz__ (S_AZz__) { } +// { dg-final { scan-assembler "_Z7s_AZz__1BIXtl2A1tlA5_cLc65EEEEE" } } + +void s_AZZz_ (S_AZZz_) { } +// { dg-final { scan-assembler "_Z7s_AZZz_1BIXtl2A1tlA5_cLc65EEEEE" } } + +void s_AZZZz (S_AZZZz) { } +// { dg-final { scan-assembler "_Z7s_AZZZz1BIXtl2A1tlA5_cLc65EEEEE" } } + + +typedef B A_AZZDZ; +typedef B A_AZZD_; + +void a_AZZDZ (A_AZZDZ) { } +// { dg-final { scan-assembler "_Z7a_AZZD_1BIXtl2A1tlA5_cLc65ELc0ELc0ELc68EEEEE" } } + +void a_AZZD_ (A_AZZD_) { } +// { dg-final { scan-assembler "_Z7a_AZZDZ1BIXtl2A1tlA5_cLc65ELc0ELc0ELc68EEEEE" } } + + +typedef B S_ABZD_; +typedef B S_ABZZ_; +typedef B S_ABZ__; +typedef B S_AB___; + +void s_abzd_ (S_ABZD_) { } +// { dg-final { scan-assembler "_Z7s_abzd_1BIXtl2A1tlA5_cLc65ELc66ELc0ELc68EEEEE" } } + +void s_abzz_ (S_ABZZ_) { } +// { dg-final { scan-assembler "_Z7s_abzz_1BIXtl2A1tlA5_cLc65ELc66EEEEE" } } + +void s_abz__ (S_ABZ__) { } +// { dg-final { scan-assembler "_Z7s_abz__1BIXtl2A1tlA5_cLc65ELc66EEEEE" } } + +void s_ab___ (S_AB___) { } +// { dg-final { scan-assembler "_Z7s_ab___1BIXtl2A1tlA5_cLc65ELc66EEEEE" } } + + +struct A3 { char a[5], b[5], c[5]; }; +template struct B3 { }; + +/* These all name the same type. */ +typedef B3 T_123z_______3456z; +typedef B3 T_123z__Z____3456z; +typedef B3 T_123z__ZZ___3456z; +typedef B3 T_123z__ZZZ__3456z; +typedef B3 T_123z__ZZZZ_3456z; +typedef B3 T_123z__Z____3456z; +typedef B3 T_123z__ZZ___3456z; +typedef B3 T_123z__ZZZ__3456z; +typedef B3 T_123z__ZZZZ_3456z; +typedef B3 T_123z__ZZZZZ3456z; +typedef B3 T_123Zz_ZZZZZ3456z; +typedef B3 T_123ZZzZZZZZ3456z; + + +void ft0 (T_123z_______3456z) { } +// { dg-final { scan-assembler "_Z3ft02B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } + +void ft1 (T_123z__Z____3456z) { } +// { dg-final { scan-assembler "_Z3ft12B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void ft2 (T_123z__ZZ___3456z) { } +// { dg-final { scan-assembler "_Z3ft22B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void ft3 (T_123z__ZZZ__3456z) { } +// { dg-final { scan-assembler "_Z3ft32B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void ft4 (T_123z__ZZZZ_3456z) { } +// { dg-final { scan-assembler "_Z3ft42B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void ft9 (T_123z__ZZZZZ3456z) { } +// { dg-final { scan-assembler "_Z3ft92B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void fta (T_123Zz_ZZZZZ3456z) { } +// { dg-final { scan-assembler "_Z3fta2B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } +void ftb (T_123ZZzZZZZZ3456z) { } +// { dg-final { scan-assembler "_Z3ftb2B3IXtl2A3tlA5_cLc1ELc2EEtlS1_EtlS1_Lc3ELc4ELc5ELc6EEEEE" } } Index: gcc/testsuite/g++.dg/abi/mangle70.C =================================================================== --- gcc/testsuite/g++.dg/abi/mangle70.C (nonexistent) +++ gcc/testsuite/g++.dg/abi/mangle70.C (working copy) @@ -0,0 +1,29 @@ +// Verify that class literals are mangled the same way regardless +// of the underlying type. +// { dg-do compile { target c++2a } } + +struct I { int a[5], b[5], c[5]; }; +template struct X { }; + +typedef X Ti; +void f (Ti) { } +// { dg-final { scan-assembler "_Z1f1XIXtl1ItlA5_iLi1ELi2EEtlS1_EtlS1_Li11ELi12ELi13ELi14EEEEE" } } + +struct C { char a[5], b[5], c[5]; }; +template struct Y { }; + +typedef Y Tca; +void g (Tca) { } +// { dg-final { scan-assembler "_Z1g1YIXtl1CtlA5_cLc1ELc2EEtlS1_EtlS1_Lc11ELc12ELc13ELc14EEEEE" } } + +typedef Y Tcs; +void h (Tcs) { } +// { dg-final { scan-assembler "_Z1h1YIXtl1CtlA5_cLc1ELc2EEtlS1_EtlS1_Lc11ELc12ELc13ELc14EEEEE" } } + +struct S { signed char a[5], b[5], c[5]; }; +template struct Z { }; + +typedef Z Tsc; + +void i (Tsc) { } +// { dg-final { scan-assembler "_Z1i1ZIXtl1StlA5_aLa1ELa2EEtlS1_EtlS1_La11ELa12ELa13ELa14EEEEE" } } Index: gcc/testsuite/g++.dg/abi/mangle71.C =================================================================== --- gcc/testsuite/g++.dg/abi/mangle71.C (nonexistent) +++ gcc/testsuite/g++.dg/abi/mangle71.C (working copy) @@ -0,0 +1,28 @@ +// Verify manglinng of class literals of types with ctors. +// { dg-do compile { target c++2a } } + +struct A +{ + char i; + constexpr A (): i (1) { } + constexpr A (int i): i (i) { } +}; + +struct B { A a[3]; }; + +template struct X { }; + +void f___ (X) { } +// { dg-final { scan-assembler "_Z4f___1XIXtl1BtlA3_1AtlS1_Lc1EEEEEE" } } + +void f0__ (X) { } +// { dg-final { scan-assembler "_Z4f0__1XIXtl1BtlA3_1AtlS1_Lc0EEtlS1_Lc1EEEEEE" } } + +void f00_ (X) { } +// { dg-final { scan-assembler "_Z4f00_1XIXtl1BtlA3_1AtlS1_Lc0EEtlS1_Lc0EEtlS1_Lc1EEEEEE" } } + +void f000 (X) { } +// { dg-final { scan-assembler "_Z4f0001XIXtl1BtlA3_1AtlS1_Lc0EEtlS1_Lc0EEtlS1_Lc0EEEEEE" } } + +void f1__ (X) { } +// { dg-final { scan-assembler "_Z4f1__1XIXtl1BtlA3_1AtlS1_Lc1EEtlS1_Lc1EEEEEE" } }