On Fri, 11 Mar 2011, Joseph S. Myers wrote: > On Fri, 11 Mar 2011, Richard Guenther wrote: > > > Indeed. I tried to let the array case alone (because it's so > > complicated) but failed to do so. Appearantly > > > > if (declarator->kind == cdk_array && TYPE_QUALS (element_type)) > > type = TYPE_MAIN_VARIANT (type); > > > > leaves it alone (and doesn't emit a DW_TAG_typedef for T for your > > testcase). Thus out of the set of testcases I added the array > > case now fails with the above (as I'd have expected but were of > > course positively surprised as it didn't ...). > > > > I verified the main variants and canonical types are sane with > > the above variant for your testcase. > > > > If you think such change isn't safe either I'll pursue a dwarf2out.c > > local change, somehow forcing out the typedef DIE even if it is unused. > > I don't feel at home in the grokdeclarator dungeon. > > What I think is safe in grokdeclarator is using TYPE_MAIN_VARIANT here if > *either* the type given in the declaration specifiers is an array type > (TREE_CODE (type) == ARRAY_TYPE, as in your previous patch) *or* the first > declarator that is not cdk_attrs is cdk_array (as in this version, but > checking through a chain of declarator->declarator to find a possible > cdk_array after a sequence of cdk_attrs). > > (Aside from all this it is a longstanding known bug that the debug > information for arrays of qualified types isn't quite right: PR 8354.)
Ok, the following works for me. Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk? Thanks, Richard. 2011-03-17 Richard Guenther <rguent...@suse.de> PR c/47939 * c-decl.c (grokdeclarator): Drop to the main variant only for array types. Drop flag_gen_aux_info check. * gcc.dg/debug/dwarf2/pr47939-1.c: New testcase. * gcc.dg/debug/dwarf2/pr47939-2.c: Likewise. * gcc.dg/debug/dwarf2/pr47939-3.c: Likewise. * gcc.dg/debug/dwarf2/pr47939-4.c: Likewise. Index: gcc/c-decl.c =================================================================== *** gcc/c-decl.c (revision 171097) --- gcc/c-decl.c (working copy) *************** grokdeclarator (const struct c_declarato *** 4892,4897 **** --- 4892,4898 ---- const char *errmsg; tree expr_dummy; bool expr_const_operands_dummy; + enum c_declarator_kind first_non_attr_kind; if (TREE_CODE (type) == ERROR_MARK) return error_mark_node; *************** grokdeclarator (const struct c_declarato *** 4911,4916 **** --- 4912,4918 ---- { const struct c_declarator *decl = declarator; + first_non_attr_kind = cdk_attrs; while (decl) switch (decl->kind) { *************** grokdeclarator (const struct c_declarato *** 4922,4927 **** --- 4924,4931 ---- case cdk_pointer: funcdef_syntax = (decl->kind == cdk_function); decl = decl->declarator; + if (first_non_attr_kind == cdk_attrs) + first_non_attr_kind = decl->kind; break; case cdk_attrs: *************** grokdeclarator (const struct c_declarato *** 4932,4937 **** --- 4936,4943 ---- loc = decl->id_loc; if (decl->u.id) name = decl->u.id; + if (first_non_attr_kind == cdk_attrs) + first_non_attr_kind = decl->kind; decl = 0; break; *************** grokdeclarator (const struct c_declarato *** 5038,5044 **** error_at (loc, "conflicting named address spaces (%s vs %s)", c_addr_space_name (as1), c_addr_space_name (as2)); ! if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) type = TYPE_MAIN_VARIANT (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) --- 5044,5052 ---- error_at (loc, "conflicting named address spaces (%s vs %s)", c_addr_space_name (as1), c_addr_space_name (as2)); ! if ((TREE_CODE (type) == ARRAY_TYPE ! || first_non_attr_kind == cdk_array) ! && TYPE_QUALS (element_type)) type = TYPE_MAIN_VARIANT (type); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) Index: gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c =================================================================== *** gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c (revision 0) --- gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c (revision 0) *************** *** 0 **** --- 1,8 ---- + /* { dg-do compile } */ + /* { dg-options "-save-temps -g -dA" } */ + + typedef struct _Harry { int dummy; } Harry_t; + Harry_t harry; + + /* { dg-final { scan-assembler "DW_TAG_typedef\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_name: \"Harry_t\"" } } */ + /* { dg-final { cleanup-saved-temps } } */ Index: gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c =================================================================== *** gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c (revision 0) --- gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c (revision 0) *************** *** 0 **** --- 1,8 ---- + /* { dg-do compile } */ + /* { dg-options "-save-temps -g -dA" } */ + + typedef const struct _Harry { int dummy; } Harry_t; + Harry_t harry; + + /* { dg-final { scan-assembler "DW_TAG_typedef\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_name: \"Harry_t\"" } } */ + /* { dg-final { cleanup-saved-temps } } */ Index: gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c =================================================================== *** gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c (revision 0) --- gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c (revision 0) *************** *** 0 **** --- 1,8 ---- + /* { dg-do compile } */ + /* { dg-options "-save-temps -g -dA" } */ + + typedef struct _Harry { int dummy; } Harry_t; + const Harry_t harry[5]; + + /* { dg-final { scan-assembler "DW_TAG_typedef\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_name: \"Harry_t\"" } } */ + /* { dg-final { cleanup-saved-temps } } */ Index: gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c =================================================================== *** gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c (revision 0) --- gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c (revision 0) *************** *** 0 **** --- 1,8 ---- + /* { dg-do compile } */ + /* { dg-options "-save-temps -g -dA" } */ + + typedef const struct _Harry { int dummy; } Harry_t; + Harry_t harry[10]; + + /* { dg-final { scan-assembler "DW_TAG_typedef\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_name: \"Harry_t\"" } } */ + /* { dg-final { cleanup-saved-temps } } */