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] Prevent memory explosion for big discriminated types


Hi,

in Ada types can be very dynamic: not only can their shape depend on variables 
but it can also depend on the object itself (these are called self-referential 
types).  This raises interesting compile-time issues when you have dozens of 
dynamic fields in a record type, or dozens of nested dynamic record types, as 
every offset or size calculation is a fully-fledged expression in the GENERIC 
language and they can quickly add up if you are not careful.

This is dealt with in stor-layout.c by means of the variable_size function, 
which ensures that these expressions are evaluated only once instead of being 
duplicated again and again as the complexity grows up.  The problem is that it 
is only called for size expressions (DECL_SIZE and DECL_SIZE_UNIT), which is 
fine for nested types, but not for offsets, which means that you will have a 
memory explosion for flat types with dozens of consecutive dynamic fields.

The patch plugs the hole by invoking it for DECL_FIELD_OFFSET as well (and the 
effect is spectacular for pathological cases).  Tested on x86_64-suse-linux, 
although this will essentially only affect Ada.  OK for the mainline?


2014-04-14  Eric Botcazou  <ebotcazou@adacore.com>

	* stor-layout.c (place_field): Finalize non-constant offset for the
	field, if any.


-- 
Eric Botcazou
Index: stor-layout.c
===================================================================
--- stor-layout.c	(revision 209334)
+++ stor-layout.c	(working copy)
@@ -1417,6 +1417,10 @@ place_field (record_layout_info rli, tre
   DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
   SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
 
+  /* Evaluate nonconstant offsets only once, either now or as soon as safe.  */
+  if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST)
+    DECL_FIELD_OFFSET (field) = variable_size (DECL_FIELD_OFFSET (field));
+
   /* If this field ended up more aligned than we thought it would be (we
      approximate this by seeing if its position changed), lay out the field
      again; perhaps we can use an integral mode for it now.  */

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