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>
PR tree-optimization/82285
......@@ -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
......
2017-09-25 Pierre-Marie de Rodat <derodat@adacore.com>
* g++.dg/pr82155.C: New testcase.
2017-09-25 Richard Biener <rguenther@suse.de>
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