We can attempt to add DW_AT_artificial because of two reasons,
because of DECL_ARTIFICIAL on the decl and because of the
artificial function attribute which is attempted when marking
a decl DIE for inlining. The following guards the latter,
avoiding an ICE with checking enabled.
Bootstrapped and tested on x86_64-unknown-linux-gnu, will push
tomorrow, just in case somebody manages to reduce the
testcase further.
Richard.
PR debug/124644
* dwarf2out.cc (dwarf2out_abstract_function): Only
add DW_AT_artificial if the decl isn't DECL_ARTIFICIAL.
* g++.dg/debug/pr124644.C: New testcase.
---
gcc/dwarf2out.cc | 1 +
gcc/testsuite/g++.dg/debug/pr124644.C | 95 +++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/debug/pr124644.C
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 31ff7ff1905..bf342e468bf 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -23790,6 +23790,7 @@ dwarf2out_abstract_function (tree decl)
}
if (DECL_DECLARED_INLINE_P (decl)
+ && !DECL_ARTIFICIAL (decl)
&& lookup_attribute ("artificial", DECL_ATTRIBUTES (decl)))
add_AT_flag (old_die, DW_AT_artificial, 1);
diff --git a/gcc/testsuite/g++.dg/debug/pr124644.C
b/gcc/testsuite/g++.dg/debug/pr124644.C
new file mode 100644
index 00000000000..e9300216a35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/pr124644.C
@@ -0,0 +1,95 @@
+// { dg-do compile }
+// { dg-options "-O -w -g1 -fchecking" }
+
+template <int __v> struct integral_constant {
+ static constexpr int value = __v;
+};
+struct __conjunction_impl {
+ using type = integral_constant<1>;
+};
+template <bool, typename _Iftrue, typename> using conditional_t = _Iftrue;
+template <int> struct _Fixed;
+template <int> struct _VecBuiltin;
+template <int _Np> using fixed_size = _Fixed<_Np>;
+template <typename...> struct _SimdTuple;
+template <int> struct __fixed_size_storage;
+template <typename, int _Np>
+using __fixed_size_storage_t = __fixed_size_storage<_Np>::type;
+struct _SimdWrapperBase {
+ [[__gnu__::__artificial__]] constexpr _SimdWrapperBase(int);
+};
+struct _SimdWrapper : _SimdWrapperBase {
+ using _SimdWrapperBase::_SimdWrapperBase;
+};
+template <unsigned long> struct __deduce_impl;
+template <typename, long _Np> using deduce_t = __deduce_impl<_Np>::type;
+template <template <int> class _Abi, int _Bytes> struct __find_next_valid_abi {
+ static auto _S_choose() { return _Abi<_Bytes>(); }
+ using type = decltype(_S_choose());
+};
+template <template <int> class...> struct _AbiList;
+const int _S_determine_best_abi__Bytes = sizeof(int);
+template <template <int> class _A0, template <int> class... _Rest>
+struct _AbiList<_A0, _Rest...> {
+ template <typename, int> static auto _S_determine_best_abi() {
+ return typename __find_next_valid_abi<_A0,
+
_S_determine_best_abi__Bytes>::type{};
+ }
+ template <typename _Tp, int _Np>
+ using _BestAbi = decltype(_S_determine_best_abi<_Tp, _Np>());
+};
+template <typename _Abi> struct _SimdTraits : _Abi::__traits<int> {};
+template <int _Np> struct __deduce_fixed_size_fallback {
+ using type = fixed_size<_Np>;
+};
+template <unsigned long _Np>
+struct __deduce_impl : __deduce_fixed_size_fallback<_Np> {};
+template <typename _Abi> struct simd {
+ using _Traits = _SimdTraits<_Abi>;
+ using _Impl = _Traits::_SimdImpl;
+ using abi_type = _Abi;
+ template <typename _Up> simd(_Up __x) : _M_data(_Impl::_S_broadcast(__x)) {}
+ friend void operator!=(simd, simd);
+ _Traits::_SimdMember _M_data;
+};
+struct _SimdTupleData {
+ _SimdWrapper second;
+};
+template <typename _Tp, typename _Abi0, typename... _Abis>
+struct _SimdTuple<_Tp, _Abi0, _Abis...> : _SimdTupleData {
+ template <typename _Fp> static _SimdTuple _S_generate(_Fp) { return {0}; }
+};
+template <typename _Tp, int _Np, typename,
+ typename = simd<_AbiList<_VecBuiltin>::_BestAbi<_Tp, _Np>>>
+struct __fixed_size_storage_builder;
+template <int _Np>
+struct __fixed_size_storage
+ : __fixed_size_storage_builder<long, _Np, _SimdTuple<>> {};
+template <typename _Tp, int _Np, typename... _As, typename _Next>
+struct __fixed_size_storage_builder<_Tp, _Np, _SimdTuple<_As...>, _Next> {
+ using type = _SimdTuple<_Tp, typename _Next::abi_type>;
+};
+template <int _Np> struct _SimdImplFixedSize {
+ template <typename _Tp> using _SimdMember = __fixed_size_storage_t<_Tp, _Np>;
+ template <typename _Tp> static _SimdMember<_Tp> _S_broadcast(_Tp) {
+ return _SimdMember<_Tp>::_S_generate([] {});
+ }
+};
+template <int _Np> struct _Fixed {
+ template <typename> struct __traits {
+ using _SimdImpl = _SimdImplFixedSize<_Np>;
+ using _SimdMember = __fixed_size_storage_t<int, _Np>;
+ };
+};
+struct _GnuTraits {
+ using _SimdImpl = long;
+ using _SimdMember = _SimdWrapper;
+};
+template <int> struct _VecBuiltin {
+ template <typename>
+ static constexpr bool _S_is_valid_v = __conjunction_impl::type ::value;
+ template <typename _Tp>
+ using __traits = conditional_t<_S_is_valid_v<_Tp>, _GnuTraits, int>;
+};
+template <typename U, int N> using V = simd<deduce_t<U, N>>;
+void reduce(V<long, 4> x) { x != 1; }
--
2.51.0