Skip to content

Commit 98febda

Browse files
jasonhjl-tools
authored andcommitted
Fix C++ __builtin_constant_p
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 gcc-mirror#2. gcc/cp/ Backport from mainline 2015-04-28 Jason Merrill <[email protected]> PR c++/65656 * constexpr.c (cxx_eval_builtin_function_call): Fix __builtin_constant_p. gcc/testsuite/ Backport from mainline 2015-04-28 Jason Merrill <[email protected]> PR c++/65656 * g++.dg/cpp0x/constexpr-builtin3.C: New test.
1 parent 440dcd8 commit 98febda

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

gcc/cp/constexpr.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,26 +1024,38 @@ lookup_parameter_binding (const constexpr_call *call, tree t)
10241024
represented by _CST nodes. */
10251025

10261026
static tree
1027-
cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
1027+
cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
10281028
bool lval,
10291029
bool *non_constant_p, bool *overflow_p)
10301030
{
10311031
const int nargs = call_expr_nargs (t);
10321032
tree *args = (tree *) alloca (nargs * sizeof (tree));
10331033
tree new_call;
10341034
int i;
1035-
for (i = 0; i < nargs; ++i)
1035+
1036+
/* Don't fold __builtin_constant_p within a constexpr function. */
1037+
if (DECL_FUNCTION_CODE (fun) == BUILT_IN_CONSTANT_P
1038+
&& current_function_decl
1039+
&& DECL_DECLARED_CONSTEXPR_P (current_function_decl))
10361040
{
1037-
args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i),
1038-
lval,
1039-
non_constant_p, overflow_p);
1040-
if (ctx->quiet && *non_constant_p)
1041-
return t;
1041+
*non_constant_p = true;
1042+
return t;
10421043
}
1043-
if (*non_constant_p)
1044-
return t;
1044+
1045+
/* Be permissive for arguments to built-ins; __builtin_constant_p should
1046+
return constant false for a non-constant argument. */
1047+
constexpr_ctx new_ctx = *ctx;
1048+
new_ctx.quiet = true;
1049+
bool dummy1 = false, dummy2 = false;
1050+
for (i = 0; i < nargs; ++i)
1051+
args[i] = cxx_eval_constant_expression (&new_ctx, CALL_EXPR_ARG (t, i),
1052+
lval, &dummy1, &dummy2);
1053+
1054+
bool save_ffbcp = force_folding_builtin_constant_p;
1055+
force_folding_builtin_constant_p = true;
10451056
new_call = fold_build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
10461057
CALL_EXPR_FN (t), nargs, args);
1058+
force_folding_builtin_constant_p = save_ffbcp;
10471059
VERIFY_CONSTANT (new_call);
10481060
return new_call;
10491061
}
@@ -1226,7 +1238,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
12261238
return void_node;
12271239

12281240
if (is_builtin_fn (fun))
1229-
return cxx_eval_builtin_function_call (ctx, t,
1241+
return cxx_eval_builtin_function_call (ctx, t, fun,
12301242
lval, non_constant_p, overflow_p);
12311243
if (!DECL_DECLARED_CONSTEXPR_P (fun))
12321244
{
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// PR c++/65656
2+
// { dg-options "-std=c++11 -O" }
3+
4+
int main(int argc, char *argv[]) {
5+
constexpr bool x = __builtin_constant_p(argc);
6+
}

0 commit comments

Comments
 (0)