From 504e0b5f2c7128a89f869ca984949d063bab52c4 Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Mon, 25 Sep 2017 12:26:36 +0000 Subject: [PATCH] [PR82155] Fix crash in dwarf2out_abstract_function This patch is an attempt to fix the crash reported in PR82155. When generating a C++ class method for a class that is itself nested in a class method, dwarf2out_early_global_decl currently leaves the existing context DIE as it is if it already exists. However, it is possible that this call happens at a point where this context DIE is just a declaration that is itself not located in its own context. From there, if dwarf2out_early_global_decl is not called on any of the FUNCTION_DECL in the context chain, DIEs will be left badly scoped and some (such as the nested method) will be removed by the type pruning machinery. As a consequence, dwarf2out_abstract_function will will crash when called on the corresponding DECL because it asserts that the DECL has a DIE. This patch fixes this crash making dwarf2out_early_global_decl process context DIEs the same way we process abstract origins for FUNCTION_DECL: if the corresponding DIE exists but is only a declaration, call dwarf2out_decl anyway on it so that it is turned into a more complete DIE and so that it is relocated in the proper context. Bootstrapped and regtested on x86_64-linux. gcc/ PR debug/82155 * dwarf2out.c (dwarf2out_early_global_decl): Call dwarf2out_decl on the FUNCTION_DECL function context if it has a DIE that is a declaration. gcc/testsuite/ * g++.dg/pr82155.C: New testcase. From-SVN: r253147 --- gcc/ChangeLog | 7 +++++++ gcc/dwarf2out.c | 10 ++++++++-- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/pr82155.C | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr82155.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f618113..b3dadab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-09-25 Pierre-Marie de Rodat + + PR debug/82155 + * dwarf2out.c (dwarf2out_early_global_decl): Call dwarf2out_decl + on the FUNCTION_DECL function context if it has a DIE that is a + declaration. + 2017-09-25 Richard Biener PR tree-optimization/82285 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index dda569f..e97ceb6 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -25490,10 +25490,16 @@ dwarf2out_early_global_decl (tree decl) so that all nested DIEs are generated at the proper scope in the first shot. */ tree context = decl_function_context (decl); - if (context != NULL && lookup_decl_die (context) == NULL) + if (context != NULL) { + dw_die_ref context_die = lookup_decl_die (context); current_function_decl = context; - dwarf2out_decl (context); + + /* Avoid emitting DIEs multiple times, but still process CONTEXT + enough so that it lands in its own context. This avoids type + pruning issues later on. */ + if (context_die == NULL || is_declaration_die (context_die)) + dwarf2out_decl (context); } /* Emit an abstract origin of a function first. This happens diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 333e2c8..8cdcbc6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-09-25 Pierre-Marie de Rodat + + * g++.dg/pr82155.C: New testcase. + 2017-09-25 Richard Biener PR tree-optimization/82285 diff --git a/gcc/testsuite/g++.dg/pr82155.C b/gcc/testsuite/g++.dg/pr82155.C new file mode 100644 index 0000000..75d9b61 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr82155.C @@ -0,0 +1,36 @@ +/* { dg-do compile { target c++11 } } */ +/* { dg-options "-g -O2" } */ + +template struct b { a c; }; +template struct e { d *operator->(); }; +template class h { +public: + typedef e ag; +}; +class i { +protected: + i(int); +}; +class j { + virtual void k(int) = 0; + +public: + int f; + void l() { k(f); } +}; +struct m : i { + int cn; + m() : i(cn) { + struct n : j { + n() {} + void k(int) {} + }; + } +}; +struct o { + o() { + for (h>>::ag g;;) + g->c.c->l(); + } +}; +void fn1() { o(); } -- 2.7.4