middle-end/112487 - inline and parameter mismatch

Message ID 20231113133844.16AD213398@imap2.suse-dmz.suse.de
State Accepted
Headers
Series middle-end/112487 - inline and parameter mismatch |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Richard Biener Nov. 13, 2023, 1:38 p.m. UTC
  When passing an aggregate to a implicitly declared function that's
later declared as receiving a register type we can run into a
sanity assert that cannot hold for such gross mismatches.  Instead
of asserting avoid emitting a debug temp that's invalid.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR middle-end/112487
	* tree-inline.cc (setup_one_parameter): When the parameter
	is unused only insert a debug bind when there's not a gross
	mismatch in value and declared parameter type.  Do not assert
	there effectively isn't.

	* gcc.dg/torture/pr112487.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr112487.c | 18 ++++++++++++++++++
 gcc/tree-inline.cc                      |  6 +++++-
 2 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr112487.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr112487.c b/gcc/testsuite/gcc.dg/torture/pr112487.c
new file mode 100644
index 00000000000..bc2838ee3eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr112487.c
@@ -0,0 +1,18 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-w -std=gnu89" } */
+
+struct A { char i; };
+struct B {
+  struct C *p;
+  struct A *q;
+};
+struct C { struct B a[1]; };
+struct T { struct U *ptr; };
+
+volatile struct T v;
+void f1(volatile struct T v) { f2(v); }
+void f2(volatile struct T *const v) { }
+void bar() {
+  struct U *ptr;
+  f1(v);
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 00d05102e7a..0b14118b94b 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -3562,7 +3562,11 @@  setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
      it.  */
   if (optimize && gimple_in_ssa_p (cfun) && !def && is_gimple_reg (p))
     {
-      gcc_assert (!value || !TREE_SIDE_EFFECTS (value));
+      /* When there's a gross type mismatch between the passed value
+	 and the declared argument type drop it on the floor and do
+	 not bother to insert a debug bind.  */
+      if (value && !is_gimple_reg_type (TREE_TYPE (value)))
+	return NULL;
       return insert_init_debug_bind (id, bb, var, rhs, NULL);
     }