@@ -10902,7 +10902,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
name lookup will find the TYPE_DECL for the implicit "S::S"
typedef. Adjust for that here. */
if (DECL_SELF_REFERENCE_P (decl))
- decl = TYPE_NAME (TREE_TYPE (decl));
+ decl = TYPE_NAME (DECL_ORIGINAL_TYPE (decl));
type = TREE_TYPE (decl);
@@ -12791,6 +12791,23 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* Otherwise, look for a type-name. */
else
type = cp_parser_type_name (parser);
+
+ /* Self reference typedefs should not be kept because it
+ confuses the debug info emitter that wouldn't know how to
+ tell the difference between an artificial typedef to drop
+ and an artificial self reference typedef to keep.
+ So let's replace the self reference by the type by its
+ underlying type. */
+ if (type && TREE_CODE (type) == TYPE_DECL
+ && DECL_SELF_REFERENCE_P (type)
+ /* If TYPE is a decl of a template or a template
+ instantiation we need to keep it because the information
+ is used later by e.g,
+ maybe_get_template_decl_from_type_decl. */
+ && !CLASSTYPE_IS_TEMPLATE (TREE_TYPE (type))
+ && !CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type)))
+ type = TYPE_NAME (DECL_ORIGINAL_TYPE (type));
+
/* Keep track of all name-lookups performed in class scopes. */
if (type
&& !global_p
new file mode 100644
@@ -0,0 +1,28 @@
+// Origin: PR debug/45088
+// { dg-do compile }
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_pointer_type\\)\[\n\r\]{1,2}\[^\n\r\]*DW_AT_byte_size\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type" 3 } }
+
+struct A
+{
+ virtual ~A();
+};
+
+struct B : public A
+{
+ virtual ~B(){}
+};
+
+struct C : public B
+{
+ A* a1;
+};
+
+int
+main()
+{
+ C c;
+ c.a1 = 0;
+ return 0;
+}
+
new file mode 100644
@@ -0,0 +1,29 @@
+// Origin: PR debug/45088
+// { dg-do compile }
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_pointer_type\\)\[\n\r\]{1,2}\[^\n\r\]*DW_AT_byte_size\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type" 4 } }
+
+template<class T>
+struct A
+{
+ virtual ~A();
+};
+
+struct B : public A<int>
+{
+ virtual ~B(){}
+};
+
+struct C : public B
+{
+ A<int>* a1;
+};
+
+int
+main()
+{
+ C c;
+ c.a1 = 0;
+ return 0;
+}
+