aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-08-08 11:00:51 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-08-08 11:00:51 +0200
commite408261123697a82b5965c700fa2465999f0fd62 (patch)
tree22ed906d9f15d60555219787db1ca461460a6741 /gcc/testsuite
parent5e539332c47faa6d6df728d27fae5d02805ca5ec (diff)
downloadgcc-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/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated1.C66
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 ();
+}