re PR middle-end/92384 (Empty class instances have different equal testing result...
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Nov 2019 10:52:50 +0000 (11:52 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 8 Nov 2019 10:52:50 +0000 (11:52 +0100)
PR c++/92384
* function.c (assign_parm_setup_block, assign_parm_setup_stack): Don't
copy TYPE_EMPTY_P arguments from data->entry_parm to data->stack_parm
slot.
(assign_parms): For TREE_ADDRESSABLE parms with TYPE_EMPTY_P type
force creation of a unique data.stack_parm slot.

* g++.dg/torture/pr92384.C: New test.

From-SVN: r277962

gcc/ChangeLog
gcc/function.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr92384.C [new file with mode: 0644]

index d2dd042..3649706 100644 (file)
@@ -1,3 +1,12 @@
+2019-11-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/92384
+       * function.c (assign_parm_setup_block, assign_parm_setup_stack): Don't
+       copy TYPE_EMPTY_P arguments from data->entry_parm to data->stack_parm
+       slot.
+       (assign_parms): For TREE_ADDRESSABLE parms with TYPE_EMPTY_P type
+       force creation of a unique data.stack_parm slot.
+
 2019-11-08  Richard Biener  <rguenther@suse.de>
 
        * genmatch.c (expr::gen_transform): Use the resimplify
index 3f79a38..1fe956b 100644 (file)
@@ -3087,7 +3087,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
        move_block_from_reg (REGNO (entry_parm), mem,
                             size_stored / UNITS_PER_WORD);
     }
-  else if (data->stack_parm == 0)
+  else if (data->stack_parm == 0 && !TYPE_EMPTY_P (data->arg.type))
     {
       push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
       emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
@@ -3488,7 +3488,9 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
       dest = validize_mem (copy_rtx (data->stack_parm));
       src = validize_mem (copy_rtx (data->entry_parm));
 
-      if (MEM_P (src))
+      if (TYPE_EMPTY_P (data->arg.type))
+       /* Empty types don't really need to be copied.  */;
+      else if (MEM_P (src))
        {
          /* Use a block move to handle potentially misaligned entry_parm.  */
          if (!to_conversion)
@@ -3643,6 +3645,16 @@ assign_parms (tree fndecl)
        {
          assign_parm_find_stack_rtl (parm, &data);
          assign_parm_adjust_entry_rtl (&data);
+         /* For arguments that occupy no space in the parameter
+            passing area, have non-zero size and have address taken,
+            force creation of a stack slot so that they have distinct
+            address from other parameters.  */
+         if (TYPE_EMPTY_P (data.arg.type)
+             && TREE_ADDRESSABLE (parm)
+             && data.entry_parm == data.stack_parm
+             && MEM_P (data.entry_parm)
+             && int_size_in_bytes (data.arg.type))
+           data.stack_parm = NULL_RTX;
        }
       /* Record permanently how this parm was passed.  */
       if (data.arg.pass_by_reference)
index 8b7bea0..6e3027f 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/92384
+       * g++.dg/torture/pr92384.C: New test.
+
 2019-11-08  Martin Liska  <mliska@suse.cz>
 
        * g++.dg/pr92339.C: Rename identifiers to something
diff --git a/gcc/testsuite/g++.dg/torture/pr92384.C b/gcc/testsuite/g++.dg/torture/pr92384.C
new file mode 100644 (file)
index 0000000..049a45a
--- /dev/null
@@ -0,0 +1,38 @@
+// PR c++/92384
+// { dg-do run }
+
+struct S {};
+struct T : public S { S a, b, c, d, e, f, g, h, i, j, k, l, m; };
+struct U { long long a, b, c; };
+
+U
+foo (S, S, S, T, T, T, U g)
+{
+  return g;
+}
+
+__attribute__((noipa)) bool
+bar (S a, S b, S c, T d, T e, T f, U g, void **h)
+{
+  h[0] = (void *) &a;
+  h[1] = (void *) &b;
+  h[2] = (void *) &c;
+  h[3] = (void *) &d;
+  h[4] = (void *) &e;
+  h[5] = (void *) &f;
+  h[6] = (void *) &g;
+  asm volatile ("" : : "r" (h) : "memory");
+  return (h[0] != h[1] && h[1] != h[2] && h[2] != h[3]
+         && h[3] != h[4] && h[4] != h[5] && h[5] != h[6]);
+}
+
+int
+main ()
+{
+  S a;
+  T b;
+  U c = { 1, 2, 3 };
+  void *d[7];
+  if (!bar (a, a, a, b, b, b, c, d))
+    __builtin_abort ();
+}