aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr102518.c12
-rw-r--r--gcc/tree-inline.c6
2 files changed, 17 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr102518.c b/gcc/testsuite/gcc.dg/torture/pr102518.c
new file mode 100644
index 0000000..bd181ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr102518.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+struct A {
+ int *x;
+};
+int i;
+int f(int *const c) {
+ struct A * b = (struct A *)(&c);
+ return b->x != 0;
+}
+void g() { f(&i); }
+
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 5e50e80..e292a14 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3490,7 +3490,11 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
/* We may produce non-gimple trees by adding NOPs or introduce invalid
sharing when the value is not constant or DECL. And we need to make
sure that it cannot be modified from another path in the callee. */
- if ((is_gimple_min_invariant (value)
+ if (((is_gimple_min_invariant (value)
+ /* When the parameter is used in a context that forces it to
+ not be a GIMPLE register avoid substituting something that
+ is not a decl there. */
+ && ! DECL_NOT_GIMPLE_REG_P (p))
|| (DECL_P (value) && TREE_READONLY (value))
|| (auto_var_in_fn_p (value, id->dst_fn)
&& !TREE_ADDRESSABLE (value)))