]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix code size increase with pragma Aggregate_Individually_Assign
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 7 Feb 2025 08:26:51 +0000 (09:26 +0100)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Thu, 12 Jun 2025 08:37:58 +0000 (10:37 +0200)
The problem is that individual assignments have to preserve the other bits
of the target, in other words the original semantics of aggregates, where
the anonymous object is entirely constructed, is partially lost.

gcc/ada/ChangeLog:

* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Variable>: Generate
a zero-initialization for the anonymous object of a small aggregate
allocated on the stack.
(inline_status_for_subprog): Minor tweak.

gcc/ada/gcc-interface/decl.cc

index 1694b4eb1065f3162be614d22b9d0b6bfb3c8d25..972607a917b06ae7532832323b55dca75002ab22 100644 (file)
@@ -1228,6 +1228,24 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
            gnu_expr = gnat_build_constructor (gnu_type, v);
          }
 
+       /* If we are allocating the anonymous object of a small aggregate on
+          the stack, zero-initialize it so that the entire object is assigned
+          and the subsequent assignments need not preserve unknown bits, but
+          do it only when optimization is enabled for the sake of consistency
+          with the gimplifier which does the same for CONSTRUCTORs.  */
+       else if (definition
+                && !imported_p
+                && !static_flag
+                && !gnu_expr
+                && TREE_CODE (gnu_type) == RECORD_TYPE
+                && TREE_CODE (gnu_object_size) == INTEGER_CST
+                && compare_tree_int (gnu_object_size, MAX_FIXED_MODE_SIZE) <= 0
+                && Present (Related_Expression (gnat_entity))
+                && Nkind (Original_Node (Related_Expression (gnat_entity)))
+                   == N_Aggregate
+                && optimize)
+           gnu_expr = build_constructor (gnu_type, NULL);
+
        /* Convert the expression to the type of the object if need be.  */
        if (gnu_expr && initial_value_needs_conversion (gnu_type, gnu_expr))
          gnu_expr = convert (gnu_type, gnu_expr);
@@ -5251,7 +5269,7 @@ inline_status_for_subprog (Entity_Id subprog)
          && Is_Record_Type (Etype (First_Formal (subprog)))
          && (gnu_type = gnat_to_gnu_type (Etype (First_Formal (subprog))))
          && !TYPE_IS_BY_REFERENCE_P (gnu_type)
-         && tree_fits_uhwi_p (TYPE_SIZE (gnu_type))
+         && TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST
          && compare_tree_int (TYPE_SIZE (gnu_type), MAX_FIXED_MODE_SIZE) <= 0)
        return is_prescribed;