From patchwork Wed Aug 26 08:14:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1351699 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=ISZgn953; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BbzDc0p8Bz9sSJ for ; Wed, 26 Aug 2020 18:14:56 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2AC8F385040E; Wed, 26 Aug 2020 08:14:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2AC8F385040E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1598429694; bh=fC9mFuEhZS5qKDe2WjY2nZCydK+N4EPEhmJ0YI63gCg=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ISZgn9538IpIF6MsAfMR7yyqyOLu5vEQB09xWht45LP6wosQx52/CFEMLQmjhk+oc Nfq03Qwa5RbsJBwouWnfY4N3fVLnVyf36+tZ+ds/fDX671OaDLCdgwcv3Uh1vMOKvq YDZHufhu2ORZ9qpt5yFAWaGEJmh3AF5+zclhgJ9w= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-102.mailbox.org (mout-p-102.mailbox.org [IPv6:2001:67c:2050::465:102]) by sourceware.org (Postfix) with ESMTPS id C9DE4386102C for ; Wed, 26 Aug 2020 08:14:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C9DE4386102C Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4BbzDV6FBmzKmWQ; Wed, 26 Aug 2020 10:14:50 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter04.heinlein-hosting.de (spamfilter04.heinlein-hosting.de [80.241.56.122]) (amavisd-new, port 10030) with ESMTP id nKQqb2cprItO; Wed, 26 Aug 2020 10:14:47 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Fix small struct literals that have non-deterministic hash values Date: Wed, 26 Aug 2020 10:14:46 +0200 Message-Id: <20200826081446.451079-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: * X-Rspamd-Score: 1.26 / 15.00 / 15.00 X-Rspamd-Queue-Id: C6FF4679 X-Rspamd-UID: 582f92 X-Spam-Status: No, score=-15.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch addresses the same issue as the first patch for PR96153, only this time, 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. Regstrapped on x86_64-linux-gnu/-m32/-mx32, committed to mainline, and backported to the releases/gcc-10 branch. Regards Iain --- 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. --- 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;