From b925d25d7eeccf5a259f5c744b2de8d8285e0bc3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 16 Nov 2015 22:58:18 -0500 Subject: [PATCH] constexpr.c (cxx_eval_builtin_function_call): Use cp_fully_fold to fold arguments to __builtin_constant_p. * constexpr.c (cxx_eval_builtin_function_call): Use cp_fully_fold to fold arguments to __builtin_constant_p. From-SVN: r230453 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/constexpr.c | 14 ++++++++++--- gcc/cp/cp-gimplify.c | 20 +++++++------------ .../g++.dg/delayedfold/builtin-constant1.C | 7 +++++++ .../g++.dg/delayedfold/builtin-constant2.C | 13 ++++++++++++ 5 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/delayedfold/builtin-constant1.C create mode 100644 gcc/testsuite/g++.dg/delayedfold/builtin-constant2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7027d937acf..05b92528995 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2015-11-16 Jason Merrill + + * constexpr.c (cxx_eval_builtin_function_call): Use cp_fully_fold + to fold arguments to __builtin_constant_p. + 2015-11-16 Kirill Yukhin * parser.c (cp_parser_late_parsing_cilk_simd_fn_info): Look for diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index aabb9809154..459173dec07 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1014,7 +1014,9 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, int i; /* Don't fold __builtin_constant_p within a constexpr function. */ - if (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P + bool bi_const_p = (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P); + + if (bi_const_p && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) { @@ -1028,8 +1030,14 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, 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); + { + args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i), + lval, &dummy1, &dummy2); + if (bi_const_p) + /* For __built_in_constant_p, fold all expressions with constant values + even if they aren't C++ constant-expressions. */ + args[i] = cp_fully_fold (args[i]); + } bool save_ffbcp = force_folding_builtin_constant_p; force_folding_builtin_constant_p = true; diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 5f5cd367f58..8fe9e133407 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -2107,20 +2107,14 @@ cp_fold (tree x) int i, m, sv = optimize, nw = sv, changed = 0; tree callee = get_callee_fndecl (x); + /* Some built-in function calls will be evaluated at compile-time in + fold (). Set optimize to 1 when folding __builtin_constant_p inside + a constexpr function so that fold_builtin_1 doesn't fold it to 0. */ if (callee && DECL_BUILT_IN (callee) && !optimize && DECL_IS_BUILTIN_CONSTANT_P (callee) && current_function_decl && DECL_DECLARED_CONSTEXPR_P (current_function_decl)) nw = 1; - optimize = nw; - r = fold (x); - optimize = sv; - - if (TREE_CODE (r) != CALL_EXPR) - { - x = cp_fold (r); - break; - } x = copy_node (x); @@ -2145,11 +2139,11 @@ cp_fold (tree x) optimize = nw; - /* Invoke maybe_constant_value for functions being declared - constexpr, and are no AGGR_INIT_EXPRs ... + /* Invoke maybe_constant_value for functions declared + constexpr and not called with AGGR_INIT_EXPRs. TODO: - Due issues in maybe_constant_value for CALL_EXPR with - arguments passed by reference, it is disabled. */ + Do constexpr expansion of expressions where the call itself is not + constant, but the call followed by an INDIRECT_REF is. */ if (callee && DECL_DECLARED_CONSTEXPR_P (callee)) r = maybe_constant_value (x); optimize = sv; diff --git a/gcc/testsuite/g++.dg/delayedfold/builtin-constant1.C b/gcc/testsuite/g++.dg/delayedfold/builtin-constant1.C new file mode 100644 index 00000000000..56bcfc5e831 --- /dev/null +++ b/gcc/testsuite/g++.dg/delayedfold/builtin-constant1.C @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert ((X),#X) + +int i; + +SA(__builtin_constant_p (i == 42 && false)); diff --git a/gcc/testsuite/g++.dg/delayedfold/builtin-constant2.C b/gcc/testsuite/g++.dg/delayedfold/builtin-constant2.C new file mode 100644 index 00000000000..05fd2866614 --- /dev/null +++ b/gcc/testsuite/g++.dg/delayedfold/builtin-constant2.C @@ -0,0 +1,13 @@ +// { dg-do run } + +int i; + +#define CV(X) (__builtin_constant_p (X) ? (X) : -1) + +int ar[] = { CV (i == 42 && false) }; + +int main() +{ + if (ar[0] != 0) + __builtin_abort(); +} -- 2.30.2