aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-02-01 09:08:21 -0700
committerMartin Sebor <msebor@redhat.com>2021-02-01 09:09:52 -0700
commit0718336a5284dd5b40fd6691a94d6be93a80f279 (patch)
treeb873cfd81012cb3152afe090d344c4cb7f9aa89b
parent90c9b2c17688f7be434415e90c5a655a6ecfaa9e (diff)
downloadgcc-0718336a5284dd5b40fd6691a94d6be93a80f279.zip
gcc-0718336a5284dd5b40fd6691a94d6be93a80f279.tar.gz
gcc-0718336a5284dd5b40fd6691a94d6be93a80f279.tar.bz2
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.
-rw-r--r--gcc/attribs.c32
-rw-r--r--gcc/attribs.h3
-rw-r--r--gcc/c/c-decl.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr97172.c50
4 files changed, 109 insertions, 0 deletions
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 94991fb..81322d4 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 21d28a4..898e73d 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 4ba9477..be95643 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 0000000..ab5b2e9
--- /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); }