https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101312
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <[email protected]>: https://gcc.gnu.org/g:3d2a91a3767982dde5a37abf45c12c08d4fdbf41 commit r16-7102-g3d2a91a3767982dde5a37abf45c12c08d4fdbf41 Author: Jakub Jelinek <[email protected]> Date: Wed Jan 28 09:50:26 2026 +0100 c, c++: Use c*_build_qualified_type instead of build_qualified_type from within build_type_attribute_qual_variant [PR101312] The following testcases ICE in various ways because of the interaction between attributes and C/C++ c*_build_qualified_type behavior on array types and how they affect TYPE_CANONICAL. For array types, C/C++ moves qualifiers to the element type, but when a cv qualified array build that way has an attribute applied to it, we call build_type_attribute_qual_variant and that doesn't have that handling and builds non-qualified version of the array type with qualified element type and puts it as TYPE_CANONICAL of the type with attribute which is a distinct type copy. The following patch adds a langhook, so that even build_type_attribute_qual_variant uses for C/C++ for array types c*_build_qualified_type. There has been already a related langhook lang_hooks.types.copy_lang_qualifiers used solely for C++, so instead of adding another langhook this adds a combined langhook for those two, where C can handle array types specially and otherwise build_qualified_type, while C++ ditto + do the function/method type modifiers propagation as well. Unfortunately there is a terrible array_as_string hack used by some of the middle-end warnings which creates some array type with sometimes an artificial attribute and then has hacks in the c-family type printing to tweak the printed form, and this hack relies on the previous behavior of build_type_attribute_qual_variant where it even for C/C++ kept element type quals unmodified and added normally invalid quals on the array type itself. The patch stops using build_type_attribute_qual_variant for that and instead uses copy_node on the type and adjusts the quals and adds the attribute to the copy and then ggc_frees it. Also it renames the attribute from "array" to "array " to make it clear it is internal attribute users can't specify even in vendor attributes. 2026-01-28 Jakub Jelinek <[email protected]> PR c/101312 gcc/ * langhooks.h (struct lang_hooks_for_types): Remove copy_lang_qualifiers. Add build_lang_qualified_type. * langhooks.cc (lhd_build_lang_qualified_type): New function. * langhooks-def.h (lhd_build_lang_qualified_type): Declare. (LANG_HOOKS_COPY_LANG_QUALIFIERS): Remove. (LANG_HOOKS_BUILD_LANG_QUALIFIED_TYPE): Add. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Use LANG_HOOKS_BUILD_LANG_QUALIFIED_TYPE instead of LANG_HOOKS_COPY_LANG_QUALIFIERS. * attribs.cc (build_type_attribute_qual_variant): Use lang_hooks.types.build_lang_qualified_type instead of build_qualified_type and/or build_qualified_type with optional lang_hooks.types.copy_lang_qualifiers call. (attr_access::array_as_string): Use "array " attribute instead of "array". If attribute has been created or intended quals differ from quals of build_array_type, use copy_node and adjust quals and attributes on the copy, print and then ggc_free. gcc/c-family/ * c-pretty-print.cc (c_pretty_printer::direct_abstract_declarator): Look up "array " attribute instead of "array". gcc/c/ * c-tree.h (c_build_lang_qualified_type): Declare. * c-objc-common.h (LANG_HOOKS_BUILD_LANG_QUALIFIED_TYPE): Define. * c-objc-common.cc (c_build_lang_qualified_type): New function. gcc/cp/ * cp-tree.h (cxx_build_lang_qualified_type): Declare. * cp-objcp-common.h (LANG_HOOKS_COPY_LANG_QUALIFIERS): Remove. (LANG_HOOKS_BUILD_LANG_QUALIFIED_TYPE): Define. * tree.cc (cxx_build_lang_qualified_type): New function. gcc/testsuite/ * c-c++-common/pr101312-1.c: New test. * c-c++-common/pr101312-2.c: New test.
