From patchwork Wed Apr 5 09:46:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 747189 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 3vygw20wNQz9s7g for ; Wed, 5 Apr 2017 19:46:24 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="p41kZvKp"; 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:from :to:subject:date:message-id:content-type:mime-version; q=dns; s= default; b=NqLNylxBXIUtVUDXdA89Zr6mlbNlW8+87xHKTYNx2O8dGCt9GkhXI Ss5kKx6N+hoKRTdoCmzZhQ+UeQsNIK8EXmMc/rdPqPFuTFW1HlyJ5ODHY7Y71lMm uWe3ApvhByfcCqWJ+zfBhZL18bxB+Uiwt906brMswofmEMqrlMJDf8= 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:content-type:mime-version; s= default; bh=x1BNO/srhxCme4vQSq95jET7Ud4=; b=p41kZvKpmUoqnqQZ7rbh roLnPoMhbnRVGxhNjcnTwrOclVLGy9dUy+ETxBwgXFlpa0edKGH+sGDUq9RUebNv I0/mhwmg5tRd4KQB1IfLkFmQJNQ1aO+/b3y7oz5Slb3G4pxR+jK/IM3+z8VYPut+ llrCXud1TmbBkKkwEIzJO3w= Received: (qmail 42665 invoked by alias); 5 Apr 2017 09:46:15 -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 42646 invoked by uid 89); 5 Apr 2017 09:46:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_MANYTO, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: EUR03-AM5-obe.outbound.protection.outlook.com Received: from mail-oln040092070072.outbound.protection.outlook.com (HELO EUR03-AM5-obe.outbound.protection.outlook.com) (40.92.70.72) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 05 Apr 2017 09:46:10 +0000 Received: from AM5EUR03FT041.eop-EUR03.prod.protection.outlook.com (10.152.16.59) by AM5EUR03HT158.eop-EUR03.prod.protection.outlook.com (10.152.16.244) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.1005.5; Wed, 5 Apr 2017 09:46:09 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com (10.152.16.60) by AM5EUR03FT041.mail.protection.outlook.com (10.152.17.186) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1005.5 via Frontend Transport; Wed, 5 Apr 2017 09:46:09 +0000 Received: from AM4PR0701MB2162.eurprd07.prod.outlook.com ([fe80::a806:64f0:6377:f3ea]) by AM4PR0701MB2162.eurprd07.prod.outlook.com ([fe80::a806:64f0:6377:f3ea%19]) with mapi id 15.01.1019.015; Wed, 5 Apr 2017 09:46:09 +0000 From: Bernd Edlinger To: GCC Patches , Jason Merrill , "Marc Glisse ; Jakub Jelinek ; Jonathan Wakely" , Richard Biener , Jakub Jelinek , Jeff Law Subject: [PATCH] Add a new type attribute always_alias (PR79671) Date: Wed, 5 Apr 2017 09:46:09 +0000 Message-ID: authentication-results: gcc.gnu.org; dkim=none (message not signed) header.d=none; gcc.gnu.org; dmarc=none action=none header.from=hotmail.de; x-incomingtopheadermarker: OriginalChecksum:A5D082A46834B07F41D92A65456BA3EFDB24854D62AAD169A13B729DF3C4BB56; UpperCasedChecksum:13F2A94134A78364E078403522DB8951C5D9EA564E626D6A6B96E49CBB2D4C92; SizeAsReceived:8195; Count:40 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [HF8ltITJ1LJkQb0XKrLAFwLViq7keLh0] x-microsoft-exchange-diagnostics: 1; AM5EUR03HT158; 5:TEoie+0Q4lCqZ3rDGGFQu2TBU0OKuZYLwvB9PvPmMtdichi9d+T/lTKyqgUrL8zxpQNavxVSADAEb8B+jhScak6Nsck7cRa9A27GwFbhUHmHBqz9nHVtwTWRlztrcWylmArhynhitHoks8iyDovw6Q==; 24:PMnDTUz0aPcsuOQJAuF1V0zOg/80OsTj7WWQCL0NpagRAGHMYbMooMO11UEDT0HmSL3fH8L3RRk95ltWMxb/trWdfQxrJkCb7QXHph5Mj0Y=; 7:LAn81rpcLKuBVOMOoCjBLG2u7lJYAt8CKrMRUay3cUnOsO7kmaHB8eQGU5P7JaQ/jUY4axVylau5qz5ETFN0XocUgYta/hdHHNDYU+d6ArGULLNgljQdhU0lJrCeCy8kyxMDGjzQOi3WPD86OqTgQQe0iZkco/8zpp/4fcyuPzchjogF0emB/SIZXSOhs8b12x+iFgVetF+ekY+07kJ6ezDFKc1ZZxfcz6L5iSfp/tTJExR1AJwhRsYWaqzfI9fbmdunA7wlONOHo+BkOFcJAwfSPZVxvxPYp49SMJCNkq6dRRIpQ2pCfqqkBLn77IGH x-incomingheadercount: 40 x-eopattributedmessage: 0 x-forefront-antispam-report: EFV:NLI; SFV:NSPM; SFS:(7070007)(98901004); DIR:OUT; SFP:1901; SCL:1; SRVR:AM5EUR03HT158; H:AM4PR0701MB2162.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; x-ms-office365-filtering-correlation-id: e7d141f3-d28d-4e24-aaf5-08d47c089693 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201702061074)(5061506573)(5061507331)(1603103135)(2017031320274)(2017031322274)(1603101448)(1601125374)(1701031045); SRVR:AM5EUR03HT158; x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(444000031); SRVR:AM5EUR03HT158; BCL:0; PCL:0; RULEID:; SRVR:AM5EUR03HT158; x-forefront-prvs: 0268246AE7 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Apr 2017 09:46:09.3064 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5EUR03HT158 Hi, this is related to the P1 codegen bug PR79671: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671 Therefore I would like to add this now although the trunk is already at in stage 4. I propose to add a new type attribute always_alias that works like may_alias but unlike may_alias it should also make instances alias anything. It is also exposed in C/C++ as __attribute__((always_alias)). For C++17 the FE automatically introduces this attribute at std::byte and all class/struct/union which contain either a std::byte array or an unsigned char array. Note that the patch [1] needs to be applied as well, because otherwise the new attribute will trip several failures in the libstdc++ testsuite. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd. [1] https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00189.html gcc 2017-04-05 Bernd Edlinger * doc/extend.texi: Document the always_alias type attribute. * alias.c (get_alias_set): Honor the always_alias attribute. (record_component_aliases): Don't ignore the always_alias attribute. * tree.c (build_pointer_type_for_mode, build_reference_type_for_mode): Add the always_alias attribute. gcc/c-family 2017-04-05 Bernd Edlinger * c-attribs.c (c_common_attribute_tab): Add the always_alias attribute. gcc/cp 2017-04-05 Bernd Edlinger * class.c (fixup_attribute_variants): Add the always_alias attribute. (finish_struct_1): Add an always_alias attribute if required by C++17. * decl.c (start_enum): Likewise. * pt.c (lookup_template_class_1): Add the always_alias attribute. * typeck2.c (cxx_type_contains_byte_buffer): New function. * cp-tree.h (cxx_type_contains_byte_buffer): Declare. Index: gcc/alias.c =================================================================== --- gcc/alias.c (revision 246678) +++ gcc/alias.c (working copy) @@ -879,6 +879,10 @@ get_alias_set (tree t) t = TREE_TYPE (t); } + /* Honor the always_alias type attribute. */ + if (lookup_attribute ("always_alias", TYPE_ATTRIBUTES (t))) + return 0; + /* Variant qualifiers don't affect the alias set, so get the main variant. */ t = TYPE_MAIN_VARIANT (t); @@ -1234,7 +1238,9 @@ record_component_aliases (tree type) /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their element type and that type has to be normalized to void *, too, in the case it is a pointer. */ - while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t)) + while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t) + && !lookup_attribute ("always_alias", + TYPE_ATTRIBUTES (t))) { gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t)); t = TREE_TYPE (t); Index: gcc/c-family/c-attribs.c =================================================================== --- gcc/c-family/c-attribs.c (revision 246678) +++ gcc/c-family/c-attribs.c (working copy) @@ -265,6 +265,7 @@ const struct attribute_spec c_common_attribute_tab { "nothrow", 0, 0, true, false, false, handle_nothrow_attribute, false }, { "may_alias", 0, 0, false, true, false, NULL, false }, + { "always_alias", 0, 0, false, true, false, NULL, false }, { "cleanup", 1, 1, true, false, false, handle_cleanup_attribute, false }, { "warn_unused_result", 0, 0, false, true, true, Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 246678) +++ gcc/cp/class.c (working copy) @@ -2083,7 +2082,8 @@ fixup_attribute_variants (tree t) tree attrs = TYPE_ATTRIBUTES (t); unsigned align = TYPE_ALIGN (t); bool user_align = TYPE_USER_ALIGN (t); - bool may_alias = lookup_attribute ("may_alias", attrs); + bool may_alias = lookup_attribute ("may_alias", attrs) + || lookup_attribute ("always_alias", attrs); if (may_alias) fixup_may_alias (t); @@ -7345,6 +7346,15 @@ finish_struct_1 (tree t) the class or perform any other required target modifications. */ targetm.cxx.adjust_class_at_definition (t); + if (cxx_dialect >= cxx1z && cxx_type_contains_byte_buffer (t) + && !lookup_attribute ("always_alias", TYPE_ATTRIBUTES (t))) + { + TYPE_ATTRIBUTES (t) + = tree_cons (get_identifier ("always_alias"), + NULL_TREE, TYPE_ATTRIBUTES (t)); + fixup_attribute_variants (t); + } + maybe_suppress_debug_info (t); if (flag_vtable_verify) Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 246678) +++ gcc/cp/cp-tree.h (working copy) @@ -6858,6 +6858,7 @@ extern tree finish_binary_fold_expr (tree extern void require_complete_eh_spec_types (tree, tree); extern void cxx_incomplete_type_diagnostic (location_t, const_tree, const_tree, diagnostic_t); +extern bool cxx_type_contains_byte_buffer (tree); inline void cxx_incomplete_type_diagnostic (const_tree value, const_tree type, diagnostic_t diag_kind) Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 246678) +++ gcc/cp/decl.c (working copy) @@ -14081,10 +14081,15 @@ start_enum (tree name, tree enumtype, tree underly enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current); /* std::byte aliases anything. */ - if (enumtype != error_mark_node + if (cxx_dialect >= cxx1z + && enumtype != error_mark_node && TYPE_CONTEXT (enumtype) == std_node - && !strcmp ("byte", TYPE_NAME_STRING (enumtype))) - TYPE_ALIAS_SET (enumtype) = 0; + && !strcmp ("byte", TYPE_NAME_STRING (enumtype)) + && !lookup_attribute ("always_alias", + TYPE_ATTRIBUTES (enumtype))) + TYPE_ATTRIBUTES (enumtype) + = tree_cons (get_identifier ("always_alias"), + NULL_TREE, TYPE_ATTRIBUTES (enumtype)); } else enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 246678) +++ gcc/cp/pt.c (working copy) @@ -8851,9 +8851,9 @@ lookup_template_class_1 (tree d1, tree arglist, tr if (OVERLOAD_TYPE_P (t) && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)) { - static const char *tags[] = {"abi_tag", "may_alias"}; + static const char *tags[] = {"abi_tag", "may_alias", "always_alias"}; - for (unsigned ix = 0; ix != 2; ix++) + for (unsigned ix = 0; ix < sizeof (tags) / sizeof (tags[0]); ix++) { tree attributes = lookup_attribute (tags[ix], TYPE_ATTRIBUTES (template_type)); Index: gcc/cp/typeck2.c =================================================================== --- gcc/cp/typeck2.c (revision 246678) +++ gcc/cp/typeck2.c (working copy) @@ -2234,5 +2234,29 @@ require_complete_eh_spec_types (tree fntype, tree } } +/* True iff type either is or contains a byte buffer (which can be used for + storing any trivially copyable type). */ + +bool +cxx_type_contains_byte_buffer (tree type) +{ + if (TREE_CODE (type) == ARRAY_TYPE + && (cxx_type_contains_byte_buffer (TREE_TYPE (type)) + || TREE_TYPE (type) == unsigned_char_type_node + || (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE + && TYPE_CONTEXT (TREE_TYPE (type)) == std_node + && !strcmp ("byte", TYPE_NAME_STRING (TREE_TYPE (type)))))) + return true; + + if (CLASS_TYPE_P (type)) + for (tree field = next_initializable_field (TYPE_FIELDS (type)); + field; + field = next_initializable_field (DECL_CHAIN (field))) + if (cxx_type_contains_byte_buffer (TREE_TYPE (field))) + return true; + + return false; +} + #include "gt-cp-typeck2.h" Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 246678) +++ gcc/doc/extend.texi (working copy) @@ -6656,6 +6656,11 @@ declaration, the above program would abort when co @option{-fstrict-aliasing}, which is on by default at @option{-O2} or above. +@item always_alias +@cindex @code{always_alias} type attribute +Same as @code{may_alias}, but additionally applies to instances of +types with this attribute. + @item packed @cindex @code{packed} type attribute This attribute, attached to @code{struct} or @code{union} type Index: gcc/testsuite/c-c++-common/attr-always-alias-1.c =================================================================== --- gcc/testsuite/c-c++-common/attr-always-alias-1.c (revision 0) +++ gcc/testsuite/c-c++-common/attr-always-alias-1.c (working copy) @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +typedef int T __attribute__((always_alias)); + +extern T t, v; +extern T *p; +extern int *p; + +extern int *p2; +extern T *p2; + +void fn1 (T); +void fn1 (int); + +void fn2 (int); +void fn2 (T); + +/* Ensure that the composite types have always_alias. */ +void +f (long *i) +{ + *i = *(__typeof (*p) *) &p; + asm ("" : : "r" (*p)); + *i = *(__typeof (*p2) *) &p2; + asm ("" : : "r" (*p2)); + t = v; + asm ("" : : "r" (t)); +} Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 246678) +++ gcc/tree.c (working copy) @@ -8041,7 +8041,8 @@ build_pointer_type_for_mode (tree to_type, machine /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ - if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) + if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)) + || lookup_attribute ("always_alias", TYPE_ATTRIBUTES (to_type))) can_alias_all = true; /* In some cases, languages will have things that aren't a POINTER_TYPE @@ -8110,7 +8111,8 @@ build_reference_type_for_mode (tree to_type, machi /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ - if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) + if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)) + || lookup_attribute ("always_alias", TYPE_ATTRIBUTES (to_type))) can_alias_all = true; /* In some cases, languages will have things that aren't a REFERENCE_TYPE