From 0718336a5284dd5b40fd6691a94d6be93a80f279 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 1 Feb 2021 09:08:21 -0700 Subject: [PATCH] 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. --- gcc/attribs.c | 32 ++++++++++++++++++++++ gcc/attribs.h | 3 ++ gcc/c/c-decl.c | 24 ++++++++++++++++ gcc/testsuite/gcc.dg/pr97172.c | 50 ++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr97172.c diff --git a/gcc/attribs.c b/gcc/attribs.c index 94991fbbeab..81322d40f1d 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -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[]; diff --git a/gcc/attribs.h b/gcc/attribs.h index 21d28a47f39..898e73db3e4 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -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', '^' }; diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 4ba9477f5d1..be95643fcf9 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -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); diff --git a/gcc/testsuite/gcc.dg/pr97172.c b/gcc/testsuite/gcc.dg/pr97172.c new file mode 100644 index 00000000000..ab5b2e9e7e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97172.c @@ -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); } -- 2.30.2