This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix tree-optimization/91169


Hi,

this fixes the cd2a31a regression in the ACATS testsuite on 32-bit targets 
introduced by the recent change to get_array_ctor_element_at_index:

	* fold-const.h (get_array_ctor_element_at_index): Adjust.
	* fold-const.c (get_array_ctor_element_at_index): Add
	ctor_idx output parameter informing the caller where in
	the constructor the element was (not) found.  Add early exit
	for when the ctor is sorted.

This change overlooks that the index can wrap around during the traversal of 
the CONSTRUCTOR and therefore causes the function to return bogus values as 
soon as this happens.  Moreover, given this chunk of added code:

      else if (in_gimple_form)
	/* We're past the element we search for.  Note during parsing
	   the elements might not be sorted.
	   ???  We should use a binary search and a flag on the
	   CONSTRUCTOR as to whether elements are sorted in declaration
	   order.  */
	break;

I would respectfully suggest that the author thinks about redoing things from 
scratch here.  In the meantime, the attached patch kludges around the issue.

Tested on x86_64-suse-linux, OK for the mainline?


2019-08-01  Eric Botcazou  <ebotcazou@adacore.com>

	PR tree-optimization/91169
	* fold-const.c (get_array_ctor_element_at_index): Remove early exit and
	do not return a bogus ctor_idx when the index wraps around.

-- 
Eric Botcazou
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 273907)
+++ fold-const.c	(working copy)
@@ -11841,9 +11841,9 @@ fold_ternary_loc (location_t loc, enum tree_code c
 /* Gets the element ACCESS_INDEX from CTOR, which must be a CONSTRUCTOR
    of an array (or vector).  *CTOR_IDX if non-NULL is updated with the
    constructor element index of the value returned.  If the element is
-   not found NULL_TREE is returned and *CTOR_IDX is updated to
-   the index of the element after the ACCESS_INDEX position (which
-   may be outside of the CTOR array).  */
+   not found, then NULL_TREE is returned and *CTOR_IDX is updated to
+   the index of the element after the ACCESS_INDEX position (which may
+   be outside of the CTOR array).  */
 
 tree
 get_array_ctor_element_at_index (tree ctor, offset_int access_index,
@@ -11874,8 +11874,9 @@ get_array_ctor_element_at_index (tree ctor, offset
 		     TYPE_SIGN (index_type));
 
   offset_int max_index;
-  unsigned cnt;
+  unsigned cnt, after_cnt;
   tree cfield, cval;
+  bool after_cnt_valid = false;
 
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
     {
@@ -11895,10 +11896,15 @@ get_array_ctor_element_at_index (tree ctor, offset
 	}
       else
 	{
+	  const offset_int old_index = index;
 	  index += 1;
 	  if (index_type)
-	    index = wi::ext (index, TYPE_PRECISION (index_type),
-			     TYPE_SIGN (index_type));
+	    {
+	      index = wi::ext (index, TYPE_PRECISION (index_type),
+			       TYPE_SIGN (index_type));
+	      if (wi::cmpu (index, old_index) <= 0)
+		after_cnt_valid = false;
+	    }
 	  max_index = index;
 	}
 
@@ -11912,16 +11918,20 @@ get_array_ctor_element_at_index (tree ctor, offset
 	      return cval;
 	    }
 	}
-      else if (in_gimple_form)
-	/* We're past the element we search for.  Note during parsing
-	   the elements might not be sorted.
-	   ???  We should use a binary search and a flag on the
-	   CONSTRUCTOR as to whether elements are sorted in declaration
-	   order.  */
-	break;
+
+      /* We may be past the element we search for.  Note that during parsing
+	 the elements might not be sorted.  Note also that the index may wrap
+	 around during the traversal of the constructor if it was signed.
+	 ??? We should use a binary search and a flag on the CONSTRUCTOR as
+	 to whether elements are sorted in declaration order.  */
+      else if (in_gimple_form && !after_cnt_valid)
+	{
+	  after_cnt = cnt;
+	  after_cnt_valid = true;
+	}
     }
   if (ctor_idx)
-    *ctor_idx = cnt;
+    *ctor_idx = after_cnt_valid ? after_cnt : cnt;
   return NULL_TREE;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]