From patchwork Sat Aug 29 10:14:10 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Trippelsdorf X-Patchwork-Id: 512131 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 12D5C1401AF for ; Sat, 29 Aug 2015 20:14:24 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=LAEoNvFo; 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=gAbKQEqyPyQg4tS09 Ci1py2L3zwi/hrCW0Xg3z3X+66Jd/i9Bye/GoY8vAgEKa/suOxghrM95+EOcwboD +A0Q3axf53Eo4vY/u+78KTSzsSZu33E78Xn/u4CBac2AWnKxdtl1VVfZ8LEVBO8B BfQR3hpcbMJsNoqDKYOOLnSGrc= 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:references:mime-version :content-type:in-reply-to; s=default; bh=sl96kbhNU2cMuMXCTnNz2MP GwMM=; b=LAEoNvFoxogiVLuTdZWi4B8Zo35RjxoliMktNh6qZVmW6GJm+rT/L0g yfcDzpVQlsBk7r28S6zrl5MTQRDc1wSTwBNmV0JAG8WdnA8VuLmh2rqliK7CFtfD E+94OzEYUvIKHfXR5eCbnQzyLrA9f2ZEJ7PApxk0esisijCJXBys= Received: (qmail 54302 invoked by alias); 29 Aug 2015 10:14:17 -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 54277 invoked by uid 89); 29 Aug 2015 10:14:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.5 required=5.0 tests=AWL, BAYES_00, KAM_MXURI, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS autolearn=no version=3.3.2 X-HELO: mail.ud10.udmedia.de Received: from ud10.udmedia.de (HELO mail.ud10.udmedia.de) (194.117.254.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sat, 29 Aug 2015 10:14:14 +0000 Received: (qmail 28156 invoked from network); 29 Aug 2015 12:14:10 +0200 Received: from ip5b41f88a.dynamic.kabel-deutschland.de (HELO x4) (ud10?360p3@91.65.248.138) by mail.ud10.udmedia.de with ESMTPSA (ECDHE-RSA-AES256-SHA encrypted, authenticated); 29 Aug 2015 12:14:10 +0200 Date: Sat, 29 Aug 2015 12:14:10 +0200 From: Markus Trippelsdorf To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH v2] Fix c++/67371 (issues with throw in constexpr) Message-ID: <20150829101410.GA421@x4> References: <20150828120003.GA421@x4> <55E117BB.7080609@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <55E117BB.7080609@redhat.com> On 2015.08.28 at 22:23 -0400, Jason Merrill wrote: > On 08/28/2015 08:00 AM, Markus Trippelsdorf wrote: > > As PR67371 shows gcc currently rejects all throw statements in > > constant-expressions, even when they are never executed. > > > > Fix by simply allowing THROW_EXPR in potential_constant_expression_1. > > > > One drawback is that we now accept some ill formed cases, but they > > fall under the "no diagnostic required" rule in the standard, e.g.: > > I think we can do better. > > The handling of IF_STMT in potential_constant_expression_1 currently > returns false if either the then or the else clauses are problematic, > but instead it should return true if either of them are OK (or empty). > > We could try to analyze the body of a SWITCH_STMT more closely, but if > you don't want to try it's fine if we just assume that the body is OK. Ok. Thank you for the suggestions. I've tested the patch below on ppc64le. OK for trunk? Thanks. PR c++/67371 * constexpr.c (potential_constant_expression_1): Guard THEN_CLAUSE and ELSE_CLAUSE checking. Remove SWITCH_STMT body checking. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 1eacb8be9a44..29a7f1f22169 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4276,10 +4276,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case IF_STMT: if (!RECUR (IF_COND (t), rval)) return false; - if (!RECUR (THEN_CLAUSE (t), any)) - return false; - if (!RECUR (ELSE_CLAUSE (t), any)) - return false; + if (integer_nonzerop (IF_COND (t)) && !RECUR (THEN_CLAUSE (t), any)) + return false; + if (integer_zerop (IF_COND (t)) && !RECUR (ELSE_CLAUSE (t), any)) + return false; return true; case DO_STMT: @@ -4310,8 +4310,6 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case SWITCH_STMT: if (!RECUR (SWITCH_STMT_COND (t), rval)) return false; - if (!RECUR (SWITCH_STMT_BODY (t), any)) - return false; return true; case STMT_EXPR: diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C new file mode 100644 index 000000000000..7241fefc41e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++14 } } + +constexpr int *f4(bool b) { + if (b) { + return nullptr; + } else { + return new int{42}; // { dg-error "call to non-constexpr" } + } +} +static_assert(f4(true) == nullptr, ""); +static_assert(f4(false) == nullptr, ""); // { dg-error "non-constant condition" } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C new file mode 100644 index 000000000000..ac90051d5e99 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-throw.C @@ -0,0 +1,34 @@ +// { dg-do compile { target c++14 } } + +constexpr void f1() { + if (false) + throw; +} + +constexpr void f2() { + if (true) + throw; +} // { dg-error "not a constant-expression" } + +constexpr void f3() { + if (false) + ; + else + throw; +}// { dg-error "not a constant-expression" } + +constexpr void f4() { + throw; +}// { dg-error "not a constant-expression" } + +constexpr int fun(int n) { + switch (n) { + case 0: + return 1; + default: + throw; // { dg-error "not a constant-expression" } + } +} + +static_assert(fun(0), ""); +static_assert(fun(1), ""); // { dg-error "non-constant" }