From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19330 invoked by alias); 18 Jun 2011 11:03:35 -0000 Received: (qmail 19321 invoked by uid 22791); 18 Jun 2011 11:03:33 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 18 Jun 2011 11:03:18 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id F2471CB029A for ; Sat, 18 Jun 2011 13:03:16 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Q1JTi1HzEwis for ; Sat, 18 Jun 2011 13:03:14 +0200 (CEST) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id A7866CB01D8 for ; Sat, 18 Jun 2011 13:03:13 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Fix bugs with volatile and components of aggregate types Date: Sat, 18 Jun 2011 13:01:00 -0000 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_NQI/NGTmsIq+l8E" Message-Id: <201106181255.09679.ebotcazou@adacore.com> 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 X-SW-Source: 2011-06/txt/msg01387.txt.bz2 --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1286 This is the usual problem of volatile accesses not preserved under (heavy) optimization. In Ada, we can put pragma Volatile on components of composite types without putting it on the enclosing type itself, but this doesn't really work when you're starting to optimize. Mostly gigi changes, but this plugs a hole in type_internals_preclude_sra_p which already tests TREE_THIS_VOLATILE on fields of record and union types but doesn't perform the equivalent test for array types. Tested on i586-suse-linux, applied on mainline, as obvious for the SRA bits. 2011-06-18 Eric Botcazou * tree-sra.c (type_internals_preclude_sra_p) : Return true if the element type is volatile. ada/ * gcc-interface/decl.c (gnat_to_gnu_component_type): Use GNAT_TYPE local variable throughout. Remove useless call to Base_Type. (gnat_to_gnu_field): Use GNAT_FIELD_TYPE local variable throughout. Take it also into account for the volatileness of the field. Set the TREE_SIDE_EFFECTS flag as well in this case. Reorder some warnings. 2011-06-18 Eric Botcazou * gnat.dg/volatile6.adb: New test. * gnat.dg/volatile7.adb: Likewise. * gnat.dg/volatile8.adb: Likewise. * gnat.dg/volatile9.adb: Likewise. -- Eric Botcazou --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/x-diff; charset="iso 8859-15"; name="p.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="p.diff" Content-length: 6433 Index: ada/gcc-interface/decl.c =================================================================== --- ada/gcc-interface/decl.c (revision 175136) +++ ada/gcc-interface/decl.c (working copy) @@ -5229,7 +5229,8 @@ static tree gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, bool debug_info_p) { - tree gnu_type = gnat_to_gnu_type (Component_Type (gnat_array)); + const Entity_Id gnat_type = Component_Type (gnat_array); + tree gnu_type = gnat_to_gnu_type (gnat_type); tree gnu_comp_size; /* Try to get a smaller form of the component if needed. */ @@ -5237,7 +5238,7 @@ gnat_to_gnu_component_type (Entity_Id gn || Has_Component_Size_Clause (gnat_array)) && !Is_Bit_Packed_Array (gnat_array) && !Has_Aliased_Components (gnat_array) - && !Strict_Alignment (Component_Type (gnat_array)) + && !Strict_Alignment (gnat_type) && TREE_CODE (gnu_type) == RECORD_TYPE && !TYPE_FAT_POINTER_P (gnu_type) && host_integerp (TYPE_SIZE (gnu_type), 1)) @@ -5301,7 +5302,7 @@ gnat_to_gnu_component_type (Entity_Id gn debug_info_p, gnat_array); } - if (Has_Volatile_Components (Base_Type (gnat_array))) + if (Has_Volatile_Components (gnat_array)) gnu_type = build_qualified_type (gnu_type, TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE); @@ -6716,12 +6717,16 @@ static tree gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, bool definition, bool debug_info_p) { + const Entity_Id gnat_field_type = Etype (gnat_field); + tree gnu_field_type = gnat_to_gnu_type (gnat_field_type); tree gnu_field_id = get_entity_name (gnat_field); - tree gnu_field_type = gnat_to_gnu_type (Etype (gnat_field)); tree gnu_field, gnu_size, gnu_pos; + bool is_volatile + = (Treat_As_Volatile (gnat_field) || Treat_As_Volatile (gnat_field_type)); bool needs_strict_alignment - = (Is_Aliased (gnat_field) || Strict_Alignment (Etype (gnat_field)) - || Treat_As_Volatile (gnat_field)); + = (is_volatile + || Is_Aliased (gnat_field) + || Strict_Alignment (gnat_field_type)); /* If this field requires strict alignment, we cannot pack it because it would very likely be under-aligned in the record. */ @@ -6737,7 +6742,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, gnu_size = validate_size (Esize (gnat_field), gnu_field_type, gnat_field, FIELD_DECL, false, true); else if (packed == 1) - gnu_size = validate_size (RM_Size (Etype (gnat_field)), gnu_field_type, + gnu_size = validate_size (RM_Size (gnat_field_type), gnu_field_type, gnat_field, FIELD_DECL, false, true); else gnu_size = NULL_TREE; @@ -6829,7 +6834,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, if (gnu_size && !operand_equal_p (gnu_size, TYPE_SIZE (gnu_field_type), 0)) { - if (Is_Atomic (gnat_field) || Is_Atomic (Etype (gnat_field))) + if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type)) post_error_ne_tree ("atomic field& must be natural size of type{ (^)}", Last_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6841,7 +6846,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, Last_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_SIZE (gnu_field_type)); - else if (Strict_Alignment (Etype (gnat_field))) + else if (Strict_Alignment (gnat_field_type)) post_error_ne_tree ("size of & with aliased or tagged components not ^ bits", Last_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6854,19 +6859,19 @@ gnat_to_gnu_field (Entity_Id gnat_field, (TRUNC_MOD_EXPR, gnu_pos, bitsize_int (TYPE_ALIGN (gnu_field_type))))) { - if (Is_Aliased (gnat_field)) + if (is_volatile) post_error_ne_num - ("position of aliased field& must be multiple of ^ bits", + ("position of volatile field& must be multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_ALIGN (gnu_field_type)); - else if (Treat_As_Volatile (gnat_field)) + else if (Is_Aliased (gnat_field)) post_error_ne_num - ("position of volatile field& must be multiple of ^ bits", + ("position of aliased field& must be multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, TYPE_ALIGN (gnu_field_type)); - else if (Strict_Alignment (Etype (gnat_field))) + else if (Strict_Alignment (gnat_field_type)) post_error_ne_num ("position of & with aliased or tagged components not multiple of ^ bits", First_Bit (Component_Clause (gnat_field)), gnat_field, @@ -6901,7 +6906,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, if (TREE_CODE (gnu_field_type) == RECORD_TYPE && !gnu_size && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_field_type)) - && !Is_Constrained (Underlying_Type (Etype (gnat_field)))) + && !Is_Constrained (Underlying_Type (gnat_field_type))) { gnu_size = max_size (TYPE_SIZE (gnu_field_type), true); packed = 0; @@ -6953,7 +6958,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, = create_field_decl (gnu_field_id, gnu_field_type, gnu_record_type, gnu_size, gnu_pos, packed, Is_Aliased (gnat_field)); Sloc_to_locus (Sloc (gnat_field), &DECL_SOURCE_LOCATION (gnu_field)); - TREE_THIS_VOLATILE (gnu_field) = Treat_As_Volatile (gnat_field); + TREE_THIS_VOLATILE (gnu_field) = TREE_SIDE_EFFECTS (gnu_field) = is_volatile; if (Ekind (gnat_field) == E_Discriminant) DECL_DISCRIMINANT_NUMBER (gnu_field) Index: tree-sra.c =================================================================== --- tree-sra.c (revision 175136) +++ tree-sra.c (working copy) @@ -671,8 +671,7 @@ type_internals_preclude_sra_p (tree type && int_bit_position (fld) % BITS_PER_UNIT != 0)) return true; - if (AGGREGATE_TYPE_P (ft) - && type_internals_preclude_sra_p (ft)) + if (AGGREGATE_TYPE_P (ft) && type_internals_preclude_sra_p (ft)) return true; } @@ -681,10 +680,13 @@ type_internals_preclude_sra_p (tree type case ARRAY_TYPE: et = TREE_TYPE (type); - if (AGGREGATE_TYPE_P (et)) - return type_internals_preclude_sra_p (et); - else - return false; + if (TYPE_VOLATILE (et)) + return true; + + if (AGGREGATE_TYPE_P (et) && type_internals_preclude_sra_p (et)) + return true; + + return false; default: return false; --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/x-adasrc; charset="iso 8859-15"; name="volatile6.adb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="volatile6.adb" Content-length: 368 -- { dg-do compile } -- { dg-options "-O2 -fdump-tree-optimized" } function Volatile6 return Integer is type Vol is new Integer; pragma Volatile (Vol); V : Vol := 0; begin for J in 1 .. 10 loop V := V + 1; end loop; return Integer (V); end; -- { dg-final { scan-tree-dump "goto" "optimized" } } -- { dg-final { cleanup-tree-dump "optimized" } } --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/x-adasrc; charset="iso 8859-15"; name="volatile7.adb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="volatile7.adb" Content-length: 430 -- { dg-do compile } -- { dg-options "-O2 -fdump-tree-optimized" } function Volatile7 return Integer is type Vol is new Integer; pragma Volatile (Vol); type R is record X : Vol := 0; end record; V : R; begin for J in 1 .. 10 loop V.X := V.X + 1; end loop; return Integer (V.X); end; -- { dg-final { scan-tree-dump "goto" "optimized" } } -- { dg-final { cleanup-tree-dump "optimized" } } --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/x-adasrc; charset="iso 8859-15"; name="volatile8.adb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="volatile8.adb" Content-length: 429 -- { dg-do compile } -- { dg-options "-O2 -fdump-tree-optimized" } function Volatile8 return Integer is type Vol is new Integer; pragma Volatile (Vol); type A is array (1..4) of Vol; V : A := (others => 0); begin for J in 1 .. 10 loop V(1) := V(1) + 1; end loop; return Integer (V(1)); end; -- { dg-final { scan-tree-dump "goto" "optimized" } } -- { dg-final { cleanup-tree-dump "optimized" } } --Boundary-00=_NQI/NGTmsIq+l8E Content-Type: text/x-adasrc; charset="iso 8859-15"; name="volatile9.adb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="volatile9.adb" Content-length: 403 -- { dg-do compile } -- { dg-options "-O2 -fdump-tree-optimized" } function Volatile9 return Integer is type A is array (1..4) of Integer; pragma Volatile_Components (A); V : A := (others => 0); begin for J in 1 .. 10 loop V(1) := V(1) + 1; end loop; return V(1); end; -- { dg-final { scan-tree-dump "goto" "optimized" } } -- { dg-final { cleanup-tree-dump "optimized" } } --Boundary-00=_NQI/NGTmsIq+l8E--