From b3a51b99dbba2035723ccec69a8f0037f547bddf Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 11 Sep 2020 10:41:28 +0200 Subject: [PATCH] Fix crash on array component with nonstandard index type This is a regression present on mainline, 10 and 9 branches: the compiler goes into an infinite recursion eventually exhausting the stack for the declaration of a discriminated record type with an array component having a discriminant as bound and an index type that is an enumeration type with a non-standard representation clause. gcc/ada/ChangeLog: * gcc-interface/decl.c (gnat_to_gnu_entity) : Only create extra subtypes for discriminants if the RM size of the base type of the index type is lower than that of the index type. gcc/testsuite/ChangeLog: * gnat.dg/specs/discr7.ads: New test. --- gcc/ada/gcc-interface/decl.c | 12 ++++++------ gcc/testsuite/gnat.dg/specs/discr7.ads | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/discr7.ads diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 0117f1b8d349..9ca7884f3d34 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -2433,8 +2433,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) tree gnu_base_orig_max = TYPE_MAX_VALUE (gnu_base_index_type); tree gnu_min, gnu_max, gnu_high; - /* We try to define subtypes for discriminants used as bounds - that are more restrictive than those declared by using the + /* We try to create subtypes for discriminants used as bounds + that are more restrictive than those declared, by using the bounds of the index type of the base array type. This will make it possible to calculate the maximum size of the record type more conservatively. This may have already been done by @@ -2442,8 +2442,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) there will be a conversion that needs to be removed first. */ if (CONTAINS_PLACEHOLDER_P (gnu_orig_min) && TYPE_RM_SIZE (gnu_base_index_type) - && !tree_int_cst_lt (TYPE_RM_SIZE (gnu_index_type), - TYPE_RM_SIZE (gnu_base_index_type))) + && tree_int_cst_lt (TYPE_RM_SIZE (gnu_base_index_type), + TYPE_RM_SIZE (gnu_index_type))) { gnu_orig_min = remove_conversions (gnu_orig_min, false); TREE_TYPE (gnu_orig_min) @@ -2454,8 +2454,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) if (CONTAINS_PLACEHOLDER_P (gnu_orig_max) && TYPE_RM_SIZE (gnu_base_index_type) - && !tree_int_cst_lt (TYPE_RM_SIZE (gnu_index_type), - TYPE_RM_SIZE (gnu_base_index_type))) + && tree_int_cst_lt (TYPE_RM_SIZE (gnu_base_index_type), + TYPE_RM_SIZE (gnu_index_type))) { gnu_orig_max = remove_conversions (gnu_orig_max, false); TREE_TYPE (gnu_orig_max) diff --git a/gcc/testsuite/gnat.dg/specs/discr7.ads b/gcc/testsuite/gnat.dg/specs/discr7.ads new file mode 100644 index 000000000000..ca35ced2e7ae --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/discr7.ads @@ -0,0 +1,14 @@ +-- { dg-do compile } + +package Discr7 is + + type Enum is (One, Two, Three); + for Enum use (One => 1, Two => 2, Three => 3); + + type Arr is array (Integer range <>, Enum range <>) of Boolean; + + type Rec (D : Integer) is record + A: Arr (1 .. D, Enum'Range); + end record; + +end Discr7; -- 2.47.2