http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47939
--- Comment #7 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-03-01 17:01:38 UTC --- (In reply to comment #6) > On Tue, 1 Mar 2011, rguenth at gcc dot gnu.org wrote: > > > The patch bootstrapped and tested ok. Removing > > > > if (!flag_gen_aux_info && (TYPE_QUALS (element_type))) > > type = TYPE_MAIN_VARIANT (type); > > > > unconditionally breaks gcc.dg/array-quals-2.c (but nothing else). > > The point of the logic removing qualifiers here is as described in the > comment > > /* Now figure out the structure of the declarator proper. > Descend through it, creating more complex types, until we reach > the declared identifier (or NULL_TREE, in an absolute declarator). > At each stage we maintain an unqualified version of the type > together with any qualifiers that should be applied to it with > c_build_qualified_type; this way, array types including > multidimensional array types are first built up in unqualified > form and then the qualified form is created with > TYPE_MAIN_VARIANT pointing to the unqualified form. */ > > to ensure consistency in TYPE_MAIN_VARIANT for array types; see > <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg02180.html>. > > > Probably a better general approach would be to make c_build_qualified_type > > also take a desired name as argument instead of using TYPE_NAME. > > In general it's a desired name for an intermediate type at some level of > array derivation, not for the type being constructed by > c_build_qualified_type. I suppose you could pass both the name and the > particular type that should have that name, or otherwise indicate the > qualifiers and level of array nesting where the name should be used if > possible. > > If you have > > typedef const int T[1]; > T array[2][3]; > > then "const" is being applied to "int [2][3][1]", and it's the > intermediate type "const int [1]" that you'd like to get the name T. I see. There is an alternative way to stripping qualifiers - build an unqualified variant like with Index: gcc/c-decl.c =================================================================== --- gcc/c-decl.c (revision 170594) +++ gcc/c-decl.c (working copy) @@ -5038,8 +5038,8 @@ grokdeclarator (const struct c_declarato 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); + if (TYPE_QUALS (element_type)) + type = c_build_qualified_type (type, 0); type_quals = ((constp ? TYPE_QUAL_CONST : 0) | (restrictp ? TYPE_QUAL_RESTRICT : 0) | (volatilep ? TYPE_QUAL_VOLATILE : 0) or alternatively using build_qualified_type directly to not strip qualifiers recursively at this point. That would preserve the type-names but also introduce a unqualified variants with that name if it doesn't exist already. To avoid the latter in c_build_qualified_type we could pass TYPE_MAIN_VARIANT to the build_qualified_type calls. I don't know if I'm the correct person to try fixing this (I'm certainly new to this part of the code), but at least the flag_gen_aux_info checking looks suspicious and should be removed.