public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Marc Poulhiès" <poulhies@adacore.com>
To: gcc-patches@gcc.gnu.org
Cc: Eric Botcazou <ebotcazou@adacore.com>
Subject: [COMMITTED] ada: Fix bogus Storage_Error on dynamic array with static zero length
Date: Tue, 30 May 2023 09:21:20 +0200	[thread overview]
Message-ID: <20230530072120.2500814-1-poulhies@adacore.com> (raw)

From: Eric Botcazou <ebotcazou@adacore.com>

This works around the limitations present for the support of arrays in the
middle-end by clearing the TREE_OVERFLOW flag for arrays with zero length.

gcc/ada/

	* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Type>: Use a
	local variable for the GNAT index type.
	<E_Array_Subtype>: Likewise.  Call Is_Null_Range on the bounds and
	force the zero on TYPE_SIZE and TYPE_SIZE_UNIT if it returns true.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gcc-interface/decl.cc | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 456fe53737d..e5e04ddad93 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -2241,9 +2241,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	     index += (convention_fortran_p ? - 1 : 1),
 	     gnat_index = Next_Index (gnat_index))
 	  {
+	    const Entity_Id gnat_index_type = Etype (gnat_index);
 	    const bool is_flb
-	      = Is_Fixed_Lower_Bound_Index_Subtype (Etype (gnat_index));
-	    tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
+	      = Is_Fixed_Lower_Bound_Index_Subtype (gnat_index_type);
+	    tree gnu_index_type = get_unpadded_type (gnat_index_type);
 	    tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type);
 	    tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type);
 	    tree gnu_index_base_type = get_base_type (gnu_index_type);
@@ -2479,6 +2480,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	  const int ndim = Number_Dimensions (gnat_entity);
 	  tree gnu_base_type = gnu_type;
 	  tree *gnu_index_types = XALLOCAVEC (tree, ndim);
+	  bool *gnu_null_ranges = XALLOCAVEC (bool, ndim);
 	  tree gnu_max_size = size_one_node;
 	  bool need_index_type_struct = false;
 	  int index;
@@ -2494,7 +2496,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	       gnat_index = Next_Index (gnat_index),
 	       gnat_base_index = Next_Index (gnat_base_index))
 	    {
-	      tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
+	      const Entity_Id gnat_index_type = Etype (gnat_index);
+	      tree gnu_index_type = get_unpadded_type (gnat_index_type);
 	      tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type);
 	      tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type);
 	      tree gnu_index_base_type = get_base_type (gnu_index_type);
@@ -2671,6 +2674,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 		= create_index_type (gnu_min, gnu_high, gnu_index_type,
 				     gnat_entity);
 
+	      /* Record whether the range is known to be null at compile time
+		 to disambiguate it from too large ranges.  */
+	      const Entity_Id gnat_ui_type = Underlying_Type (gnat_index_type);
+	      gnu_null_ranges[index]
+		= Is_Null_Range (Type_Low_Bound (gnat_ui_type),
+				 Type_High_Bound (gnat_ui_type));
+
 	      /* We need special types for debugging information to point to
 		 the index types if they have variable bounds, are not integer
 		 types, are biased or are wider than sizetype.  These are GNAT
@@ -2737,7 +2747,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	      if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
 		set_nonaliased_component_on_array_type (gnu_type);
 
-	      /* Kludge to remove the TREE_OVERFLOW flag for the sake of LTO
+	      /* Clear the TREE_OVERFLOW flag, if any, for null arrays.  */
+	      if (gnu_null_ranges[index])
+		{
+		  TYPE_SIZE (gnu_type) = bitsize_zero_node;
+		  TYPE_SIZE_UNIT (gnu_type) = size_zero_node;
+		}
+
+	      /* Kludge to clear the TREE_OVERFLOW flag for the sake of LTO
 		 on maximally-sized array types designed by access types.  */
 	      if (integer_zerop (TYPE_SIZE (gnu_type))
 		  && TREE_OVERFLOW (TYPE_SIZE (gnu_type))
-- 
2.40.0


                 reply	other threads:[~2023-05-30  7:21 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230530072120.2500814-1-poulhies@adacore.com \
    --to=poulhies@adacore.com \
    --cc=ebotcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).