]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constexpr always_inline [PR120935]
authorJason Merrill <jason@redhat.com>
Thu, 22 May 2025 13:11:04 +0000 (09:11 -0400)
committerJason Merrill <jason@redhat.com>
Thu, 22 May 2025 20:05:30 +0000 (16:05 -0400)
In cp_fold we do speculative constant evaluation of constexpr calls when
inlining is enabled.  Let's also do it for always_inline functions.

PR c++/120935

gcc/cp/ChangeLog:

* cp-gimplify.cc (cp_fold): Check always_inline.

gcc/testsuite/ChangeLog:

* g++.dg/opt/always_inline2.C: New test.
* g++.dg/debug/dwarf2/pubnames-2.C: Suppress -fimplicit-constexpr.
* g++.dg/debug/dwarf2/pubnames-3.C: Likewise.

gcc/cp/cp-gimplify.cc
gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
gcc/testsuite/g++.dg/opt/always_inline2.C [new file with mode: 0644]

index f7bd453bc5eb3662b228ca988a89349a733fd964..03d5352977b2ee8731fefea66a7dce279a73d04c 100644 (file)
@@ -3441,7 +3441,9 @@ cp_fold (tree x, fold_flags_t flags)
           Do constexpr expansion of expressions where the call itself is not
           constant, but the call followed by an INDIRECT_REF is.  */
        if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
-           && !flag_no_inline)
+           && (!flag_no_inline
+               || lookup_attribute ("always_inline",
+                                    DECL_ATTRIBUTES (callee))))
          {
            mce_value manifestly_const_eval = mce_unknown;
            if (flags & ff_mce_false)
index 1fb5004df4012fc61de85fb7ea1268778d6dedb8..96469d4d332f1dc9858529265db216da8f0108c1 100644 (file)
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-skip-if "" { powerpc-ibm-aix* } }
-// { dg-options "-gpubnames -gdwarf-4 -fno-debug-types-section -dA -fno-inline" }
+// { dg-options "-gpubnames -gdwarf-4 -fno-debug-types-section -dA -fno-inline -fno-implicit-constexpr" }
 // { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 } }
 // { dg-final { scan-assembler "\"\\(anonymous namespace\\)\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
 // { dg-final { scan-assembler "\"one\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
index 37e04fb6c972c603cb822dd620b2ea3c6b9e0e83..f635803d45ac47814d00c6f708db13b42918d7bb 100644 (file)
@@ -1,6 +1,6 @@
 // { dg-do compile { target c++11 } }
 // { dg-skip-if "" { powerpc-ibm-aix* } }
-// { dg-options "-gpubnames -gdwarf-4 -fdebug-types-section -dA -fno-inline" }
+// { dg-options "-gpubnames -gdwarf-4 -fdebug-types-section -dA -fno-inline -fno-implicit-constexpr" }
 // { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 } }
 // { dg-final { scan-assembler "\"\\(anonymous namespace\\)\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
 // { dg-final { scan-assembler "\"one\\\\0\"+\[ \t\]+\[#;/|@!]+\[ \t\]+external name" } }
diff --git a/gcc/testsuite/g++.dg/opt/always_inline2.C b/gcc/testsuite/g++.dg/opt/always_inline2.C
new file mode 100644 (file)
index 0000000..8cfdd67
--- /dev/null
@@ -0,0 +1,28 @@
+// PR c++/120935
+// { dg-additional-options "-fdump-tree-optimized" }
+// { dg-final { scan-tree-dump-not "goto" "optimized" } }
+// { dg-do compile { target c++11 } }
+
+void x(int);
+
+[[gnu::always_inline]] constexpr bool
+is_constant_evaluated()
+{ return __builtin_is_constant_evaluated(); }
+
+struct Iter
+{
+    typedef int value_type;
+
+    int& operator*() const;
+    Iter& operator++();
+    bool operator!=(const Iter&) const;
+};
+
+void f(Iter first, Iter last)
+{
+    if (__is_trivial(Iter::value_type))
+        if (!is_constant_evaluated())
+            return;
+    for (; first != last; ++first)
+        x(*first);
+}