]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/92384 (Empty class instances have different equal testing result...
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Nov 2019 19:02:24 +0000 (20:02 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 8 Nov 2019 19:02:24 +0000 (20:02 +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: r277989

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

index de09391a66a5fac9ae9a3fd6270bed4df57d750d..64849fa22bbc65cf3d3ac5fe22ed0c5ede6e7ffd 100644 (file)
@@ -1,5 +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.
+
        Backported from mainline
        2019-10-31  Jakub Jelinek  <jakub@redhat.com>
 
index 6c1d27f8a92138c6a8069991e5bcb8a745fe005f..acf9f9e60c7b888b8b6f1dce5046e8dc8723409b 100644 (file)
@@ -3078,7 +3078,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->passed_type))
     {
       push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
       emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
@@ -3454,7 +3454,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->passed_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)
@@ -3610,6 +3612,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.passed_type)
+             && TREE_ADDRESSABLE (parm)
+             && data.entry_parm == data.stack_parm
+             && MEM_P (data.entry_parm)
+             && int_size_in_bytes (data.passed_type))
+           data.stack_parm = NULL_RTX;
        }
       /* Record permanently how this parm was passed.  */
       if (data.passed_pointer)
index c3c660864bdf29449bbb55867bf8171eee8c63ed..90948e8ee3a285317905515134f641d4c5684132 100644 (file)
@@ -1,5 +1,8 @@
 2019-11-08  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/92384
+       * g++.dg/torture/pr92384.C: New test.
+
        Backported from mainline
        2019-11-05  Jakub Jelinek  <jakub@redhat.com>
 
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 ();
+}