From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 123833 invoked by alias); 16 Jun 2015 08:55:48 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 123818 invoked by uid 89); 16 Jun 2015 08:55:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL,BAYES_50,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 16 Jun 2015 08:55:37 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 69C3F2853E46 for ; Tue, 16 Jun 2015 10:55:34 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gfOqH7b8KATc for ; Tue, 16 Jun 2015 10:55:34 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 36D542853E3F for ; Tue, 16 Jun 2015 10:55:34 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch 2/6] scalar-storage-order merge: C front-end Date: Tue, 16 Jun 2015 08:56:00 -0000 Message-ID: <2396877.AqT21tpnmO@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) In-Reply-To: <3247494.5bgQPARZRk@polaris> References: <3247494.5bgQPARZRk@polaris> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart4271326.CkR9z7xzpG" Content-Transfer-Encoding: 7Bit X-SW-Source: 2015-06/txt/msg01077.txt.bz2 --nextPart4271326.CkR9z7xzpG Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Content-length: 1092 This is the C front-end + C family part. * doc/extend.texi (type attributes): Document scalar_storage_order. * doc/invoke.texi (Warnings): Document -Wno-scalar-storage-order. c-family/ * c-common.c (c_common_attributes): Add scalar_storage_order. (handle_scalar_storage_order_attribute): New function. * c.opt (Wscalar-storage-order): New warning. c/ * c-decl.c (finish_struct): If the structure has reverse scalar storage order, rewrite the type of array fields with scalar component. * c-typeck.c (build_unary_op) : Remove left-overs. Issue errors on bit-fields and reverse SSO here and not... (c_mark_addressable): ...here. doc/extend.texi | 47 +++++++++++++++++++++++++++++++++++++++++++++ doc/invoke.texi | 6 +++++ c-family/c.opt | 4 +++ c-family/c-common.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++- c/c-typeck.c | 53 +++++++++++++++++++++++++++++++------------------- c/c-decl.c | 45 +++++++++++++++++++++++++++++-------------- 6 files changed, 175 insertions(+), 34 deletions(-) -- Eric Botcazou --nextPart4271326.CkR9z7xzpG Content-Disposition: attachment; filename="sso-c.diff" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="sso-c.diff" Content-length: 12210 Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (.../trunk) (revision 224461) +++ gcc/doc/extend.texi (.../branches/scalar-storage-order) (revision 224467) @@ -6064,6 +6064,53 @@ S *p = (S *)malloc (sizeof(S) + 100); p->data[10] = 0; //OK @end smallexample +@item scalar_storage_order +@itemx scalar_storage_order ("@var{endianness}") +@cindex @code{scalar_storage_order} type attribute +When attached to a @code{union} or a @code{struct}, this attribute sets +the storage order, aka endianness, of the scalar fields of the type, as +well as the array fields whose component is scalar. The supported +endianness are @code{big-endian} and @code{little-endian}. The attribute +has no effects on fields which are themselves a @code{union}, a @code{struct} +or an array whose component is a @code{union} or a @code{struct}, and it is +possible to have fields with a different scalar storage order than the +enclosing type. + +This attribute is supported only for targets that use a uniform default +scalar storage order (fortunately, most of them), i.e. targets that store +the scalars either all in big-endian or all in little-endian. + +Additional restrictions are enforced for types with the reverse scalar +storage order with regard to the scalar storage order of the target: + +@itemize +@item Taking the address of a scalar field of a @code{union} or a +@code{struct} with reverse scalar storage order is illegal and will +yield an error +@item Taking the address of an array field, whose component is scalar, of +a @code{union} or a @code{struct} with reverse scalar storage order is +permitted but will yield a warning, unless @option{-Wno-scalar-storage-order} +is specified +@item Taking the address of a @code{union} or a @code{struct} with reverse +scalar storage order is permitted +@end itemize + +These restrictions exist because the storage order attribute is lost when +the address of a scalar or the address of an array with scalar component +is taken, so storing indirectly through this address will generally not work. +The second case is nevertheless allowed to be able to perform a block copy +from or to the array. + +@item unused +@cindex @code{unused} type attribute +When attached to a type (including a @code{union} or a @code{struct}), +this attribute means that variables of that type are meant to appear +possibly unused. GCC does not produce a warning for any variables of +that type, even if the variable appears to do nothing. This is often +the case with lock or thread classes, which are usually defined and then +not referenced, but contain constructors and destructors that have +nontrivial bookkeeping functions. + @item deprecated @itemx deprecated (@var{msg}) @cindex @code{deprecated} type attribute Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (.../trunk) (revision 224461) +++ gcc/doc/invoke.texi (.../branches/scalar-storage-order) (revision 224467) @@ -275,6 +275,7 @@ Objective-C and Objective-C++ Dialects}. -Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol -Wsign-compare -Wsign-conversion -Wfloat-conversion @gol +-Wno-scalar-storage-order @gol -Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol -Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol @@ -4938,6 +4939,11 @@ This includes conversions from real to i real to lower precision real values. This option is also enabled by @option{-Wconversion}. +@item -Wno-scalar-storage-order +@opindex -Wno-scalar-storage-order +@opindex -Wscalar-storage-order +Do not warn on suspicious constructs involving reverse scalar storage order. + @item -Wsized-deallocation @r{(C++ and Objective-C++ only)} @opindex Wsized-deallocation @opindex Wno-sized-deallocation Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (.../trunk) (revision 224461) +++ gcc/c-family/c.opt (.../branches/scalar-storage-order) (revision 224467) @@ -768,6 +768,10 @@ Wreturn-type C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++) +Wscalar-storage-order +C ObjC C++ ObjC++ Init(1) Warning +Warn on suspicious constructs involving reverse scalar storage order + Wselector ObjC ObjC++ Var(warn_selector) Warning Warn if a selector has multiple methods Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (.../trunk) (revision 224461) +++ gcc/c-family/c-common.c (.../branches/scalar-storage-order) (revision 224467) @@ -346,6 +346,8 @@ static tree handle_no_reorder_attribute static tree handle_const_attribute (tree *, tree, tree, int, bool *); static tree handle_transparent_union_attribute (tree *, tree, tree, int, bool *); +static tree handle_scalar_storage_order_attribute (tree *, tree, tree, + int, bool *); static tree handle_constructor_attribute (tree *, tree, tree, int, bool *); static tree handle_destructor_attribute (tree *, tree, tree, int, bool *); static tree handle_mode_attribute (tree *, tree, tree, int, bool *); @@ -690,6 +692,8 @@ const struct attribute_spec c_common_att handle_const_attribute, false }, { "transparent_union", 0, 0, false, false, false, handle_transparent_union_attribute, false }, + { "scalar_storage_order", 1, 1, false, false, false, + handle_scalar_storage_order_attribute, false }, { "constructor", 0, 1, true, false, false, handle_constructor_attribute, false }, { "destructor", 0, 1, true, false, false, @@ -7502,7 +7506,6 @@ handle_transparent_union_attribute (tree *no_add_attrs = true; - if (TREE_CODE (*node) == TYPE_DECL && ! (flags & ATTR_FLAG_CXX11)) node = &TREE_TYPE (*node); @@ -7542,6 +7545,55 @@ handle_transparent_union_attribute (tree return NULL_TREE; } + ignored: + warning (OPT_Wattributes, "%qE attribute ignored", name); + return NULL_TREE; +} + +/* Handle a "scalar_storage_order" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_scalar_storage_order_attribute (tree *node, tree name, tree args, + int flags, bool *no_add_attrs) +{ + tree id = TREE_VALUE (args); + tree type; + + *no_add_attrs = true; + + if (TREE_CODE (*node) == TYPE_DECL + && ! (flags & ATTR_FLAG_CXX11)) + node = &TREE_TYPE (*node); + type = *node; + + if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) + error ("scalar_storage_order is not supported"); + + if (RECORD_OR_UNION_TYPE_P (type)) + { + if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + goto ignored; + + if (TREE_CODE (id) == STRING_CST + && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0) + { + if (!BYTES_BIG_ENDIAN) + TYPE_REVERSE_STORAGE_ORDER (type) = 1; + } + else if (TREE_CODE (id) == STRING_CST + && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0) + { + if (BYTES_BIG_ENDIAN) + TYPE_REVERSE_STORAGE_ORDER (type) = 1; + } + else + error ("scalar_storage_order argument must be one of \"big-endian\" " + "or \"little-endian\""); + + return NULL_TREE; + } + ignored: warning (OPT_Wattributes, "%qE attribute ignored", name); return NULL_TREE; Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (.../trunk) (revision 224461) +++ gcc/c/c-typeck.c (.../branches/scalar-storage-order) (revision 224467) @@ -4163,18 +4163,10 @@ build_unary_op (location_t location, goto return_build_unary_op; } - /* For &x[y], return x+y */ - if (TREE_CODE (arg) == ARRAY_REF) - { - tree op0 = TREE_OPERAND (arg, 0); - if (!c_mark_addressable (op0)) - return error_mark_node; - } - /* Anything not already handled and not a true memory reference or a non-lvalue array is an error. */ - else if (typecode != FUNCTION_TYPE && !flag - && !lvalue_or_else (location, arg, lv_addressof)) + if (typecode != FUNCTION_TYPE && !flag + && !lvalue_or_else (location, arg, lv_addressof)) return error_mark_node; /* Move address operations inside C_MAYBE_CONST_EXPR to simplify @@ -4212,6 +4204,38 @@ build_unary_op (location_t location, argtype = c_build_qualified_type (argtype, quals); } + switch (TREE_CODE (arg)) + { + case COMPONENT_REF: + if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1))) + { + error ("cannot take address of bit-field %qD", + TREE_OPERAND (arg, 1)); + return error_mark_node; + } + + /* ... fall through ... */ + + case ARRAY_REF: + if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0)))) + { + if (!AGGREGATE_TYPE_P (TREE_TYPE (arg))) + { + error ("cannot take address of scalar with reverse storage " + "order"); + return error_mark_node; + } + + if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE + && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (arg))) + warning (OPT_Wscalar_storage_order, "address of array with " + "reverse scalar storage order requested"); + } + + default: + break; + } + if (!c_mark_addressable (arg)) return error_mark_node; @@ -4354,15 +4378,6 @@ c_mark_addressable (tree exp) switch (TREE_CODE (x)) { case COMPONENT_REF: - if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) - { - error - ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); - return false; - } - - /* ... fall through ... */ - case ADDR_EXPR: case ARRAY_REF: case REALPART_EXPR: Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c (.../trunk) (revision 224461) +++ gcc/c/c-decl.c (.../branches/scalar-storage-order) (revision 224467) @@ -7732,27 +7732,44 @@ finish_struct (location_t loc, tree t, t && !valid_constant_size_p (TYPE_SIZE_UNIT (t))) error ("type %qT is too large", t); - /* Give bit-fields their proper types. */ - { - tree *fieldlistp = &fieldlist; - while (*fieldlistp) - if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp) - && TREE_TYPE (*fieldlistp) != error_mark_node) + /* Give bit-fields their proper types and rewrite the type of array fields + if the enclosing type has reverse storage order. */ + for (tree field = fieldlist; field; field = DECL_CHAIN (field)) + { + if (TREE_CODE (field) == FIELD_DECL + && DECL_INITIAL (field) + && TREE_TYPE (field) != error_mark_node) { unsigned HOST_WIDE_INT width - = tree_to_uhwi (DECL_INITIAL (*fieldlistp)); - tree type = TREE_TYPE (*fieldlistp); + = tree_to_uhwi (DECL_INITIAL (field)); + tree type = TREE_TYPE (field); if (width != TYPE_PRECISION (type)) { - TREE_TYPE (*fieldlistp) + TREE_TYPE (field) = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type)); - DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp)); + DECL_MODE (field) = TYPE_MODE (TREE_TYPE (field)); } - DECL_INITIAL (*fieldlistp) = 0; + DECL_INITIAL (field) = 0; } - else - fieldlistp = &DECL_CHAIN (*fieldlistp); - } + else if (TYPE_REVERSE_STORAGE_ORDER (t) + && TREE_CODE (field) == FIELD_DECL + && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE) + { + tree ftype = TREE_TYPE (field); + do + ftype = TREE_TYPE (ftype); + while (TREE_CODE (ftype) == ARRAY_TYPE); + if (!RECORD_OR_UNION_TYPE_P (ftype)) + { + tree *ftypep = &TREE_TYPE (field); + do { + *ftypep = build_distinct_type_copy (*ftypep); + TYPE_REVERSE_STORAGE_ORDER (*ftypep) = 1; + ftypep = &TREE_TYPE (*ftypep); + } while (TREE_CODE (*ftypep) == ARRAY_TYPE); + } + } + } /* Now we have the truly final field list. Store it in this type and in the variants. */ --nextPart4271326.CkR9z7xzpG--