From patchwork Tue Jun 2 02:26:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 479254 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 8D2611412E9 for ; Tue, 2 Jun 2015 12:26:36 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=t6vXHcEh; 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 :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=SX51dfwf4Wq5neS7gRyeIc4/eNzRzAMKHmjZd6lG2d+Fy/ gZ7iuoeelWUmLSaztyJE9CCcrGxkdzzaiRP3PULkIY7P97Zj2prT1kpLIHKxSgTY yLDQCUZcpTMywbeK6AuUzcrTGfpoMPtcNv91igguXKUY95CIoWXgIbyLAv5Bs= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=qO4GhbBpOljyYKsYUHdDrzT/+tk=; b=t6vXHcEhPe2XpXId7X9z Pwi3eq0PE6jpx10fCu8aLIrifV53FOGdM734mA+FatCGj62LVAZH3VT1dpp9p0l2 yDdnHNlV22yaSpFjs3wCi7wjniW6IFVsip2vKJA7eatwjo8DR8VoLCNFPJjchFDW Tp4EqX0J9PTPI6fQUGJTrN8= Received: (qmail 29594 invoked by alias); 2 Jun 2015 02:26:27 -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 29585 invoked by uid 89); 2 Jun 2015 02:26:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_20, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 02 Jun 2015 02:26:25 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 3BA18CC7E4 for ; Tue, 2 Jun 2015 02:26:24 +0000 (UTC) Received: from [10.10.116.39] ([10.10.116.39]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t522QNIP004098 for ; Mon, 1 Jun 2015 22:26:23 -0400 Message-ID: <556D144D.6010404@redhat.com> Date: Mon, 01 Jun 2015 22:26:21 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling) A recent change broke bootstrap on ia32 because code intended to strip non-type-identity attributes from template arguments was also stripping type-identity attributes such as the ia32 calling convention attributes. When I fixed that it reminded me of this bug: we weren't mangling the function pointer type differently based on the calling convention. This patch fixes that. Tested x86_64-pc-linux-gnu, applying to trunk. commit 0707fcaee20275a8955ab5741df70831c8e9e350 Author: Jason Merrill Date: Sat Apr 25 07:45:02 2015 -0400 PR c++/44282 gcc/cp/ * mangle.c (attr_strcmp): New. (write_CV_qualifiers_for_type): Also write out attributes that affect type identity. (write_type): Strip all attributes after writing qualifiers. libiberty/ * cp-demangle.c (cplus_demangle_type): Handle arguments to vendor extended qualifier. diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index e9eb511..748306b 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename) /* Change flag_abi_version to be the actual current ABI level for the benefit of c_cpp_builtins. */ if (flag_abi_version == 0) - flag_abi_version = 8; + flag_abi_version = 9; /* Set C++ standard to C++98 if not specified on the command line. */ if (c_dialect_cxx () && cxx_dialect == cxx_unset) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 647ec70..8151179 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-ref.h" #include "cgraph.h" #include "wide-int.h" +#include "attribs.h" /* Debugging support. */ @@ -1916,11 +1917,15 @@ write_type (tree type) candidates. */ { tree t = TYPE_MAIN_VARIANT (type); + if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t)) + t = cp_build_type_attribute_variant (t, NULL_TREE); + gcc_assert (t != type); if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) { t = build_ref_qualified_type (t, type_memfn_rqual (type)); - if (abi_version_at_least (8)) + if (abi_version_at_least (8) + || type == TYPE_MAIN_VARIANT (type)) /* Avoid adding the unqualified function type as a substitution. */ write_function_type (t); else @@ -2168,6 +2173,20 @@ write_type (tree type) add_substitution (type); } +/* qsort callback for sorting a vector of attribute entries. */ + +static int +attr_strcmp (const void *p1, const void *p2) +{ + tree a1 = *(const tree*)p1; + tree a2 = *(const tree*)p2; + + const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1)); + const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2)); + + return strcmp (as1->name, as2->name); +} + /* Non-terminal for type nodes. Returns the number of CV-qualifiers written for TYPE. @@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type) "In cases where multiple order-insensitive qualifiers are present, they should be ordered 'K' (closest to the base type), - 'V', 'r', and 'U' (farthest from the base type) ..." + 'V', 'r', and 'U' (farthest from the base type) ..." */ - Note that we do not use cp_type_quals below; given "const + /* Mangle attributes that affect type identity as extended qualifiers. + + We mangle them onto the obstack, then copy the result into a string + vector and back up the obstack. Once we've handled all of them we + sort them and write them out in order. + + We don't do this with classes and enums because their attributes + are part of their definitions, not something added on. */ + + if (abi_version_at_least (9) && !OVERLOAD_TYPE_P (type)) + { + auto_vec vec; + for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a)) + { + tree name = get_attribute_name (a); + const attribute_spec *as = lookup_attribute_spec (name); + if (as && as->affects_type_identity + && !is_attribute_p ("abi_tag", name)) + vec.safe_push (a); + } + vec.qsort (attr_strcmp); + while (!vec.is_empty()) + { + tree a = vec.pop(); + const attribute_spec *as + = lookup_attribute_spec (get_attribute_name (a)); + + write_char ('U'); + write_unsigned_number (strlen (as->name)); + write_string (as->name); + if (TREE_VALUE (a)) + { + write_char ('I'); + for (tree args = TREE_VALUE (a); args; + args = TREE_CHAIN (args)) + { + tree arg = TREE_VALUE (args); + write_template_arg (arg); + } + write_char ('E'); + } + + ++num_qualifiers; + } + } + + /* Note that we do not use cp_type_quals below; given "const int[3]", the "const" is emitted with the "int", not with the array. */ cp_cv_quals quals = TYPE_QUALS (type); diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm.C b/gcc/testsuite/g++.dg/abi/mangle-regparm.C new file mode 100644 index 0000000..7d4121b --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C @@ -0,0 +1,29 @@ +// { dg-do run { target i?86-*-* } } +// { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } } + +typedef __SIZE_TYPE__ size_t; + +template +void IndirectExternCall(F f, T t1, T t2) { + typedef F (*WrapF)(F); + f (t1, t2); +} + +__attribute__((regparm(3), stdcall)) +void regparm_func (int i, int j) +{ + if (i != 24 || j != 42) + __builtin_abort(); +} + +void normal_func (int i, int j) +{ + if (i != 24 || j != 42) + __builtin_abort(); +} + +int main() +{ + IndirectExternCall (regparm_func, 24, 42); + IndirectExternCall (normal_func, 24, 42); +} diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 77c2cee..2988b6b 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di) case 'U': d_advance (di, 1); ret = d_source_name (di); + if (d_peek_char (di) == 'I') + ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, + d_template_args (di)); ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, cplus_demangle_type (di), ret); break; diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index a030685..6ea64ae 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z --format=gnu-v3 _Z1fSsB3fooS_ f(std::string[abi:foo], std::string[abi:foo]) +--format=gnu-v3 +_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_ +void IndirectExternCall stdcall*)(int, int), int>(void ( regparm<3> stdcall*)(int, int), int, void ( regparm<3> stdcall*)(int, int))