[Bug c++/110295] [10/11/12/13/14 Regression] ICE in dwarf2out_finish with local class with inherited operator delete in a templated function and -g

2023-06-20 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110295

--- Comment #4 from CVS Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:963f87f8a65ec82f503ac4334a3da83b0a8a43b2

commit r14-1958-g963f87f8a65ec82f503ac4334a3da83b0a8a43b2
Author: Richard Biener 
Date:   Mon Jun 19 09:23:16 2023 +0200

debug/110295 - mixed up early/late debug for member DIEs

When we process a scope typedef during early debug creation and
we have already created a DIE for the type when the decl is
TYPE_DECL_IS_STUB and this DIE is still in limbo we end up
just re-parenting that type DIE instead of properly creating
a DIE for the decl, eventually picking up the now completed
type and creating DIEs for the members.  Instead this is currently
defered to the second time we come here, when we annotate the
DIEs with locations late where now the type DIE is no longer
in limbo and we fall through doing the job for the decl.

The following makes sure we perform the necessary early tasks
for this by continuing with the decl DIE creation after setting
a parent for the limbo type DIE.

PR debug/110295
* dwarf2out.cc (process_scope_var): Continue processing
the decl after setting a parent in case the existing DIE
was in limbo.

* g++.dg/debug/pr110295.C: New testcase.

[Bug c++/110295] [10/11/12/13/14 Regression] ICE in dwarf2out_finish with local class with inherited operator delete in a templated function and -g

2023-06-19 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110295

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org
   Keywords|needs-bisection |

--- Comment #3 from Richard Biener  ---
(gdb) p debug_dwarf_die (deferred_asm_name->die)
DIE0: DW_TAG_subprogram (0x76e4aaa0)
  abbrev id: 0 offset: 0 mark: 0
  DW_AT_external: 1
  DW_AT_name: "thing_t"
  DW_AT_artificial: 1
  DW_AT_declaration: 1
  DW_AT_object_pointer: die -> 0 (0x76e4aaf0)
DIE0: DW_TAG_formal_parameter (0x76e4aaf0)
  abbrev id: 0 offset: 0 mark: 0
  DW_AT_type: die -> 0 (0x76e4a1e0)
  DW_AT_artificial: 1
(gdb) p deferred_asm_name->created_for 
$4 = 

created via

(gdb) bt
#0  add_linkage_name_raw (
die=>, decl=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:22023
#1  0x013ef18a in add_linkage_name (
die=>, decl=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:22047
#2  0x013ef2b8 in add_name_and_src_coords_attributes (
die=>, decl=, 
no_linkage_name=false)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:22072
#3  0x013f363d in gen_subprogram_die (
decl=, 
context_die=>)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:23701
#4  0x013fda8f in gen_decl_die (
decl=, origin=, 
ctx=0x7fffd1b0, 
context_die=>)
#5  0x013f9dc5 in gen_member_die (
type=, 
context_die=>)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:25858
#6  0x013fa517 in gen_struct_or_union_type_die (
type=, 
context_die=>, usage=DINFO_USAGE_DIR_USE)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:25954
#7  0x013faff8 in gen_tagged_type_die (
type=, 
context_die=>, usage=DINFO_USAGE_DIR_USE)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:26155
#8  0x013fb94f in gen_type_die_with_usage (
type=, 
context_die=>, usage=DINFO_USAGE_DIR_USE)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:26349
#9  0x013fbcec in gen_type_die (
type=, 
context_die=>)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:26404
#10 0x013fdc7f in gen_decl_die (
decl=, origin=, ctx=0x0, 
context_die=>)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:27043
#11 0x013fc3e4 in process_scope_var (stmt=, 
decl=, origin=, 
context_die=>)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:26557
#12 0x013fc46d in decls_for_scope (stmt=, 
context_die=>, recurse=true)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:26583
#13 0x013f4757 in gen_subprogram_die (
decl=, 
context_die=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:24087
#14 0x013fda8f in gen_decl_die (
decl=, origin=, ctx=0x0, 
context_die=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:27020
#15 0x013ff1da in dwarf2out_decl (
decl=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:27601
#16 0x013ff239 in dwarf2out_function_decl (
decl=)
at /space/rguenther/src/gcc11queue/gcc/dwarf2out.cc:27616
#17 0x014bfa35 in rest_of_handle_final ()
at /space/rguenther/src/gcc11queue/gcc/final.cc:4274

interestingly we do not arrive at the member DIE creation of the typedef
from the outermost frames.  In fact we create the type DIE for
thing_t before processing the local typedef decl but there it's not
final it seems but simply

 
full-name "struct exercise<1>()::thing_t"
no-binfo use_template=1 interface-unknown
pointer_to_this  chain >

and we then run into

/* Process variable DECL (or variable with origin ORIGIN) within
   block STMT and add it to CONTEXT_DIE.  */
static void
process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
{
...
  if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);

because appearantly we have created the DIE in limbo.  Of course when
running into this code late we now have a parent and end up creating
the decl DIE.

I think we want to continue creating the DIE for the decl here.  The following
fixes this issue.

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index d89ffa66847..e70c47cec8d 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -26533,7 +26533,8 @@ process_scope_var (tree stmt, tree decl, tree origin,
dw_die_ref context_die)

   if (die != NULL && die->die_parent == NULL)
 add_child_die (context_die, die);
-  else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
+
+  if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
 {
   if (early_dwarf)
dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME
(decl_or_origin),

[Bug c++/110295] [10/11/12/13/14 Regression] ICE in dwarf2out_finish with local class with inherited operator delete in a templated function and -g

2023-06-17 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110295

Andrew Pinski  changed:

   What|Removed |Added

Summary|internal compiler error: in |[10/11/12/13/14 Regression]
   |dwarf2out_finish|ICE in dwarf2out_finish
   ||with local class with
   ||inherited operator delete
   ||in a templated function and
   ||-g
   Target Milestone|--- |10.5
 Ever confirmed|0   |1
  Known to work||5.1.0, 5.5.0
  Known to fail||10.1.0, 6.1.0, 7.1.0
 Status|UNCONFIRMED |NEW
   Keywords||ice-on-valid-code
   Last reconfirmed||2023-06-17

--- Comment #2 from Andrew Pinski  ---
Reduced testcase:
```
template 
struct QCachedT
{
  void operator delete(void *, T *) {}
};
template
void exercise()
{
  struct thing_t
: QCachedT
  {
  };
  thing_t *list[1];
  new thing_t;
}
int main() { exercise<1>(); }
```

Note exercise needs to be templated and so does QCachedT.
My guess is thing_t that is for the operator delete is not be subsituted
correctly for the new class when instantiating exercise; it works ok without -g
but when trying to emit debug info, it crashes not knowing the class.