From patchwork Thu Apr 3 15:25:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 336658 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 1CAB614007C for ; Fri, 4 Apr 2014 02:25:28 +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:cc:subject:date:message-id; q=dns; s=default; b=p3TKn74GyW91 u53zoeXvLVu68yCxDULlCW82zNqgdzCQG4kVepoI036tnXuZs6GghSnqZdy38J3g gTKXAKYFEOhUd9gNtxBHVmOhZ+fW++KgaseRFGRTMp5LBSuwxVmZA/lgQOLiw0PR YV7kZUIX6uqOXOhDdkIql6FQz9kD5/E= 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=3lOh1O6XA7yLdDflx4 74QMhrsYE=; b=c9LTkK3AVqvbllj1w3BrD5ZSqyl0nLgPMmAEnCZSyEVifINLfP kkylmSndd+icTZgfCCSv0sGa08tXq276F4nVDx888KVZ7ffUJG/DdxSHXvaQIJxP AegRQCEnrl4TIPAIkK6iwlejM7nRjzUCqYAIYT+zmW3zrRTLr1DLAooxY= Received: (qmail 2128 invoked by alias); 3 Apr 2014 15:25:22 -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 2113 invoked by uid 89); 3 Apr 2014 15:25:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-HELO: mail-qg0-f49.google.com Received: from mail-qg0-f49.google.com (HELO mail-qg0-f49.google.com) (209.85.192.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 03 Apr 2014 15:25:20 +0000 Received: by mail-qg0-f49.google.com with SMTP id j107so558583qga.8 for ; Thu, 03 Apr 2014 08:25:18 -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=Y7wKMrPcqlIcQTWRFYfLoIaO/35WNjV/rWvM5gQYn2o=; b=ZoY3LaZjCILZ+ESgC/4i/vp+N73u+H9p1dTMqwefV67cWmUj7O0UcA1Y0iGKOeVRHd If5SrWrKW8fSe7C0pHjWf6N9KMBgfriGmodGcUkcACsWnDdzXGwwcTlJbwLGPcdijpNA 8mftgoqUhRGxxe1kGEqKPtc93b452DOyi6l1m+UDIT2ZeYh8dZczsYwfG+ClcIGIJFwL 6kU3n5RNCECKvURzSbiDpWy5Q57od2Q745BtsHTkgL9MI6xy6+kOw/tgTNxZ3ELMzqtm FNPI5Efe8/1O8fEh8tsuF6JCnjAfuLK8H57guhLzg1sRxWTs7qMcJdDZujI06ImfIEMq Py4A== X-Gm-Message-State: ALoCoQm5xIvSrJXEWGeyGJ1brSHU4DhrgGhkyU6hFptsKOkzAPC1uQy1JWUayXC6lRXStAt4kBQB X-Received: by 10.224.104.1 with SMTP id m1mr7945782qao.51.1396538718146; Thu, 03 Apr 2014 08:25:18 -0700 (PDT) Received: from localhost.localdomain (ool-4353a9c4.dyn.optonline.net. [67.83.169.196]) by mx.google.com with ESMTPSA id c61sm3296713qgf.15.2014.04.03.08.25.16 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 Apr 2014 08:25:17 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix PR c++/44613 Date: Thu, 3 Apr 2014 11:25:09 -0400 Message-Id: <1396538709-31519-1-git-send-email-patrick@parcs.ath.cx> Hi, This patch fixes a wrong code issue in the code generated for VLAs in the C++ frontend. This exact issue was fixed in the C frontend with r85849, and this patch is essentially a port of r85849 for the C++ frontend. The issue is that this C++ code: { foo: int x[n]; f (); } gets gimplified into this: { int x[n]; void *saved_stack; saved_stack = __builtin_stack_save (); try { foo: // <-- jump to foo will bypass initialization of saved_stack x = alloca (...); f (); } finally { __builtin_stack_restore (saved_stack); } } In order to ensure that labels such as "foo" that occur before the initialization of a VLA are emitted in the right place by the gimplifier, the C++ frontend is changed to handle the above C++ code as if it looked like this: { foo: { int x[n]; f (); } } thereby forcing the label "foo" to be placed before the initialization of saved_stack during gimplification. This is the same approach that the C frontend uses (see r85849). I bootstrapped and regtested this patch on x86_64-unknown-linux-gnu. 2014-04-03 Patrick Palka PR c++/44613 * semantics.c (add_stmt): Set STATEMENT_LIST_HAS_LABEL. * decl.c (cp_finish_decl): Create a new BIND_EXPR before instantiating a variable-sized type. --- gcc/cp/decl.c | 19 ++++++++++++++++++- gcc/cp/semantics.c | 3 +++ gcc/testsuite/g++.dg/ext/vla15.C | 20 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ext/vla15.C diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f3a081b..5bd33c5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6441,7 +6441,24 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, after the call to check_initializer so that the DECL_EXPR for a reference temp is added before the DECL_EXPR for the reference itself. */ if (DECL_FUNCTION_SCOPE_P (decl)) - add_decl_expr (decl); + { + /* If we're building a variable sized type, and we might be + reachable other than via the top of the current binding + level, then create a new BIND_EXPR so that we deallocate + the object at the right time. */ + if (VAR_P (decl) + && DECL_SIZE (decl) + && !TREE_CONSTANT (DECL_SIZE (decl)) + && STATEMENT_LIST_HAS_LABEL (cur_stmt_list)) + { + tree bind; + bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + BIND_EXPR_BODY (bind) = push_stmt_list (); + } + add_decl_expr (decl); + } /* Let the middle end know about variables and functions -- but not static data members in uninstantiated class templates. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fb1e404..b00294e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -386,6 +386,9 @@ add_stmt (tree t) STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); } + if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) + STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; + /* Add T to the statement-tree. Non-side-effect statements need to be recorded during statement expressions. */ gcc_checking_assert (!stmt_list_stack->is_empty ()); diff --git a/gcc/testsuite/g++.dg/ext/vla15.C b/gcc/testsuite/g++.dg/ext/vla15.C new file mode 100644 index 0000000..feeb49f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla15.C @@ -0,0 +1,20 @@ +// PR c++/44613 +// { dg-do run } +// { dg-options "" } + +void *volatile p; + +int +main (void) +{ + int n = 0; + lab:; + int x[n % 1000 + 1]; + x[0] = 1; + x[n % 1000] = 2; + p = x; + n++; + if (n < 1000000) + goto lab; + return 0; +}