aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-09-30 15:05:53 +0200
committerRichard Biener <rguenther@suse.de>2021-10-01 08:26:26 +0200
commit3a7f20ed26416b56df6f3c8240f3c65a5715b17d (patch)
treec714dba36ab60fe15d7b6c4dc04fd9df7bb2cfe3 /gcc
parentea0b5b656a0e90bc9bb3ab0920796b24a9387d76 (diff)
downloadgcc-3a7f20ed26416b56df6f3c8240f3c65a5715b17d.zip
gcc-3a7f20ed26416b56df6f3c8240f3c65a5715b17d.tar.gz
gcc-3a7f20ed26416b56df6f3c8240f3c65a5715b17d.tar.bz2
middle-end/102518 - avoid invalid GIMPLE during inlining
When inlining we have to avoid mapping a non-lvalue parameter value into a context that prevents the parameter to be a register. Formerly the register were TREE_ADDRESSABLE but now it can be just DECL_NOT_GIMPLE_REG_P. 2021-09-30 Richard Biener <rguenther@suse.de> PR middle-end/102518 * tree-inline.c (setup_one_parameter): Avoid substituting an invariant into contexts where a GIMPLE register is not valid. * gcc.dg/torture/pr102518.c: New testcase.
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)))