https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78112
--- Comment #9 from Pierre-Marie de Rodat <derodat at adacore dot com> --- Back to business. ;-) Thank you very much, Jakub! During investigation, I managed to reduce this even further: void run (int *int_p, void(*func)(int *)) { func (int_p); } namespace foo { struct Foo { int a; Foo() { run (&a, [](int *int_p) { *int_p = 0; }); } }; } int main (void) { foo::Foo f; } With today’s trunk (gcc/cc1plus -g -dA foo.C) and this reproducer, I see three DW_TAG_subprogram having two DW_AT_object_pointer each. Disclaimer: to be perfectly honnest, I have a very partial understanding of how dwarf2out.c:gen_subprogram_die is supposed to work. It has a good share of explaining comments, but it is still hard to grasp as it does quite complex things. That being said… My analysis so far is that gen_subprogram_die is supposed to be called a very specific number of times for each function and my change from 2016-10-12 made it run more times, so it unintentionally added some attributes more than just once. The following patch seems to restore call count to what we had previously: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 78a2979..a85ab3b 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -23909,11 +23909,11 @@ dwarf2out_early_global_decl (tree decl) if (!DECL_STRUCT_FUNCTION (decl)) goto early_decl_exit; - /* For nested functions, emit DIEs for the parents first so that all - nested DIEs are generated at the proper scope in the first - shot. */ + /* For nested functions, make sure we have DIEs for the parents first + so that all nested DIEs are generated at the proper scope in the + first shot. */ tree context = decl_function_context (decl); - if (context != NULL) + if (context != NULL && lookup_decl_die (context) == NULL) { current_function_decl = context; dwarf2out_decl (context); I’m currently bootstrapping+regtesting it on x86_64-linux. I tried to come up with a regression testcase for it, but I can’t find a human-friendly regexp for scan-assembler-times to check that we don’t have multiple attributes per tag. So for local testing, I wrote a Python3 script to use the pyelftools library. I’ll file it right after sending this message if others need to use it. Something bugs me, though: with Jakub’s reproducer, I get multiple DW_AT_object_pointer attributes even at r241022 (i.e. right before my 2016-10-12 patch): $ gcc/cc1plus -g -dA pr78112.ii && gcc -c pr78112.s && ./check.py pr78112.o In (0x3c4) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times In (0x46a) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times In (0x4fe) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times In (0x55a) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times In (0x5cf) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times In (0x668) DW_TAG_subprogram: DW_AT_object_pointer appears 2 times So I’m surprised Rainer hasn’t spotted this kind of error before. Thoughts?