From patchwork Thu Jan 21 20:24:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 571331 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 EECB11402D9 for ; Fri, 22 Jan 2016 07:25:11 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=HlDKWiiY; 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:reply-to:mime-version :content-type; q=dns; s=default; b=HLy7JxtfsW3VmqWL0wav+FISSeYak CP9yLg5PKnwCERvLA5fuxwErbjZgYlWVkLhkSnvpluwN+YVV8K6MEObKVpLjFYlq h4+TG4d3zAtbXOpTdClcwjtIblai2mi5QPdDhBDF6xK2c8QuBkq8SpfH6IlIVZ5A zkR10jl8tIcebE= 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:reply-to:mime-version :content-type; s=default; bh=8kcBmdA6GMjw53r/XRaFEPDmnh0=; b=HlD KWiiYqFU5wI5zTDfX5XflMmBNKkJ6iaLkHCbznu2puCkNiU1L++WL4ICB5J+gIE0 3nojnVH/ZGv6CGtFCfileNV9W64NUvpHQPua9uHAZXdv7BQkSgkKEvJz0PeUmilM XSGqBBQ5AwSscWmTj3YuU8vi5na8o7b3BMqdCp3U= Received: (qmail 81865 invoked by alias); 21 Jan 2016 20:25:01 -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 81843 invoked by uid 89); 21 Jan 2016 20:25:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.7 required=5.0 tests=BAYES_00, BIGNUM_EMAILS, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=desires, sk:fold_bu, CALL_EXPR_ARG, call_expr_arg X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (134.134.136.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 21 Jan 2016 20:25:00 +0000 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP; 21 Jan 2016 12:24:47 -0800 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([172.25.70.52]) by fmsmga004.fm.intel.com with ESMTP; 21 Jan 2016 12:24:47 -0800 Received: by gnu-6.sc.intel.com (Postfix, from userid 1000) id 310A6200B1E; Thu, 21 Jan 2016 12:24:47 -0800 (PST) Date: Thu, 21 Jan 2016 12:24:47 -0800 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: Jason Merrill Subject: [gcc-5-branch] [PATCH] Fix C++ __builtin_constant_p Message-ID: <20160121202447.GA5618@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) wide-int.h has /* For fixed-precision integers like offset_int and widest_int, handle the case where the shift value is constant and the result is a single nonnegative HWI (meaning that we don't need to worry about val[1]). This is particularly common for converting a byte count to a bit count. For variable-precision integers like wide_int, handle HWI and sub-HWI integers inline. */ if (__builtin_constant_p (xi.precision > HOST_BITS_PER_WIDE_INT) ? (__builtin_constant_p (shift < HOST_BITS_PER_WIDE_INT - 1) && xi.len == 1 && xi.val[0] <= (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) HOST_WIDE_INT_MAX >> shift)) : precision <= HOST_BITS_PER_WIDE_INT) { val[0] = xi.ulow () << shift; result.set_len (1); } __builtin_constant_p is miscompiled due to PR c++/65656, which leads to PR 69399. Backport the PR c++/65656 fix to gcc-5-branch fixes PR 69399. OK for gcc-5-branch if there is no regression on x86-64? Thanks. H.J. --- We have two desires for interaction of __builtin_constant_p with constexpr: 1) it should be a constant-expression even if its operands are not, and 2) we shouldn't fold it to false prematurely when parsing a constexpr function (c++/54021). We were having trouble with both of these, and this patch fixes #1 without breaking #2. gcc/cp/ Backport from mainline 2015-04-28 Jason Merrill PR c++/65656 * constexpr.c (cxx_eval_builtin_function_call): Fix __builtin_constant_p. gcc/testsuite/ Backport from mainline 2015-04-28 Jason Merrill PR c++/65656 * g++.dg/cpp0x/constexpr-builtin3.C: New test. --- gcc/cp/constexpr.c | 32 +++++++++++++++++-------- gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C | 6 +++++ 2 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4ca99e8..3c9362e 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1024,7 +1024,7 @@ lookup_parameter_binding (const constexpr_call *call, tree t) represented by _CST nodes. */ static tree -cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, +cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, bool lval, bool *non_constant_p, bool *overflow_p) { @@ -1032,18 +1032,30 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree *args = (tree *) alloca (nargs * sizeof (tree)); tree new_call; int i; - for (i = 0; i < nargs; ++i) + + /* Don't fold __builtin_constant_p within a constexpr function. */ + if (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P + && current_function_decl + && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) { - args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i), - lval, - non_constant_p, overflow_p); - if (ctx->quiet && *non_constant_p) - return t; + *non_constant_p = true; + return t; } - if (*non_constant_p) - return t; + + /* Be permissive for arguments to built-ins; __builtin_constant_p should + return constant false for a non-constant argument. */ + constexpr_ctx new_ctx = *ctx; + new_ctx.quiet = true; + bool dummy1 = false, dummy2 = false; + for (i = 0; i < nargs; ++i) + args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i), + lval, &dummy1, &dummy2); + + bool save_ffbcp = force_folding_builtin_constant_p; + force_folding_builtin_constant_p = true; new_call = fold_build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t), CALL_EXPR_FN (t), nargs, args); + force_folding_builtin_constant_p = save_ffbcp; VERIFY_CONSTANT (new_call); return new_call; } @@ -1226,7 +1238,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, return void_node; if (is_builtin_fn (fun)) - return cxx_eval_builtin_function_call (ctx, t, + return cxx_eval_builtin_function_call (ctx, t, fun, lval, non_constant_p, overflow_p); if (!DECL_DECLARED_CONSTEXPR_P (fun)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C new file mode 100644 index 0000000..3582525 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C @@ -0,0 +1,6 @@ +// PR c++/65656 +// { dg-options "-std=c++11 -O" } + +int main(int argc, char *argv[]) { + constexpr bool x = __builtin_constant_p(argc); +}