From patchwork Mon Mar 21 22:35:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 600367 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3qTVz80lxXz9s2k for ; Tue, 22 Mar 2016 09:35:47 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=wjlYT64Q; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=VGYw7L2TUV3I nBLpG0F3yWlxR3QfIgTkaby5cAbFZaTvdIxKfgMi34brqv01h6OT5rNYAJ566gl8 sTsYfYBBIubYXSWIq7w+IzVQ2uRbeS0Xifo655qFNaBQmnrNivHazLR2M3zJATY/ lnWgbOYH7cOmq8Sk9Wb8fhT8a1RsLD4= 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:from :to:cc:subject:date:message-id; s=default; bh=32aXrv1m15vp0vJdgD DDFPWbzWk=; b=wjlYT64QpqqxTHzAXfmobE19oHmzYCYznBYsCCa79i22VZkzBL bdqRJiIrqaeA5IkQPd7flsBMJrGNkaci6O+3+JXpG+590OJQFH1ylmtbM4inHyDc FF66/pdYBXgpyRUfFgerm0wy/l5+hQfidCTjSoz2jrfSaWGZC4x4CNeGQ= Received: (qmail 56707 invoked by alias); 21 Mar 2016 22:35:39 -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 56693 invoked by uid 89); 21 Mar 2016 22:35:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=UD:inst X-HELO: mail-qg0-f50.google.com Received: from mail-qg0-f50.google.com (HELO mail-qg0-f50.google.com) (209.85.192.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 21 Mar 2016 22:35:37 +0000 Received: by mail-qg0-f50.google.com with SMTP id w104so164690498qge.1 for ; Mon, 21 Mar 2016 15:35:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ZkcSD/jDE74X3BX3+h9iAwfKlvjwfyUufGe8yN3xeJA=; b=N8rq44CZGPWsU2CawZQPft1QnU7P6s1GfZ6Ooh37SIffC3HiQOCfOzsB6jf7/ucRmz yPfKer0T9REavnV8bhPS0vR7tD2hht5qc0tEt0Iy6izA9hljRO6Ng0ararDz4pdVjyvQ FBcSzDy6qRh+3ZlSpZn4/95//DjPA9WbYRzfKB3PhlHR6MFkSXPO9BolaOugZfYPShdH OdmIlUkUXMS6XelN+v5iR8ZHT/Knu/fiuTO6uljJQXWE3kuN8fjgDLOyGIuPteuX/tvv mWroinGkx47pyH+E5HUo7yZLCO2de0ciR75grZygseoDruNfZdicGVayXYt6SccYoGar 46+A== X-Gm-Message-State: AD7BkJIWVYm/ZuiKHWaosHkaB5u7MLoMeIKdvmhKn4UQkc2i4sVHPLOS/qS5WF/wwi3o+w== X-Received: by 10.140.252.197 with SMTP id x188mr45704526qhc.81.1458599734993; Mon, 21 Mar 2016 15:35:34 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id a66sm13228195qkb.20.2016.03.21.15.35.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 21 Mar 2016 15:35:34 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix PR c++/70096 (wrong code for pointer-to-member-function copy) Date: Mon, 21 Mar 2016 18:35:26 -0400 Message-Id: <1458599726-11471-1-git-send-email-patrick@parcs.ath.cx> Given template void foo () { T A::*fptr; } We don't know whether fptr is a pointer-to-member-function or a pointer-to-data-member until we know what T is. But until then, fptr gets the type OFFSET_TYPE. If we later instantiate foo with e.g. T = void() then we know that fptr is a pointer-to-member-function and so we give the specialized copy of fptr a type which satisfies TYPE_PTRMEMFUNC_P (some RECORD_TYPE). The placeholder OFFSET_TYPE and the resulting RECORD_TYPE however have different sizes and modes (DI vs TI on x86_64), but the DECL_MODE of the specialized copy of fptr never gets updated accordingly. This stale DECL_MODE eventually leads the backend to miscompile copies to and from fptr. [ Some more analysis at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70096#c4 ] This patch makes tsubst_decl clear the DECL_MODE of the new decl so that the subsequent call to layout_type can update it accordingly. Tested on x86_64-pc-linux-gnu. Does this patch look OK to commit? gcc/cp/ChangeLog: PR c++/70096 * pt.c (tsubst_decl): Clear the DECL_MODE of the new decl. gcc/testsuite/ChangeLog: PR c++/70096 * g++.dg/template/ptrmem30.C: New test. --- gcc/cp/pt.c | 2 ++ gcc/testsuite/g++.dg/template/ptrmem30.C | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/ptrmem30.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f9c5b0b..ebfc45b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12374,6 +12374,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* The initializer must not be expanded until it is required; see [temp.inst]. */ DECL_INITIAL (r) = NULL_TREE; + if (VAR_P (r)) + DECL_MODE (r) = VOIDmode; if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL)) SET_DECL_RTL (r, NULL); DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0; diff --git a/gcc/testsuite/g++.dg/template/ptrmem30.C b/gcc/testsuite/g++.dg/template/ptrmem30.C new file mode 100644 index 0000000..923238b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem30.C @@ -0,0 +1,45 @@ +// PR c++/70096 +// { dg-do run } + +int read; + +struct Holder +{ + void foo () { read = data; } + int data; +}; + +void +poison_stack () +{ + volatile char a[256]; + __builtin_memset ((void *)a, 0xa, sizeof a); +} + +template +void test1 () +{ + Holder h; + h.data = 42; + F Holder::*fptr = &Holder::foo; + (h.*fptr)(); +} + +template +void test2 () +{ + Holder h; + h.data = 42; + F Holder::*fptr1 = &Holder::foo; + F Holder::*fptr2 = fptr1; + (h.*fptr2)(); +} + + +int main () +{ + poison_stack (); + test1(); + poison_stack (); + test2(); +}