]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add std::to_underlying to the set of stdlib functions that are always folded
authorVille Voutilainen <ville.voutilainen@gmail.com>
Mon, 12 May 2025 20:16:46 +0000 (23:16 +0300)
committerVille Voutilainen <ville.voutilainen@gmail.com>
Wed, 14 May 2025 08:27:38 +0000 (11:27 +0300)
gcc/cp/ChangeLog:
* cp-gimplify.cc (cp_fold): Add to_underlying.

gcc/testsuite/ChangeLog:
* g++.dg/opt/pr96780_cpp23.C: New.

libstdc++-v3/ChangeLog:
* include/std/utility (to_underlying): Add the __always_inline__ attribute.

Signed-off-by: Ville Voutilainen <ville.voutilainen@gmail.com>
gcc/cp/cp-gimplify.cc
gcc/testsuite/g++.dg/opt/pr96780_cpp23.C [new file with mode: 0644]
libstdc++-v3/include/std/utility

index d2423fd1848a69bbb9204db7fac04acf35b7151a..4e5d383daeb6e3928053e057ebac5cac902688d3 100644 (file)
@@ -3343,19 +3343,16 @@ cp_fold (tree x, fold_flags_t flags)
                || id_equal (DECL_NAME (callee), "addressof")
                /* This addressof equivalent is used heavily in libstdc++.  */
                || id_equal (DECL_NAME (callee), "__addressof")
+               || id_equal (DECL_NAME (callee), "to_underlying")
                || id_equal (DECL_NAME (callee), "as_const")))
          {
            r = CALL_EXPR_ARG (x, 0);
            /* Check that the return and argument types are sane before
               folding.  */
-           if (INDIRECT_TYPE_P (TREE_TYPE (x))
-               && INDIRECT_TYPE_P (TREE_TYPE (r)))
-             {
-               if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r)))
-                 r = build_nop (TREE_TYPE (x), r);
-               x = cp_fold (r, flags);
-               break;
-             }
+           if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r)))
+             r = build_nop (TREE_TYPE (x), r);
+           x = cp_fold (r, flags);
+           break;
          }
 
        int sv = optimize, nw = sv;
diff --git a/gcc/testsuite/g++.dg/opt/pr96780_cpp23.C b/gcc/testsuite/g++.dg/opt/pr96780_cpp23.C
new file mode 100644 (file)
index 0000000..ba4a837
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/96780
+// Verify calls to std::move/forward are folded away by the frontend.
+// { dg-do compile { target c++23 } }
+// { dg-additional-options "-ffold-simple-inlines -fdump-tree-gimple" }
+
+#include <utility>
+
+enum class A : char {a};
+
+extern A& x;
+
+void f() {
+  auto&& x1 = std::to_underlying(x);
+}
+
+// { dg-final { scan-tree-dump-not "= std::to_underlying" "gimple" } }
index 1c15c75f92b014a516c1cc6c0ce652c91ce70669..8a85ccfd09ba2dd042d45fb9952f4a7d5bc25a09 100644 (file)
@@ -201,7 +201,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef __cpp_lib_to_underlying // C++ >= 23
   /// Convert an object of enumeration type to its underlying type.
   template<typename _Tp>
-    [[nodiscard]]
+    [[nodiscard, __gnu__::__always_inline__]]
     constexpr underlying_type_t<_Tp>
     to_underlying(_Tp __value) noexcept
     { return static_cast<underlying_type_t<_Tp>>(__value); }