public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-6421] c++: constant non-copy-init is manifestly constant [PR108243]
@ 2023-03-02 19:05 Patrick Palka
0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2023-03-02 19:05 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:cbaa1d9c218d9c0b5e34e510a462ff4e299a0f3f
commit r13-6421-gcbaa1d9c218d9c0b5e34e510a462ff4e299a0f3f
Author: Patrick Palka <ppalka@redhat.com>
Date: Thu Mar 2 14:03:21 2023 -0500
c++: constant non-copy-init is manifestly constant [PR108243]
According to [basic.start.static]/2 and [expr.const]/2, a variable
with static storage duration initialized with a constant initializer
has constant initialization, and such an initializer is manifestly
constant-evaluated.
For copy initialization, we're already getting this right because in
that case check_initializer would consistently call store_init_value,
which for TREE_STATIC variables calls fold_non_dependent_init with
m_c_e=true.
But for direct (or default) initialization, check_initializer doesn't
always call store_init_value. We instead however always call
maybe_constant_init from expand_default_init[1], albeit with m_c_e=false
which means we don't get the "manifestly constant-evaluated" part right
for non-copy-init.
This patch fixes this by setting m_c_e=true in maybe_constant_init for
static storage duration variables, mainly for benefit of the call
to maybe_constant_init from expand_default_init.
[1]: this maybe_constant_init call isn't reached in the copy-init
case because there init is a CONSTRUCTOR rather than a TREE_LIST,
and so we exit early from expand_default_init, returning an INIT_EXPR.
This INIT_EXPR is ultimately what causes us to consistently hit the
store_init_value code path from check_initializer in the copy-init case.
PR c++/108243
gcc/cp/ChangeLog:
* constexpr.cc (maybe_constant_init_1): Override
manifestly_const_eval to true if is_static.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/is-constant-evaluated14.C: New test.
Diff:
---
gcc/cp/constexpr.cc | 2 +
.../g++.dg/cpp2a/is-constant-evaluated14.C | 140 +++++++++++++++++++++
2 files changed, 142 insertions(+)
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 0770cdcd768..acf9847a4d1 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8770,6 +8770,8 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
shouldn't bend the rules the same way for automatic variables. */
bool is_static = (decl && DECL_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
+ if (is_static)
+ manifestly_const_eval = true;
t = cxx_eval_outermost_constant_expr (t, allow_non_constant, !is_static,
mce_value (manifestly_const_eval),
false, decl);
diff --git a/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated14.C b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated14.C
new file mode 100644
index 00000000000..a41461f3604
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/is-constant-evaluated14.C
@@ -0,0 +1,140 @@
+// PR c++/108243
+// Verify a variable with static storage duration initialized with a
+// constant initializer has constant initialization, and the initializer
+// is manifestly constant-evaluated.
+// { dg-do run { target c++11 } }
+// { dg-additional-options "-fdump-tree-original" }
+
+// { dg-final { scan-tree-dump-not "static initializers for" "original" } }
+// { dg-final { scan-tree-dump-not "cxa_guard_acquire" "original" } }
+
+#include <initializer_list>
+
+struct A {
+ constexpr A(int n) : n(n), m(__builtin_is_constant_evaluated()) { }
+ constexpr A() : A(42) { }
+ void verify_mce() const {
+ if (m != 1) __builtin_abort();
+ }
+ int n;
+ int m;
+};
+
+A a1 = {42};
+A a2{42};
+A a3(42);
+A a4;
+A a5{};
+
+void f() {
+ static A a1 = {42};
+ static A a2{42};
+ static A a3(42);
+ static A a4;
+ static A a5{};
+ for (auto& a : {a1, a2, a3, a4, a5})
+ a.verify_mce();
+}
+
+template<int... N>
+void g() {
+ static A a1 = {42};
+ static A a2{42};
+ static A a3(42);
+ static A a4;
+ static A a5{};
+ static A a6 = {N...};
+ static A a7{N...};
+ static A a8(N...);
+ for (auto& a : {a1, a2, a3, a4, a5, a6, a7, a8})
+ a.verify_mce();
+}
+
+struct B {
+ static A a1;
+ static A a2;
+ static A a3;
+ static A a4;
+ static A a5;
+ static void verify_mce() {
+ for (auto& a : {a1, a2, a3, a4, a5})
+ a.verify_mce();
+ }
+};
+
+A B::a1 = {42};
+A B::a2{42};
+A B::a3(42);
+A B::a4;
+A B::a5{};
+
+template<int... N>
+struct BT {
+ static A a1;
+ static A a2;
+ static A a3;
+ static A a4;
+ static A a5;
+ static A a6;
+ static A a7;
+ static A a8;
+ static void verify_mce() {
+ for (auto& a : {a1, a2, a3, a4, a5})
+ a.verify_mce();
+ }
+};
+
+template<int... N> A BT<N...>::a1 = {42};
+template<int... N> A BT<N...>::a2{42};
+template<int... N> A BT<N...>::a3(42);
+template<int... N> A BT<N...>::a4;
+template<int... N> A BT<N...>::a5{};
+template<int... N> A BT<N...>::a6 = {N...};
+template<int... N> A BT<N...>::a7{N...};
+template<int... N> A BT<N...>::a8(N...);
+
+#if __cpp_inline_variables
+struct BI {
+ static inline A a1 = {42};
+ static inline A a2{42};
+ static inline A a3;
+ static inline A a4{};
+ static void verify_mce() {
+ for (auto& a : {a1, a2, a3, a4})
+ a.verify_mce();
+ }
+};
+
+template<int... N>
+struct BIT {
+ static inline A a1 = {42};
+ static inline A a2{42};
+ static inline A a3;
+ static inline A a4{};
+ static inline A a5 = {N...};
+ static inline A a6{N...};
+ static void verify_mce() {
+ for (auto& a : {a1, a2, a3, a4, a5, a6})
+ a.verify_mce();
+ }
+};
+#endif
+
+int main() {
+ for (auto& a : {a1, a2, a3, a4, a5})
+ a.verify_mce();
+
+ f();
+ g<42>();
+ g<>();
+
+ B::verify_mce();
+ BT<42>::verify_mce();
+ BT<>::verify_mce();
+
+#if __cpp_inline_variables
+ BI::verify_mce();
+ BIT<42>::verify_mce();
+ BIT<>::verify_mce();
+#endif
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-03-02 19:05 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-02 19:05 [gcc r13-6421] c++: constant non-copy-init is manifestly constant [PR108243] Patrick Palka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).