aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-04-28 10:43:59 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-04-28 10:43:59 -0400
commit5756d0f9319b7f40051d1d2554243a766589b0bf (patch)
treebe21bc0a2110469833777eb9e1e80cb8e57cea20 /gcc
parentb71983a5baee2fd3b87233477eee7db4b5172bee (diff)
downloadgcc-5756d0f9319b7f40051d1d2554243a766589b0bf.zip
gcc-5756d0f9319b7f40051d1d2554243a766589b0bf.tar.gz
gcc-5756d0f9319b7f40051d1d2554243a766589b0bf.tar.bz2
re PR c++/65656 (__builtin_constant_p should always be constexpr)
PR c++/65656 * constexpr.c (cxx_eval_builtin_function_call): Fix __builtin_constant_p. From-SVN: r222531
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/constexpr.c32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-builtin3.C6
3 files changed, 32 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 73d55b9..acf4d49 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2015-04-28 Jason Merrill <jason@redhat.com>
+ PR c++/65656
+ * constexpr.c (cxx_eval_builtin_function_call): Fix
+ __builtin_constant_p.
+
PR c++/50800
* tree.c (strip_typedefs): Add remove_attributes parm.
(strip_typedefs_expr): Likewise.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 6465677..403c7cf 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1014,7 +1014,7 @@ get_nth_callarg (tree t, int n)
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)
{
@@ -1022,18 +1022,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;
}
@@ -1200,7 +1212,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);
+}