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).