aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2025-02-07 09:26:51 +0100
committerMarc Poulhiès <dkm@gcc.gnu.org>2025-06-12 10:37:58 +0200
commit77a646af041cf6cc1b97051b282fc096511d5920 (patch)
tree4e807d800b8d5bb2bc19cf90e9e87a0f81b5dddb
parent7c979e702e6ab30f7c0f6eaf6020917f2ddb1f64 (diff)
downloadgcc-77a646af041cf6cc1b97051b282fc096511d5920.zip
gcc-77a646af041cf6cc1b97051b282fc096511d5920.tar.gz
gcc-77a646af041cf6cc1b97051b282fc096511d5920.tar.bz2
ada: Fix code size increase with pragma Aggregate_Individually_Assign
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.
-rw-r--r--gcc/ada/gcc-interface/decl.cc20
1 files changed, 19 insertions, 1 deletions
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 1694b4e..972607a 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -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;