2017-08-18 Richard Biener * dwarf2out.c (modified_type_die): Check for self origin before recursing. (gen_type_die_with_usage): Likewise. (gen_typedef_die): Allow self origin. * tree.c (variably_modified_type_p): Guard against Ada recursive pointer types. Index: early-lto-debug/gcc/dwarf2out.c =================================================================== --- early-lto-debug.orig/gcc/dwarf2out.c 2017-08-18 12:07:37.670609820 +0200 +++ early-lto-debug/gcc/dwarf2out.c 2017-08-18 10:16:59.261727525 +0200 @@ -12837,7 +12837,7 @@ modified_type_die (tree type, int cv_qua /* Typedef variants that have an abstract origin don't get their own type DIE (see gen_typedef_die), so fall back on the ultimate abstract origin instead. */ - if (origin != NULL) + if (origin != NULL && origin != name) return modified_type_die (TREE_TYPE (origin), cv_quals, reverse, context_die); @@ -24545,7 +24545,8 @@ gen_typedef_die (tree decl, dw_die_ref c /* As we avoid creating DIEs for local typedefs (see decl_ultimate_origin checks in process_scope_var and modified_type_die), this should be called only for original types. */ - gcc_assert (decl_ultimate_origin (decl) == NULL); + gcc_assert (decl_ultimate_origin (decl) == NULL + || decl_ultimate_origin (decl) == decl); TREE_ASM_WRITTEN (decl) = 1; type_die = new_die (DW_TAG_typedef, context_die, decl); @@ -24720,7 +24721,7 @@ gen_type_die_with_usage (tree type, dw_d tree name = TYPE_NAME (type); tree origin = decl_ultimate_origin (name); - if (origin != NULL) + if (origin != NULL && origin != name) { gen_decl_die (origin, NULL, NULL, context_die); return; Index: early-lto-debug/gcc/tree.c =================================================================== --- early-lto-debug.orig/gcc/tree.c 2017-08-18 12:07:37.786611917 +0200 +++ early-lto-debug/gcc/tree.c 2017-08-17 16:52:50.302969994 +0200 @@ -8601,8 +8601,16 @@ variably_modified_type_p (tree type, tre case POINTER_TYPE: case REFERENCE_TYPE: case VECTOR_TYPE: + /* Ada can have pointer types refering to themselves indirectly. */ + if (TREE_VISITED (type)) + return false; + TREE_VISITED (type) = true; if (variably_modified_type_p (TREE_TYPE (type), fn)) - return true; + { + TREE_VISITED (type) = false; + return true; + } + TREE_VISITED (type) = false; break; case FUNCTION_TYPE: