Reset front end trees before they make it into the middle end (PR middle-end/97172).

gcc/ChangeLog:

	PR middle-end/97172
	* attribs.c (attr_access::free_lang_data): Define new function.
	* attribs.h (attr_access::free_lang_data): Declare new function.

gcc/c/ChangeLog:

	PR middle-end/97172
	* c-decl.c (free_attr_access_data): New function.
	(c_parse_final_cleanups): Call free_attr_access_data.

gcc/testsuite/ChangeLog:

	PR middle-end/97172
	* gcc.dg/pr97172.c: New test.
This commit is contained in:
Martin Sebor 2021-02-01 09:08:21 -07:00
parent 90c9b2c176
commit 0718336a52
4 changed files with 109 additions and 0 deletions

View File

@ -2238,6 +2238,38 @@ attr_access::vla_bounds (unsigned *nunspec) const
return list_length (size);
}
/* Reset front end-specific attribute access data from ATTRS.
Called from the free_lang_data pass. */
/* static */ void
attr_access::free_lang_data (tree attrs)
{
for (tree acs = attrs; (acs = lookup_attribute ("access", acs));
acs = TREE_CHAIN (acs))
{
tree vblist = TREE_VALUE (acs);
vblist = TREE_CHAIN (vblist);
if (!vblist)
continue;
vblist = TREE_VALUE (vblist);
if (!vblist)
continue;
for (vblist = TREE_VALUE (vblist); vblist; vblist = TREE_CHAIN (vblist))
{
tree *pvbnd = &TREE_VALUE (vblist);
if (!*pvbnd || DECL_P (*pvbnd))
continue;
/* VLA bounds that are expressions as opposed to DECLs are
only used in the front end. Reset them to keep front end
trees leaking into the middle end (see pr97172) and to
free up memory. */
*pvbnd = NULL_TREE;
}
}
}
/* Defined in attr_access. */
constexpr char attr_access::mode_chars[];

View File

@ -274,6 +274,9 @@ struct attr_access
/* Return the access mode corresponding to the character code. */
static access_mode from_mode_char (char);
/* Reset front end-specific attribute access data from attributes. */
static void free_lang_data (tree);
/* The character codes corresponding to all the access modes. */
static constexpr char mode_chars[5] = { '-', 'r', 'w', 'x', '^' };

View File

@ -12146,6 +12146,27 @@ collect_source_refs (void)
collect_source_ref (DECL_SOURCE_FILE (decl));
}
/* Free attribute access data that are not needed by the middle end. */
static void
free_attr_access_data ()
{
struct cgraph_node *n;
/* Iterate over all functions declared in the translation unit. */
FOR_EACH_FUNCTION (n)
{
tree fntype = TREE_TYPE (n->decl);
if (!fntype)
continue;
tree attrs = TYPE_ATTRIBUTES (fntype);
if (!attrs)
continue;
attr_access::free_lang_data (attrs);
}
}
/* Perform any final parser cleanups and generate initial debugging
information. */
@ -12190,6 +12211,9 @@ c_parse_final_cleanups (void)
c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
c_write_global_declarations_1 (BLOCK_VARS (ext_block));
if (!in_lto_p)
free_attr_access_data ();
timevar_stop (TV_PHASE_DEFERRED);
timevar_start (TV_PHASE_PARSING);

View File

@ -0,0 +1,50 @@
/* PR middle-end/97172 - ICE: tree code ssa_name is not supported in LTO
streams
{ dg-do compile }
{ dg-options "-Wall -flto" }
{ dg-require-effective-target lto } */
int n;
void fn (int a[n]);
void fnp1 (int a[n + 1]);
void fx_n (int a[][n]);
void fx_np1 (int a[][n + 1]);
void f2_n (int a[2][n]);
void f2_np1 (int a[2][n + 1]);
void fn_3 (int a[n][3]);
void fnp1_3 (int a[n + 1][3]);
void fn_n (int a[n][n]);
void fn_np1 (int a[n][n + 1]);
void fnp1_np1 (int a[n + 1][n + 1]);
void fn_n_n (int a[n][n][n]);
void fn_n_np1 (int a[n][n][n + 1]);
void fn_np1_np1 (int a[n][n + 1][n + 1]);
void fnp1_np1_np1 (int a[n + 1][n + 1][n + 1]);
void gn (int a[n]) { fn (a); }
void gnp1 (int a[n + 1]) { fnp1 (a); }
void gx_n (int a[][n]) { fx_n (a); }
void gx_np1 (int a[][n + 1]) { fx_np1 (a); }
void g2_n (int a[2][n]) { f2_n (a); }
void g2_np1 (int a[2][n + 1]) { f2_np1 (a); }
void gn_3 (int a[n][3]) { fn_3 (a); }
void gnp1_3 (int a[n + 1][3]) { fnp1_3 (a); }
void gn_n (int a[n][n]) { fn_n (a); }
void gn_np1 (int a[n][n + 1]) { fn_np1 (a); }
void gnp1_np1 (int a[n + 1][n + 1]) { fnp1_np1 (a); }
void gn_n_n (int a[n][n][n]) { fn_n_n (a); }
void gn_n_np1 (int a[n][n][n + 1]) { fn_n_np1 (a); }
void gn_np1_np1 (int a[n][n + 1][n + 1]) { fn_np1_np1 (a); }
void gnp1_np1_np1 (int a[n + 1][n + 1][n + 1]) { fnp1_np1_np1 (a); }