From patchwork Thu Nov 7 08:34:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1190974 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=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512674-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="pDQ2rpaC"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="OqecGKOv"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 477xY60pzgz9sNx for ; Thu, 7 Nov 2019 19:35:03 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; q=dns; s=default; b=PcO PAumtimMKq+KKqsc5VCqKdsH1Gev9Bil8f4G92t5yyDXWIvhzxQU56t9mHNFnEUx ePcXNY+ttwifSzOQ0WBKpUa+XgqGT6AMk/QA/boFNMKAzwGCWoU3/7M7+oaSQUu6 QPqZqqumJodPUbkbU93+JsKGF6s9TwMC02zqE1Zk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type:content-transfer-encoding; s=default; bh=a1YWG1itF K1KZFYAkcF0eZWiAuA=; b=pDQ2rpaCl+Sk/dHY1WnuJb1HrhnImChWPAsj+UX1q tbL7lIn77HHi2ek6Wy6L6mCwCXTq0AlzHQJxZZkHFjSKU5kG2UDuD71DqyF59EtQ tdPvARTgpG8oRUdq9lqI0a/pwcHnbZoXWV2x+VksZIL7r/8ue32XpVEIxNMtGS1Q pU= Received: (qmail 12304 invoked by alias); 7 Nov 2019 08:34:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 12294 invoked by uid 89); 7 Nov 2019 08:34:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=permanently X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-2.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Nov 2019 08:34:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573115692; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=P7perGmM5Vl6gh6gd8iVrdeXJdA57F8g/SmDbpeJWaM=; b=OqecGKOvrBlttJ3ApgUqtbgKr37OEvahBNue+FOM21nTyOK7MNxMqqDS+Nm2IBRnCx46oM uv4kiyvJ+gtPk3/gOz02qKZ2UHX8rrGIp9zZPo/80uHiPoWNsnfkEnfmoGyB1ckKSy8R2l cavLI5WpBHHBxRATmczGIrSWGhcnV/o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-219-DumX0CF4Ni6nFnMOGKh35A-1; Thu, 07 Nov 2019 03:34:49 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 851B4800C61; Thu, 7 Nov 2019 08:34:48 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.36.118.135]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A0903CCA; Thu, 7 Nov 2019 08:34:48 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id xA78YjMv023391; Thu, 7 Nov 2019 09:34:46 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id xA78YhFJ023390; Thu, 7 Nov 2019 09:34:43 +0100 Date: Thu, 7 Nov 2019 09:34:43 +0100 From: Jakub Jelinek To: Jason Merrill , Richard Biener , Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Ensure x86_64 TYPE_EMPTY_P args have distinct addresses (PR c++/92384) Message-ID: <20191107083443.GD4650@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Mimecast-Spam-Score: 0 Content-Disposition: inline X-IsSubscribed: yes Hi! TYPE_EMPTY_P arguments (which right now only x86_64 uses) have data->entry_parm == data->stack_parm being a stack slot with zero size in the stack parameter passing area. The problem with that is that in C++ they should have distinct addresses from other objects, which is not the case right now, as their address is equal to whatever argument is after it on the stack. The following patch in the third hunk, if the TYPE_EMPTY_P argument has address taken forces stack_parm to be NULL, so that a new slot will be created for it, and the other two hunks just make sure we don't actually copy anything, as the TYPE_EMPTY_P types contain solely padding and so it is ok if they are just allocated on the stack, but are not copied. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-11-07 Jakub Jelinek 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. Jakub --- gcc/function.c.jj 2019-10-01 18:16:13.205128183 +0200 +++ gcc/function.c 2019-11-06 09:30:47.097353832 +0100 @@ -3087,7 +3087,7 @@ assign_parm_setup_block (struct assign_p 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_p 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) --- gcc/testsuite/g++.dg/torture/pr92384.C.jj 2019-11-06 10:01:39.794413342 +0100 +++ gcc/testsuite/g++.dg/torture/pr92384.C 2019-11-06 10:02:44.281441632 +0100 @@ -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 (); +}