aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-03-30 11:13:59 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-03-30 21:03:00 -0400
commit3809bcd6c0ee324cbd855c68cee104c8bf134dbe (patch)
tree568baf4fc6b07c0092c61cdfad2ad9ba176156ac /gcc
parent13a29fc5730ac3a5e3296971d15ca63dcc0ae261 (diff)
downloadgcc-3809bcd6c0ee324cbd855c68cee104c8bf134dbe.zip
gcc-3809bcd6c0ee324cbd855c68cee104c8bf134dbe.tar.gz
gcc-3809bcd6c0ee324cbd855c68cee104c8bf134dbe.tar.bz2
lra: set insn_code_data to NULL when freeing
libgccjit's test-threads.c repeatedly compiles and runs numerous tests, each in a separate thread. Attempting to add an empty test that generates no code leads to a double-free ICE within that thread, within lra.c's finish_insn_code_data_once. The root cause is that the insn_code_data array is cleared in init_insn_code_data_once, but this is only called the first time a cgraph_node is expanded [1], whereas the "loop-over-all-elements and free them" is unconditionally called in finalize [2]. Hence if there are no functions: * the array is not re-initialized for the empty context * when finish_insn_code_data_once is called for the empty context it still contains the freed pointers from the previous context that held the jit mutex, and hence the free is a double-free. This patch sets the pointers to NULL after freeing them, fixing the ICE. [1] init_insn_code_data_once is called via lra_init_once called by ira_init_once called by initialize_rtl, via: if (!rtl_initialized) ira_init_once (); called by init_function_start called by cgraph_node::expand [2]: finish_insn_code_data_once is called by: lra_finish_once called by finalize gcc/ChangeLog: * lra.c (finish_insn_code_data_once): Set the array elements to NULL after freeing them. gcc/testsuite/ChangeLog: * jit.dg/all-non-failing-tests.h: Add test-empty.c
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/lra.c5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h10
4 files changed, 23 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ace41d0..101956a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2020-03-30 David Malcolm <dmalcolm@redhat.com>
+
+ * lra.c (finish_insn_code_data_once): Set the array elements
+ to NULL after freeing them.
+
2020-03-30 Andreas Schwab <schwab@suse.de>
* config/host-linux.c (TRY_EMPTY_VM_SPACE) [__riscv && __LP64__]:
diff --git a/gcc/lra.c b/gcc/lra.c
index d5ea362..5e8b75b 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -653,7 +653,10 @@ finish_insn_code_data_once (void)
for (unsigned int i = 0; i < NUM_INSN_CODES; i++)
{
if (insn_code_data[i] != NULL)
- free (insn_code_data[i]);
+ {
+ free (insn_code_data[i]);
+ insn_code_data[i] = NULL;
+ }
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 66c71f1..c72aa9a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2020-03-30 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/all-non-failing-tests.h: Add test-empty.c
+
2020-03-30 Jakub Jelinek <jakub@redhat.com>
PR c++/94385
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index b2acc74..af74419 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -116,6 +116,13 @@
#undef create_code
#undef verify_code
+/* test-empty.c */
+#define create_code create_code_empty
+#define verify_code verify_code_empty
+#include "test-empty.c"
+#undef create_code
+#undef verify_code
+
/* test-error-*.c: We don't use these test cases, since they deliberately
introduce errors, which we don't want here. */
@@ -328,6 +335,9 @@ const struct testcase testcases[] = {
{"expressions",
create_code_expressions,
verify_code_expressions},
+ {"empty",
+ create_code_empty,
+ verify_code_empty},
{"factorial",
create_code_factorial,
verify_code_factorial},