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]

Fix PR41718, ICE when compiling a large testcase


As noted in the PR, there's an integer overflow that can trigger with
very large input files.  The patch below does two things: it doubles the
maximum size of the array by exchanging the order of multiplication and
division in the overflowing expression.  It also tries to detect
overflows and give a fatal_error message rather than just an ICE.

The former is enough to make the testcase compile on my 32 bit
i686-linux system.

Bootstrap in progress, ok if no regressions?


Bernd
-- 
This footer brought to you by insane German lawmakers.
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
	* cfgexpand (n_stack_vars_conflict): New static variable.
	(triangular_index): Reduce likelyhood of overflow by performing
	the division before the multiplication.
	(resize_stack_vars_conflict): Call fatal_error if overflow
	occurred in triangular_index.  Update n_stack_vars_conflict.

Index: cfgexpand.c
===================================================================
--- cfgexpand.c	(revision 154120)
+++ cfgexpand.c	(working copy)
@@ -213,6 +213,7 @@ static size_t *stack_vars_sorted;
    is lower triangular.  */
 static bool *stack_vars_conflict;
 static size_t stack_vars_conflict_alloc;
+static size_t n_stack_vars_conflict;
 
 /* The phase of the stack frame.  This is the known misalignment of
    virtual_stack_vars_rtx from PREFERRED_STACK_BOUNDARY.  That is,
@@ -331,7 +332,11 @@ triangular_index (size_t i, size_t j)
       size_t t;
       t = i, i = j, j = t;
     }
-  return (i * (i + 1)) / 2 + j;
+
+  if (i & 1)
+    return ((i + 1) / 2) * i + j;
+  else
+    return (i / 2) * (i + 1) + j;
 }
 
 /* Ensure that STACK_VARS_CONFLICT is large enough for N objects.  */
@@ -342,12 +347,17 @@ resize_stack_vars_conflict (size_t n)
   size_t size = triangular_index (n-1, n-1) + 1;
 
   if (size <= stack_vars_conflict_alloc)
-    return;
+    {
+      if (n > n_stack_vars_conflict)
+	fatal_error ("program is too large to be compiled on this machine");
+      return;
+    }
 
   stack_vars_conflict = XRESIZEVEC (bool, stack_vars_conflict, size);
   memset (stack_vars_conflict + stack_vars_conflict_alloc, 0,
 	  (size - stack_vars_conflict_alloc) * sizeof (bool));
   stack_vars_conflict_alloc = size;
+  n_stack_vars_conflict = n;
 }
 
 /* Make the decls associated with luid's X and Y conflict.  */

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