From patchwork Mon Nov 18 10:06:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 292006 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 551FF2C00AD for ; Mon, 18 Nov 2013 21:09:44 +1100 (EST) 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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=ospHnwFXT0zeIaiq ewgNew+n3CYrTEtW3RObrVBdmxG5fwyBqyQzuBwRBY9LSG+k0/R48gL/osBGpdcf Zmyxzv0fisbnENqbk+AJ4PT1nL5nPFkxVArYsa88BVnwz4H8LDeerVe6LKnTt+UJ XaA+emYYC2sCfjNlGxBza2qQ2TI= 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:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=elRcqTZCcwdoyzAPWcrNfK rKLjM=; b=nkQsBf4Bu3J5J8cN7bNqGZGkNhgAQgvx2fepBXOCY1Blzn94IlzTuo RT15zMtufaAq9Jb5WqslKnqT4ZtqKO6aLLDzlGxg/fdRmLpRtt4+wUYls3Alerbo OLCC9ND1XNeEaNzRL/prerF6o6q0zWBRJW/uan8jOCKPfjJuwmtkI= Received: (qmail 23954 invoked by alias); 18 Nov 2013 10:09:35 -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 23914 invoked by uid 89); 18 Nov 2013 10:09:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_50, RDNS_NONE, URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from Unknown (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 18 Nov 2013 10:09:33 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 0841E26A5F8D for ; Mon, 18 Nov 2013 11:09:25 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OOsfBlWPrP8q for ; Mon, 18 Nov 2013 11:09:24 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id D0B7526A5F4B for ; Mon, 18 Nov 2013 11:09:24 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Fix unexpected read of volatile scalar for Out parameter Date: Mon, 18 Nov 2013 11:06:42 +0100 Message-ID: <8499959.3HNmPuMVWn@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 This fixes an old issue in the compiler, whereby it unexpectedly generates a read of a volatile variable with scalar type passed as Out parameter to a subprogram; the subtlety being that the side-effects of the parameter viewed as a name still need to be evaluated prior to the call. Tested on x86_64-suse-linux, applied on the mainline. 2013-11-18 Eric Botcazou * gcc-interface/trans.c (Call_to_gnu): For an Out parameter passed by copy and that don't need to be copied in, only evaluate its address. 2013-11-18 Eric Botcazou * gnat.dg/volatile11.adb: New test. * gnat.dg/volatile11_pkg.ad[sb]: New helper. Index: gcc-interface/trans.c =================================================================== --- gcc-interface/trans.c (revision 204913) +++ gcc-interface/trans.c (working copy) @@ -4130,9 +4130,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gn gnu_name = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_name))), gnu_name); - /* If we have not saved a GCC object for the formal, it means it is an - Out parameter not passed by reference and that need not be copied in. - Otherwise, first see if the parameter is passed by reference. */ + /* First see if the parameter is passed by reference. */ if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal)) { if (Ekind (gnat_formal) != E_In_Parameter) @@ -4178,6 +4176,9 @@ Call_to_gnu (Node_Id gnat_node, tree *gn gnu_formal_type = TREE_TYPE (gnu_formal); gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } + + /* Then see if the parameter is an array passed to a foreign convention + subprogram. */ else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal)) { gnu_formal_type = TREE_TYPE (gnu_formal); @@ -4198,6 +4199,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gn but this is the most likely to work in all cases. */ gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } + + /* Then see if the parameter is passed by descriptor. */ else if (is_true_formal_parm && DECL_BY_DESCRIPTOR_P (gnu_formal)) { gnu_actual = convert (gnu_formal_type, gnu_actual); @@ -4214,6 +4217,8 @@ Call_to_gnu (Node_Id gnat_node, tree *gn (TREE_TYPE (TREE_TYPE (gnu_formal)), gnu_actual, gnat_actual)); } + + /* Otherwise the parameter is passed by copy. */ else { tree gnu_size; @@ -4221,11 +4226,18 @@ Call_to_gnu (Node_Id gnat_node, tree *gn if (Ekind (gnat_formal) != E_In_Parameter) gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list); + /* If we didn't create a PARM_DECL for the formal, this means that + it is an Out parameter not passed by reference and that need not + be copied in. In this case, the value of the actual need not be + read. However, we still need to make sure that its side-effects + are evaluated before the call, so we evaluate its address. */ if (!is_true_formal_parm) { - /* Make sure side-effects are evaluated before the call. */ if (TREE_SIDE_EFFECTS (gnu_name)) - append_to_statement_list (gnu_name, &gnu_stmt_list); + { + tree addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_name); + append_to_statement_list (addr, &gnu_stmt_list); + } continue; }