aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/dwarf2out.cc16
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c28
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c35
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c24
4 files changed, 95 insertions, 8 deletions
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index a817c69..ac39cf5 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -13842,14 +13842,14 @@ gen_btf_tag_dies (tree attr, dw_die_ref die)
if (die)
{
- /* Add AT_GNU_annotation referring to the annotation DIE.
- It may have already been added, some global declarations are processed
- twice, but if so it must be the same or we have a bug. */
- dw_die_ref existing = get_AT_ref (die, DW_AT_GNU_annotation);
- if (existing)
- gcc_checking_assert (existing == tag_die);
- else
- add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
+ /* Add (or replace) AT_GNU_annotation referring to the annotation DIE.
+ Replacement may happen for example when 'die' is a global variable
+ which has been re-declared multiple times. In any case, the set of
+ input attributes is the one that ought to be reflected. For global
+ variable re-declarations which add additional decl tags, they will
+ have been accumulated in the variable's DECL_ATTRIBUTES for us. */
+ remove_AT (die, DW_AT_GNU_annotation);
+ add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
}
return tag_die;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
new file mode 100644
index 0000000..6fdcdc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
@@ -0,0 +1,28 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+#define __tag4 __attribute__((btf_decl_tag ("tag4")))
+
+int foo __tag1;
+int foo __tag2;
+
+/* Result: foo has __tag1 and __tag2. */
+
+int bar __tag3;
+int bar;
+
+/* Result: bar has __tag3. */
+
+int baz;
+int baz __tag4;
+
+/* Result: baz has __tag4. */
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 4 } } */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 4 } } */
+
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
new file mode 100644
index 0000000..c7cb60c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
@@ -0,0 +1,35 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+
+struct S
+{
+ int x;
+ char c;
+};
+
+extern struct S foo __tag1;
+struct S foo __tag2;
+
+/* Result: non-completing variable DIE for 'foo' has tag1, and the
+ completing DIE (with AT_specification) for 'foo' has tag2 -> tag1. */
+
+extern int a __tag3;
+int a;
+
+/* Result: non-completing variable DIE for a has tag3, and the
+ completing DIE (with AT_specification) for 'a' also refers to tag3. */
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 3 } } */
+
+/* 5 AT_GNU annotations:
+ - foo -> tag1
+ - foo -> tag2 -> tag1
+ - a -> tag3
+ - a -> tag3 */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 5 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
new file mode 100644
index 0000000..dd89d11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
@@ -0,0 +1,24 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+
+__tag1
+extern int
+do_thing (int);
+
+__tag2
+__tag3
+int
+do_thing (int x)
+{
+ return x * x;
+}
+
+/* Result: do_thing has all 3 tags. */
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 3 } } */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 3 } } */