From patchwork Fri Apr 8 16:32:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 608121 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 3qhQ4H3MJ6z9t57 for ; Sat, 9 Apr 2016 02:33:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=jTtdko7k; 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=t6a7Svz4YjNr khj0GRt8faBXeTB/Vqu2SZC6hNY6TTv1BeXI9KSN6viQgAk2nzuC7byk+nBTry6d rl0kve5TLn1UdRoshQ6FaWoIcATZXUTMEvknufUIYbbNNvI8HPrnYhBFS7xfOdRm s1cjqXb28CFtlYxBOAFgEEOa3kzgbAE= 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=T40UrPQ5ScU+4HDJv8 BtMVLMKeY=; b=jTtdko7kQfyhP0y/nsh7uAVCs9T4v7WqVMg/QJUFdLXxBpEZuQ 1Ewf3CY+FvmIhHbnQrVueuSETgqShiw5Npg48yP7IV8CU9DWWE5x+deSlA79NBBt 0SIdifcxzI/02BYNsxT9VW8UY5yjTErmGleaE7Wly1BW1+W/JKnqvE48A= Received: (qmail 61068 invoked by alias); 8 Apr 2016 16:32:54 -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 61049 invoked by uid 89); 8 Apr 2016 16:32:53 -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= X-HELO: mail-qk0-f171.google.com Received: from mail-qk0-f171.google.com (HELO mail-qk0-f171.google.com) (209.85.220.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 08 Apr 2016 16:32:43 +0000 Received: by mail-qk0-f171.google.com with SMTP id r184so46070998qkc.1 for ; Fri, 08 Apr 2016 09:32:43 -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=iE0tKJRYB1V/GXxBLm2FSgY/u0odhji7oMVY3t7FLzk=; b=jZB6TBzH1I9kkrzTNqeU/N+FWiRUiw27IWPzZIQrbU5iMv+Ri7gmYxcTmyxCSINWpX 899CyUrVgrsyXLtBxYuohoJ6w9w3Wth/06tvrwxsKxzchUVO1AlOkl+ARS+kd6OZE1gn yNnbOhbIrjQv7ixq+eqVyC1bmCQTQVLueizQnDDO13LEy7o4sm3puqVJfkd+cg0dK5ld Hm02rSfsfFLKJmVCDp6XR2FZW42FyMqrTrC8A35cETXfpiqsPviRAAI2KvHutNlCZvpu 7Hq8iNUe0GPYr9DSf4qEL5d8bdASxF7KZvJsE9HPW9s+ZU/7iBGFewZoQhV4UPJG4Z8N pOlQ== X-Gm-Message-State: AOPr4FXD5E3l3U31kbAk1ENexUnmwzV8omrngxZ5EHXXqIygqGAiJSdXCHaOTySHO4Jm6g== X-Received: by 10.55.215.216 with SMTP id t85mr857249qkt.63.1460133161243; Fri, 08 Apr 2016 09:32:41 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id h64sm5785388qgh.39.2016.04.08.09.32.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Apr 2016 09:32:40 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix PR c++/70590 (error: location references block not in block tree) Date: Fri, 8 Apr 2016 12:32:04 -0400 Message-Id: <1460133124-12178-1-git-send-email-patrick@parcs.ath.cx> My recent change that avoided needlessly unsharing expressions during constexpr evaluation introduced a regression. If we reuse the result of the same constexpr call from the constexpr_call_table in two separate caller functions then both functions will be sharing this reused tree in their function body. Because the trees are shared, the functions will clobber each other's assignments to the TREE_BLOCK of these trees. This eventually causes a verification ICE. To stop this from happening, we could always unshare the result tree of a constexpr call, as was previously done. But conceptually it seems better and perhaps safer to just unshare the final result of the entire constexpr evaluation. That's what this patch does. Either approach seems to fix the PR though. gcc/cp/ChangeLog: PR c++/70590 PR c++/70452 * constexpr.c (cxx_eval_outermost_expression): Call unshare_expr on the result if applicable. gcc/testsuite/ChangeLog: PR c++/70590 PR c++/70452 * g++.dg/pr70590.C: New test. * g++.dg/pr70590-2.C: New test. --- gcc/cp/constexpr.c | 9 +++++++++ gcc/testsuite/g++.dg/pr70590-2.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/pr70590.C | 25 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 gcc/testsuite/g++.dg/pr70590-2.C create mode 100644 gcc/testsuite/g++.dg/pr70590.C diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 7f4bb04..d84377b 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4172,6 +4172,12 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, if (!non_constant_p && overflow_p) non_constant_p = true; + /* Unshare the result unless it's a CONSTRUCTOR in which case it's already + unshared. */ + bool should_unshare = true; + if (r == t || TREE_CODE (r) == CONSTRUCTOR) + should_unshare = false; + if (non_constant_p && !allow_non_constant) return error_mark_node; else if (non_constant_p && TREE_CONSTANT (r)) @@ -4188,6 +4194,9 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, else if (non_constant_p || r == t) return t; + if (should_unshare) + r = unshare_expr (r); + if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r))) { if (TREE_CODE (t) == TARGET_EXPR diff --git a/gcc/testsuite/g++.dg/pr70590-2.C b/gcc/testsuite/g++.dg/pr70590-2.C new file mode 100644 index 0000000..409c86e --- /dev/null +++ b/gcc/testsuite/g++.dg/pr70590-2.C @@ -0,0 +1,21 @@ +// PR c++/70590 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +int a; + +constexpr int *foo = &a; + +void blah (int *); + +int +bar () +{ + blah (foo); +} + +int +baz () +{ + blah (foo); +} diff --git a/gcc/testsuite/g++.dg/pr70590.C b/gcc/testsuite/g++.dg/pr70590.C new file mode 100644 index 0000000..4886200 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr70590.C @@ -0,0 +1,25 @@ +// PR c++/70590 +// { dg-do compile { target c++11 } } +// { dg-options "-O2" } + +int a; + +constexpr int * +foo () +{ + return &a; +} + +void blah (int *); + +int +bar () +{ + blah (foo ()); +} + +int +baz () +{ + blah (foo ()); +}