Commit 504e0b5f by Pierre-Marie de Rodat Committed by Pierre-Marie de Rodat

[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
parent d362ac6c
2017-09-25 Pierre-Marie de Rodat <derodat@adacore.com>
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 <rguenther@suse.de> 2017-09-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82285 PR tree-optimization/82285
...@@ -25490,10 +25490,16 @@ dwarf2out_early_global_decl (tree decl) ...@@ -25490,10 +25490,16 @@ dwarf2out_early_global_decl (tree decl)
so that all nested DIEs are generated at the proper scope in the so that all nested DIEs are generated at the proper scope in the
first shot. */ first shot. */
tree context = decl_function_context (decl); 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; 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 /* Emit an abstract origin of a function first. This happens
......
2017-09-25 Pierre-Marie de Rodat <derodat@adacore.com>
* g++.dg/pr82155.C: New testcase.
2017-09-25 Richard Biener <rguenther@suse.de> 2017-09-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82285 PR tree-optimization/82285
......
/* { dg-do compile { target c++11 } } */
/* { dg-options "-g -O2" } */
template <typename a> struct b { a c; };
template <typename d> struct e { d *operator->(); };
template <typename d> class h {
public:
typedef e<d> 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<b<b<j *>>>::ag g;;)
g->c.c->l();
}
};
void fn1() { o(); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment