Hi! Similarly to https://gcc.gnu.org/ml/gcc-patches/2009-09/msg01161.html the C FE gets wrong the location of DW_TAG_enumeral_type if there is a forward declaration. If we e.g. have a variable that is first declared extern and then defined, we emit DW_TAG_variable with the location of the first declaration and then another DW_TAG_variable with DW_AT_specification pointing to the previous one for the definition, with locus of the definition. That is not what we do for enums, there is just one DIE, so we should use the more descriptive from the locations, which is the definition.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-03-09 Jakub Jelinek <ja...@redhat.com> PR c/79969 * c-decl.c (start_enum): Adjust DECL_SOURCE_LOCATION of TYPE_STUB_DECL. * gcc.dg/debug/dwarf2/enum-loc1.c: New test. --- gcc/c/c-decl.c.jj 2017-03-05 22:39:45.000000000 +0100 +++ gcc/c/c-decl.c 2017-03-09 08:19:33.100042166 +0100 @@ -8201,6 +8201,10 @@ start_enum (location_t loc, struct c_enu enumtype = make_node (ENUMERAL_TYPE); pushtag (loc, name, enumtype); } + /* Update type location to the one of the definition, instead of e.g. + a forward declaration. */ + else if (TYPE_STUB_DECL (enumtype)) + DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype)) = loc; if (C_TYPE_BEING_DEFINED (enumtype)) error_at (loc, "nested redefinition of %<enum %E%>", name); --- gcc/testsuite/gcc.dg/debug/dwarf2/enum-loc1.c.jj 2017-03-09 08:09:30.742037844 +0100 +++ gcc/testsuite/gcc.dg/debug/dwarf2/enum-loc1.c 2017-03-09 08:16:45.202268438 +0100 @@ -0,0 +1,19 @@ +/* PR c/79969 */ +/* { dg-do compile } */ +/* { dg-options "-gdwarf -dA -fno-merge-debug-strings" } */ + +enum ENUMTAG; + +enum ENUMTAG +{ + B = 1, + C = 2 +}; + +void +bar (void) +{ + enum ENUMTAG a = C; +} + +/* { dg-final { scan-assembler "DW_TAG_enumeration_type\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"ENUMTAG\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ Jakub