aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr87793.c42
4 files changed, 65 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9df874d..21d9ae7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR target/87793
+ * config/i386/i386.c (ix86_const_not_ok_for_debug_p): Reject
+ non-toplevel UNSPEC.
+
2018-11-08 Aldy Hernandez <aldyh@redhat.com>
* tree-vrp.c (value_range::check): Do not access internals
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 77dec0f..711bec0c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -17177,6 +17177,18 @@ ix86_const_not_ok_for_debug_p (rtx x)
if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
return true;
+ /* Reject UNSPECs within expressions. We could accept symbol@gotoff
+ + literal_constant, but that would hardly come up in practice,
+ and it's not worth the trouble of having to reject that as an
+ operand to pretty much anything else. */
+ if (UNARY_P (x)
+ && GET_CODE (XEXP (x, 0)) == UNSPEC)
+ return true;
+ if (BINARY_P (x)
+ && (GET_CODE (XEXP (x, 0)) == UNSPEC
+ || GET_CODE (XEXP (x, 1)) == UNSPEC))
+ return true;
+
return false;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa79847..9a7dfc2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR target/87793
+ * gcc.dg/pr87793.c: New.
+
2018-11-09 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* gcc.target/arm/neon-vect-div-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr87793.c b/gcc/testsuite/gcc.dg/pr87793.c
new file mode 100644
index 0000000..3194313
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr87793.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-fpic -Os -g" } */
+
+struct fit_loadable_tbl {
+ int type;
+ void (*handler)(int data, int size);
+};
+
+#define ll_entry_start(_type, _list) \
+({ \
+ static char start[0] __attribute__((aligned(4))) \
+ __attribute__((unused, section(".u_boot_list_2_"#_list"_1"))); \
+ (_type *)&start; \
+})
+
+#define ll_entry_end(_type, _list) \
+({ \
+ static char end[0] __attribute__((aligned(4))) \
+ __attribute__((unused, section(".u_boot_list_2_"#_list"_3"))); \
+ (_type *)&end; \
+})
+
+#define ll_entry_count(_type, _list) \
+ ({ \
+ _type *start = ll_entry_start(_type, _list); \
+ _type *end = ll_entry_end(_type, _list); \
+ unsigned int _ll_result = end - start; \
+ _ll_result; \
+ })
+
+void test(int img_type, int img_data, int img_len)
+{
+ int i;
+ const unsigned int count =
+ ll_entry_count(struct fit_loadable_tbl, fit_loadable);
+ struct fit_loadable_tbl *fit_loadable_handler =
+ ll_entry_start(struct fit_loadable_tbl, fit_loadable);
+
+ for (i = 0; i < count; i++, fit_loadable_handler++)
+ if (fit_loadable_handler->type == img_type)
+ fit_loadable_handler->handler(img_data, img_len);
+}