[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 Alexandre Oliva changed: What|Removed |Added CC||aoliva at gcc dot gnu.org --- Comment #18 from Alexandre Oliva --- The pr97060 test is failing for me, in the gcc-10 branch, at least on target arm-eabi. It passes when optimization is enabled, because then the DIE with the declaration tag, generated in resolve_addr, makes to the output. With optimization disabled, it's created and resolved, but doesn't make it. It looks like this only works at -O0 with the patch for bug 96383, but it hasn't been backported to gcc-10. Only Red Hat's gcc-10 branch has it, as stated in comment 6.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #17 from CVS Commits --- The releases/gcc-10 branch has been updated by Jason Merrill : https://gcc.gnu.org/g:3c45da4414884a5424484f5db1ab951d9de6 commit r10-9070-g3c45da4414884a5424484f5db1ab951d9de6 Author: Jason Merrill Date: Tue Nov 10 18:02:04 2020 -0500 dwarf2: Set DW_AT_declaration for undefined fns [PR97060] If DECL_INITIAL isn't set, we can't emit anything about the body of the function, so add the declaration attribute. gcc/ChangeLog: PR debug/97060 * dwarf2out.c (gen_subprogram_die): It's a declaration if DECL_INITIAL isn't set. gcc/testsuite/ChangeLog: PR debug/97060 * gcc.dg/debug/dwarf2/pr97060.c: New test.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #16 from H.J. Lu --- FWIW, I cherry-picked the fix onto vendors/redhat/gcc-10-branch branch. I can build 5.10 kernel with the fixed GCC.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 Jason Merrill changed: What|Removed |Added Target Milestone|--- |11.0 Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #15 from Jason Merrill --- Fixed for GCC 11. The patch will also be backported to the Red Hat GCC 10 branch that has the same bug.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #14 from CVS Commits --- The master branch has been updated by Jason Merrill : https://gcc.gnu.org/g:87b7d45e358e4df93b6a93b2e7a55b123ea76f5d commit r11-4933-g87b7d45e358e4df93b6a93b2e7a55b123ea76f5d Author: Jason Merrill Date: Tue Nov 10 18:02:04 2020 -0500 dwarf2: Set DW_AT_declaration for undefined fns [PR97060] If DECL_INITIAL isn't set, we can't emit anything about the body of the function, so add the declaration attribute. gcc/ChangeLog: PR debug/97060 * dwarf2out.c (gen_subprogram_die): It's a declaration if DECL_INITIAL isn't set. gcc/testsuite/ChangeLog: PR debug/97060 * gcc.dg/debug/dwarf2/pr97060.c: New test.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #13 from Jiri Olsa --- hi, any update on the fix? I'm seeing the bug now in fedora 32 with: $ gcc --version gcc (GCC) 10.2.1 20201005 (Red Hat 10.2.1-5) thanks, jirka
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
Jakub Jelinek changed:
What|Removed |Added
CC||jason at gcc dot gnu.org
--- Comment #12 from Jakub Jelinek ---
So, I've tried to bootstrap/regtest an adjusted patch:
2020-09-16 Jakub Jelinek
PR debug/97060
* dwarf2out.c (dwarf2out_early_global_decl): For FUNCTION_DECLs
and their abstract origins, if they don't have gimple body,
set current_function_decl to NULL rather than the decl or origin.
* gcc.dg/debug/dwarf2/pr97060.c: New test.
--- gcc/dwarf2out.c.jj 2020-09-07 13:17:58.383594248 +0200
+++ gcc/dwarf2out.c 2020-09-16 11:14:57.763550862 +0200
@@ -26547,7 +26547,12 @@ dwarf2out_early_global_decl (tree decl)
&& ((origin_die = lookup_decl_die (origin)) == NULL
|| is_declaration_die (origin_die)))
{
- current_function_decl = origin;
+ cgraph_node *cnode = cgraph_node::get (origin);
+ if ((cnode && cnode->has_gimple_body_p ())
+ || decl_ultimate_origin (origin))
+ current_function_decl = origin;
+ else
+ current_function_decl = NULL_TREE;
dwarf2out_decl (origin);
}
@@ -26556,7 +26561,12 @@ dwarf2out_early_global_decl (tree decl)
if ((old_die = lookup_decl_die (decl)) == NULL
|| is_declaration_die (old_die))
{
- current_function_decl = decl;
+ cgraph_node *cnode = cgraph_node::get (decl);
+ if ((cnode && cnode->has_gimple_body_p ())
+ || decl_ultimate_origin (decl))
+ current_function_decl = decl;
+ else
+ current_function_decl = NULL_TREE;
dwarf2out_decl (decl);
}
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c.jj 2020-09-16
11:03:22.358420449 +0200
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c 2020-09-16 11:03:17.717486318
+0200
@@ -0,0 +1,13 @@
+/* PR debug/97060 */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" } */
+/* { dg-final { scan-assembler-times "DW_AT_declaration" 2 } } */
+
+extern int foo (unsigned int, unsigned int);
+
+int
+bar (void)
+{
+ foo (1, 2);
+ return 0;
+}
It passes bootstrap, but causes some regressions:
-FAIL: g++.dg/guality/pr55665.C -O2 -flto -fno-use-linker-plugin
-flto-partition=none line 23 p == 40
+FAIL: g++.dg/debug/dwarf2/array-3.C -std=gnu++11 scan-assembler-times
DW_TAG_const_type 5
+FAIL: g++.dg/debug/dwarf2/array-3.C -std=gnu++14 scan-assembler-times
DW_TAG_const_type 5
+FAIL: g++.dg/debug/dwarf2/array-3.C -std=gnu++17 scan-assembler-times
DW_TAG_const_type 5
+FAIL: g++.dg/debug/dwarf2/array-3.C -std=gnu++2a scan-assembler-times
DW_TAG_const_type 5
+FAIL: g++.dg/debug/dwarf2/array-3.C -std=gnu++98 scan-assembler-times
DW_TAG_const_type 5
+FAIL: g++.dg/debug/dwarf2/array-4.C -std=gnu++11 scan-assembler-times
DW_TAG_const_type 4
+FAIL: g++.dg/debug/dwarf2/array-4.C -std=gnu++14 scan-assembler-times
DW_TAG_const_type 4
+FAIL: g++.dg/debug/dwarf2/array-4.C -std=gnu++17 scan-assembler-times
DW_TAG_const_type 4
+FAIL: g++.dg/debug/dwarf2/array-4.C -std=gnu++2a scan-assembler-times
DW_TAG_const_type 4
+FAIL: g++.dg/debug/dwarf2/array-4.C -std=gnu++98 scan-assembler-times
DW_TAG_const_type 4
+FAIL: g++.dg/debug/dwarf2/defaulted-member-function-2.C scan-assembler-times
0x2[ \\t][^\\n]* DW_AT_defaulted 1
+FAIL: g++.dg/debug/dwarf2/local-var-in-contructor.C -std=gnu++11
scan-assembler problem
+FAIL: g++.dg/debug/dwarf2/local-var-in-contructor.C -std=gnu++14
scan-assembler problem
+FAIL: g++.dg/debug/dwarf2/local-var-in-contructor.C -std=gnu++17
scan-assembler problem
+FAIL: g++.dg/debug/dwarf2/local-var-in-contructor.C -std=gnu++2a
scan-assembler problem
+FAIL: g++.dg/debug/dwarf2/local-var-in-contructor.C -std=gnu++98
scan-assembler problem
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"one::c1::c10"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"one::c1::~c10"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"two::c2::c20"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"two::c2::~c20"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"two::c2::c20"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"two::c2::~c20"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.dg/debug/dwarf2/pubnames-2.C -std=gnu++11 scan-assembler
"two::c2::c20"+[ \\t]+[#;/|@!]+[ \\t]+external name
+FAIL: g++.d
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #11 from Jiri Olsa --- (In reply to Jakub Jelinek from comment #10) > RHEL8 uses gcc 8 which is not affected (unless one uses DTS/GTS). > Also, it is unclear for what in particular pahole or what wants to use > DW_AT_declaration. pahole takes dwarf data and produces BTF type data that includes functions the DW_AT_declaration flag was used to skip function declarations so only one function record was processed and added to BTF data without that flag pahole will add one function multiple times to BTF data, based on how many times it was declared in other objects > DW_TAG_subprogram of a real definition (that hasn't been optimized out) is > the one that has DW_AT_low_pc/DW_AT_high_pc or DW_AT_ranges attributes (i.e. > has any associated code). Some functions can have many definitions (e.g. > inline functions or other comdat entities). I'll check if we can add more check to pahole for this thanks
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #10 from Jakub Jelinek --- RHEL8 uses gcc 8 which is not affected (unless one uses DTS/GTS). Also, it is unclear for what in particular pahole or what wants to use DW_AT_declaration. DW_TAG_subprogram of a real definition (that hasn't been optimized out) is the one that has DW_AT_low_pc/DW_AT_high_pc or DW_AT_ranges attributes (i.e. has any associated code). Some functions can have many definitions (e.g. inline functions or other comdat entities).
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #9 from Jiri Olsa --- (In reply to Jakub Jelinek from comment #6) > Also, to avoid confusion, upstream 10 branch is not affected, but in 10-RH > we've backported the PR96383 changes from the trunk. Is this gcc going to RHEL8? that could be a problem for us. Also, is there a way how we can workaround this? How to recgnize function declaration apart from definition in dwarf data?
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
--- Comment #8 from Jakub Jelinek ---
Unfortunately the patch doesn't really bootstrap.
Small testcase that ICEs:
struct S { virtual ~S (); } s;
This is on the external S::~S() declaration, which has non-NULL
decl_ultimate_origin (the abstract destructor from which the concrete ones are
inherited), but with the above patch we want to emit it as declaration and run
into:
/* A concrete instance, tag a new DIE with DW_AT_abstract_origin. */
if (origin != NULL)
{
gcc_assert (!declaration || local_scope_p (context_die));
So, one way around would be to only clear current_function_decl for functions
with decl_ultimate_origin (decl) == NULL.
But then we wouldn't emit DW_AT_declaration in this case (ok, one needs
-fno-eliminate-unused-debug-symbols to actually see it in the assembly).
On the other side, having a DW_TAG_subprogram with both DW_AT_specification and
DW_AT_declaration looks invalid to me.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 Jakub Jelinek changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org --- Comment #7 from Jakub Jelinek --- Created attachment 49224 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49224&action=edit gcc11-pr97060.patch Actually, the DECL_EXTERNAL tests aren't probably a good idea because of the GNU extern inlines. This patch attempts to match the previous behavior where early_debug_decl was called only on FUNCTION_DECLs with gimple bodies, so the patch for those keeps setting current_function_decl to non-NULL and sets it to NULL only for the FUNCTION_DECLs for which it wouldn't be called previously and only the PR96383 changed that.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 Jakub Jelinek changed: What|Removed |Added Version|10.2.1 |11.0 --- Comment #6 from Jakub Jelinek --- Also, to avoid confusion, upstream 10 branch is not affected, but in 10-RH we've backported the PR96383 changes from the trunk.
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
--- Comment #5 from Jakub Jelinek ---
So perhaps completely untested:
--- gcc/dwarf2out.c.jj 2020-09-07 13:17:58.383594248 +0200
+++ gcc/dwarf2out.c 2020-09-16 10:53:44.353632197 +0200
@@ -26547,7 +26547,8 @@ dwarf2out_early_global_decl (tree decl)
&& ((origin_die = lookup_decl_die (origin)) == NULL
|| is_declaration_die (origin_die)))
{
- current_function_decl = origin;
+ current_function_decl
+ = DECL_EXTERNAL (origin) ? NULL_TREE : origin;
dwarf2out_decl (origin);
}
@@ -26556,7 +26557,7 @@ dwarf2out_early_global_decl (tree decl)
if ((old_die = lookup_decl_die (decl)) == NULL
|| is_declaration_die (old_die))
{
- current_function_decl = decl;
+ current_function_decl = DECL_EXTERNAL (decl) ? NULL_TREE : decl;
dwarf2out_decl (decl);
}
?
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
--- Comment #4 from Jiri Olsa ---
(In reply to Jakub Jelinek from comment #3)
> So this is really just something like: -O2 -g -dA:
> extern int foo (unsigned int, unsigned int);
>
> int
> bar (void)
> {
> foo (1, 2);
> return 0;
> }
>
> where we don't emit DW_AT_declaration neither for the external declaration
> of foo, nor for the definition of bar. Other compilers don't emit them
> either.
>
> Anyway, older gcc versions used to emit those and this changed with
> PR96383 r11-2455-gc6ef9d8d3f11221df1ea6358b8d4e79e42f074fb
is there a way we can tell which record is for declaration/definition?
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
Jakub Jelinek changed:
What|Removed |Added
CC||jakub at gcc dot gnu.org
Status|WAITING |NEW
--- Comment #3 from Jakub Jelinek ---
So this is really just something like: -O2 -g -dA:
extern int foo (unsigned int, unsigned int);
int
bar (void)
{
foo (1, 2);
return 0;
}
where we don't emit DW_AT_declaration neither for the external declaration of
foo, nor for the definition of bar. Other compilers don't emit them either.
Anyway, older gcc versions used to emit those and this changed with
PR96383 r11-2455-gc6ef9d8d3f11221df1ea6358b8d4e79e42f074fb
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060 --- Comment #2 from Jiri Olsa --- Created attachment 49223 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49223&action=edit fs/init.i
[Bug debug/97060] Missing DW_AT_declaration=1 in dwarf data
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060
Richard Biener changed:
What|Removed |Added
Last reconfirmed||2020-09-16
Ever confirmed|0 |1
CC||jsm28 at gcc dot gnu.org
Status|UNCONFIRMED |WAITING
--- Comment #1 from Richard Biener ---
I guess that vfs_getattr is declared 'extern inline'. At least with
extern inline int foo (int i) { return i; }
int main()
{
foo (5);
}
I can reproduce this kind of DIE:
<1><52>: Abbrev Number: 4 (DW_TAG_subprogram)
<53> DW_AT_external: 1
<53> DW_AT_name: foo
<57> DW_AT_decl_file : 1
<58> DW_AT_decl_line : 1
<59> DW_AT_decl_column : 19
<5a> DW_AT_prototyped : 1
<5a> DW_AT_type: <0x4b>
<5e> DW_AT_low_pc : 0x0
<66> DW_AT_high_pc : 0xc
<6e> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<70> DW_AT_GNU_all_call_sites: 1
these "extern" inline functions are not really external, but I'm not sure
of a better representation of GNU extern inline functions.
Can you please provide preprocessed source of the fs/init.o TU?
