diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-08-08 11:00:51 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-08-08 11:00:51 +0200 |
commit | e408261123697a82b5965c700fa2465999f0fd62 (patch) | |
tree | 22ed906d9f15d60555219787db1ca461460a6741 /gcc/testsuite | |
parent | 5e539332c47faa6d6df728d27fae5d02805ca5ec (diff) | |
download | gcc-e408261123697a82b5965c700fa2465999f0fd62.zip gcc-e408261123697a82b5965c700fa2465999f0fd62.tar.gz gcc-e408261123697a82b5965c700fa2465999f0fd62.tar.bz2 |
P0595R1 - is_constant_evaluated
P0595R1 - is_constant_evaluated
cp/
* cp-tree.h (enum cp_built_in_function): New.
(maybe_constant_init): Add pretend_const_required argument.
* typeck2.c (store_init_value): Pass true as new argument to
maybe_constant_init.
* constexpr.c (constexpr_fn_retval): Check also DECL_BUILT_IN_CLASS
for BUILT_IN_UNREACHABLE.
(struct constexpr_ctx): Add pretend_const_required field.
(cxx_eval_builtin_function_call): Use DECL_IS_BUILTIN_CONSTANT_P
macro. Handle CP_BUILT_IN_IS_CONSTANT_EVALUATED. Check also
DECL_BUILT_IN_CLASS for BUILT_IN_UNREACHABLE.
(cxx_eval_outermost_constant_expr): Add pretend_const_required
argument, initialize pretend_const_required field in ctx. If the
result is TREE_CONSTANT and non_constant_p, retry with
pretend_const_required false if it was true.
(is_sub_constant_expr): Initialize pretend_const_required_field in
ctx.
(cxx_constant_value): Pass true as pretend_const_required to
cxx_eval_outermost_constant_expr.
(maybe_constant_value): Pass false as pretend_const_required to
cxx_eval_outermost_constant_expr.
(fold_non_dependent_expr): Likewise.
(maybe_constant_init_1): Add pretend_const_required argument, pass it
down to cxx_eval_outermost_constant_expr. Pass !allow_non_constant
instead of false as strict to cxx_eval_outermost_constant_expr.
(maybe_constant_init): Add pretend_const_required argument, pass it
down to maybe_constant_init_1.
(cxx_constant_init): Pass true as pretend_const_required to
maybe_constant_init_1.
* cp-gimplify.c (cp_gimplify_expr): Handle CALL_EXPRs to
CP_BUILT_IN_IS_CONSTANT_EVALUATED.
(cp_fold): Don't fold CP_BUILT_IN_IS_CONSTANT_EVALUATED calls.
* decl.c: Include langhooks.h.
(cxx_init_decl_processing): Register __builtin_is_constant_evaluated
built-in.
* tree.c (builtin_valid_in_constant_expr_p): Return true for
CP_BUILT_IN_IS_CONSTANT_EVALUATED.
* pt.c (declare_integer_pack): Initialize DECL_FUNCTION_CODE.
testsuite/
* g++.dg/cpp2a/is-constant-evaluated1.C: New test.
From-SVN: r263392
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated1.C | 66 |
2 files changed, 69 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e614fed..c729af8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-08-08 Jakub Jelinek <jakub@redhat.com> + P0595R1 - is_constant_evaluated + * g++.dg/cpp2a/is-constant-evaluated1.C: New test. + PR c++/86836 * g++.dg/cpp1z/decomp46.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated1.C b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated1.C new file mode 100644 index 0000000..3b98884 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated1.C @@ -0,0 +1,66 @@ +// P0595R1 +// { dg-do compile { target c++14 } } + +template<int N> struct X { int v = N; }; +X<__builtin_is_constant_evaluated ()> x; // type X<true> +int y = 4; +int a = __builtin_is_constant_evaluated () ? y : 1; // initializes a to 1 +int b = __builtin_is_constant_evaluated () ? 2 : y; // initializes b to 2 +int c = y + (__builtin_is_constant_evaluated () ? 2 : y); // initializes c to 2*y +int d = __builtin_is_constant_evaluated (); // initializes d to 1 +int e = d + __builtin_is_constant_evaluated (); // initializes e to 0 + +struct false_type { static constexpr bool value = false; }; +struct true_type { static constexpr bool value = true; }; +template<class T, class U> +struct is_same : false_type {}; +template<class T> +struct is_same<T, T> : true_type {}; + +constexpr int +foo (int x) +{ + const int n = __builtin_is_constant_evaluated () ? 13 : 17; // n == 13 + int m = __builtin_is_constant_evaluated () ? 13 : 17; // m might be 13 or 17 (see below) + char arr[n] = {}; // char[13] + return m + sizeof (arr) + x; +} + +constexpr int +bar () +{ + const int n = __builtin_is_constant_evaluated() ? 13 : 17; + X<n> x1; + X<__builtin_is_constant_evaluated() ? 13 : 17> x2; + static_assert (is_same<decltype (x1), decltype (x2)>::value, "x1/x2's type"); + return x1.v + x2.v; +} + +int p = foo (0); // m == 13; initialized to 26 +int q = p + foo (0); // m == 17 for this call; initialized to 56 +static_assert (bar () == 26, "bar"); + +struct S { int a, b; }; + +S s = { __builtin_is_constant_evaluated () ? 2 : 3, y }; +S t = { __builtin_is_constant_evaluated () ? 2 : 3, 4 }; + +static_assert (is_same<decltype (x), X<true> >::value, "x's type"); + +int +main () +{ + if (a != 1 || b != 2 || c != 8 || d != 1 || e != 0 || p != 26 || q != 56) + __builtin_abort (); + if (s.a != 3 || s.b != 4 || t.a != 2 || t.b != 4) + __builtin_abort (); + if (foo (y) != 34) + __builtin_abort (); +#if __cplusplus >= 201703L + if constexpr (foo (0) != 26) + __builtin_abort (); +#endif + constexpr int w = foo (0); + if (w != 26) + __builtin_abort (); +} |