public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/c++-modules] d: Fix small struct literals that have non-deterministic hash values
@ 2020-08-28 16:04 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-08-28 16:04 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1db88844a22f75b13ced224415f645680784d354

commit 1db88844a22f75b13ced224415f645680784d354
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Tue Aug 25 11:05:57 2020 +0200

    d: Fix small struct literals that have non-deterministic hash values
    
    Same issue as the initial commit that addressed PR96153, only this time to fix
    it also for structs that are not returned in memory.  Tests have been added
    that triggered an assertion on x86_64, however the original test was failing
    on SPARC 64-bit targets.
    
    gcc/d/ChangeLog:
    
            PR d/96153
            * d-codegen.cc (build_address): Create a temporary for CALL_EXPRs
            returning trivial aggregates, pre-filling it with zeroes.
            (build_memset_call): Use build_zero_cst if setting the entire object.
    
    gcc/testsuite/ChangeLog:
    
            PR d/96153
            * gdc.dg/pr96153.d: Add new tests.

Diff:
---
 gcc/d/d-codegen.cc             | 31 +++++++++++++++++++++++++++++--
 gcc/testsuite/gdc.dg/pr96153.d | 18 ++++++++++++++++++
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 6a7ecc50645..4050b85af28 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -668,9 +668,23 @@ build_address (tree exp)
   /* Some expression lowering may request an address of a compile-time constant,
      or other non-lvalue expression.  Make sure it is assigned to a location we
      can reference.  */
-  if ((CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
-      || TREE_CODE (exp) == CALL_EXPR)
+  if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
     exp = force_target_expr (exp);
+  else if (TREE_CODE (exp) == CALL_EXPR)
+    {
+      /* When a struct or array is returned in registers, we need to again fill
+	 in all alignment holes.  */
+      if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
+	  && !aggregate_value_p (TREE_TYPE (exp), exp))
+	{
+	  tree tmp = build_local_temp (TREE_TYPE (exp));
+	  init = compound_expr (init, build_memset_call (tmp));
+	  init = compound_expr (init, modify_expr (tmp, exp));
+	  exp = tmp;
+	}
+      else
+	exp = force_target_expr (exp);
+    }
 
   d_mark_addressable (exp);
   exp = build_fold_addr_expr_with_type_loc (input_location, exp, ptrtype);
@@ -825,6 +839,19 @@ build_memset_call (tree ptr, tree num)
       ptr = build_address (ptr);
     }
 
+  /* Use a zero constant to fill the destination if setting the entire object.
+     For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
+     which can then be merged with other stores to the object.  */
+  tree valtype = TREE_TYPE (TREE_TYPE (ptr));
+  if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num))
+    {
+      tree cst = build_zero_cst (valtype);
+      if (TREE_CODE (cst) == CONSTRUCTOR)
+	return build_memcpy_call (ptr, build_address (cst), num);
+
+      return modify_expr (build_deref (ptr), cst);
+    }
+
   return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3,
 			  ptr, integer_zero_node, num);
 }
diff --git a/gcc/testsuite/gdc.dg/pr96153.d b/gcc/testsuite/gdc.dg/pr96153.d
index c0e3ae024f5..e1b8d816df0 100644
--- a/gcc/testsuite/gdc.dg/pr96153.d
+++ b/gcc/testsuite/gdc.dg/pr96153.d
@@ -20,6 +20,24 @@ Checked!(T, Hook) checked(Hook, T)(const T value)
 
 @system unittest
 {
+    static struct Hook1
+    {
+        uint var1 = uint.max;
+        uint var2 = uint.max;
+    }
+
+    assert(checked!Hook1(12).toHash() != checked!Hook1(13).toHash());
+    assert(checked!Hook1(13).toHash() == checked!Hook1(13).toHash());
+
+    static struct Hook2
+    {
+        uint var1 = uint.max;
+        ushort var2 = ushort.max;
+    }
+
+    assert(checked!Hook2(12).toHash() != checked!Hook2(13).toHash());
+    assert(checked!Hook2(13).toHash() == checked!Hook2(13).toHash());
+
     static struct Hook3
     {
         ulong var1 = ulong.max;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-08-28 16:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-28 16:04 [gcc/devel/c++-modules] d: Fix small struct literals that have non-deterministic hash values Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).