Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
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 | 4 ++-
.../g++.dg/debug/dwarf2/pubnames-2.C | 2 +-
.../g++.dg/debug/dwarf2/pubnames-3.C | 2 +-
gcc/testsuite/g++.dg/opt/always_inline2.C | 28 +++++++++++++++++++
4 files changed, 33 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/opt/always_inline2.C
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index f7bd453bc5e..03d5352977b 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -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)
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
index 1fb5004df40..96469d4d332 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-2.C
@@ -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" } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
index 37e04fb6c97..f635803d45a 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pubnames-3.C
@@ -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
index 00000000000..8cfdd67e36c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/always_inline2.C
@@ -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);
+}
base-commit: 10360c1b0d45ae129df616a9e9b1db5f2a2eaef8
--
2.49.0