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