diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-02-16 09:47:24 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-02-16 09:47:24 +0100 |
commit | 04c937f581e817069fa8f8c8e724097057b08c43 (patch) | |
tree | f80241d2381632dfc058bee12ceb23fe8b4a85ce /gcc | |
parent | cebb46984746605c39eaefa3d9022b4b1a4e7c42 (diff) | |
download | gcc-04c937f581e817069fa8f8c8e724097057b08c43.zip gcc-04c937f581e817069fa8f8c8e724097057b08c43.tar.gz gcc-04c937f581e817069fa8f8c8e724097057b08c43.tar.bz2 |
re PR debug/52260 (ICE in clone_tree_hash, at dwarf2out.c:7424)
PR debug/52260
* dwarf2out.c (copy_decls_walk): Fill in *slot before traversing
children with clone_tree_hash, not after it.
* g++.dg/debug/dwarf2/pr52260.C: New test.
From-SVN: r184303
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/debug/dwarf2/pr52260.C | 133 |
4 files changed, 150 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7cc1ecb..82139ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-02-16 Jakub Jelinek <jakub@redhat.com> + + PR debug/52260 + * dwarf2out.c (copy_decls_walk): Fill in *slot before traversing + children with clone_tree_hash, not after it. + 2012-02-16 Iain Sandoe <iains@gcc.gnu.org> * config/darwin.h (ASM_OUTPUT_LABELREF): Add user label prefix for diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d6fbce6..5c7d8aa 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -7471,14 +7471,6 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) dw_die_ref parent = unit; dw_die_ref copy = clone_die (targ); - FOR_EACH_CHILD (targ, c, - add_child_die (copy, - clone_tree_hash (c, decl_table))); - - /* Make sure the cloned tree is marked as part of the - type unit. */ - mark_dies (copy); - /* Record in DECL_TABLE that TARG has been copied. Need to do this now, before the recursive call, because DECL_TABLE may be expanded and SLOT @@ -7488,6 +7480,14 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table) entry->copy = copy; *slot = entry; + FOR_EACH_CHILD (targ, c, + add_child_die (copy, + clone_tree_hash (c, decl_table))); + + /* Make sure the cloned tree is marked as part of the + type unit. */ + mark_dies (copy); + /* If TARG has surrounding context, copy its ancestor tree into the new type unit. */ if (targ->die_parent != NULL diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2ab5803..ae98f1e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2012-02-16 Jakub Jelinek <jakub@redhat.com> + PR debug/52260 + * g++.dg/debug/dwarf2/pr52260.C: New test. + PR middle-end/51929 * g++.dg/ipa/pr51929.C: New test. diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr52260.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr52260.C new file mode 100644 index 0000000..9ab2589 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr52260.C @@ -0,0 +1,133 @@ +// PR debug/52260 +// { dg-do compile } +// { dg-options "-gdwarf-4 -std=c++0x" } + +namespace { typedef decltype (nullptr) T1; } +struct B {}; +namespace A +{ + template <typename T, T __v> + struct C { static constexpr T value = __v; }; + typedef C <bool, false> D; + template <typename> + struct E : D {}; + template <typename T> + struct F : C <bool, (E <T>::value)> {}; + template <bool, typename T = void> + struct G { typedef T t; }; +} +template <typename T> +struct H {}; +namespace A +{ + template <typename T> + struct I : H <T> {}; + template <typename ...> struct J; + template <typename> struct K; + struct L + { + template <typename B2> + struct M + { + template <typename T> static bool m2 (T) { return false; } + }; + }; + template <typename, typename> struct N; + template <typename T, typename B2, typename ... B4> + struct N <T (B4 ...), B2> : L::M <B2> {}; + template <typename T, typename ... B4> + struct K <T (B4 ...)> :J <,>, L + { + typedef T O (B4 ...); + struct P {}; + template <typename B2> K (B2, typename G <!F <B2>::value, P>::t = P ()); + }; + template <typename T, typename ... B1> + template <typename B2> + K <T (B1 ...)>::K (B2 __f, typename G <!F < B2>::value, P>::t) + { + typedef N <O, B2> Q; + Q::m2 (__f); + }; +} +enum R { r1 }; +const R r2 = r1; +namespace A +{ + template <typename> + struct S {}; + template <typename T, typename _Dp = S <T>> + struct U {}; + template <typename T, R _Lp = r2> + struct V { T *operator -> (); }; + template <typename T> + struct W : V <T> + { + W (const W &); + W (T1) {} + W & operator= (W) {} + }; + template <typename> struct Z; + struct AA + { + struct AB + { + struct AC { void operator () () {} }; + }; + template <typename T> using AD = U <T, AB::AC>; + struct AE + { + typedef AD <AB> AZ; + virtual ~AE (); + void o3 (K <AZ ()>, bool = false) {} + template <typename, typename _Arg> struct AY; + struct C1 {}; + template <typename T> struct AY <T, C1> + { + AZ operator () () { return AZ (); } + Z <T> _M_Z; + }; + template <typename T> + static AY <T, C1> _s1 (B, Z <T> *); + }; + }; + template <> + struct Z <void> + { + typedef AA::AE AF; + W <AF> o4; + void foo (B __p) + { + auto _s1 = AF::_s1 (__p, this); + o4->o3 (_s1); + } + }; + template <typename T, typename _Alloc> + struct AG {}; + template <typename T, typename D1 = A::I <T>> + struct AH : AG <T, D1> + { + void bar (T) { baz (); } + template <typename ... _Args> + void baz (_Args && ...); + }; + template <typename T, typename D1> + template <typename ... _Args> + void AH <T, D1>::baz (_Args && ...) {} + namespace + { + typedef A::K <void ()> AI; + struct AF + { + int v2; + AI v1; + AF (int, unsigned, AI __t) : v2 (), v1 (__t) {} + }; + struct D3 : A::AH <AF> + { + typedef AF AFT; + void v3 (AI __t) { bar (AFT (4, v4, __t)); } + int v4; + }; + } +} |