In the following testcase we error on the first case because it is
trying to construct an array from overaligned type, but if there are
qualifiers, we accept it silently (unlike in C++ which diagnoses all 3).
The problem is that grokdeclarator if TYPE_QUALS (element_type) is
non-zero just uses TYPE_MAIN_VARIANT; that loses not just the qualifiers
but also attributes, alignment etc.
The following patch uses c_build_qualified_type with TYPE_UNQUALIFIED instead,
which will be in the common case the same as TYPE_MAIN_VARIANT if the
checks are satisfied for it, but if not, will look up different unqualified
type or even create it if there is none.
2025-01-28 Jakub Jelinek <jakub@redhat.com>
PR c/116357
* c-decl.cc (grokdeclarator): Use c_build_qualified_type with
TYPE_UNQUALIFIED instead of TYPE_MAIN_VARIANT.
* gcc.dg/pr116357.c: New test.
&& TYPE_QUALS (element_type))
{
orig_qual_type = type;
- type = TYPE_MAIN_VARIANT (type);
+ type = c_build_qualified_type (type, TYPE_UNQUALIFIED);
}
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
--- /dev/null
+/* PR c/116357 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef int A __attribute__((aligned (2 * alignof (int))));
+A a[4]; /* { dg-error "alignment of array elements is greater than element size" } */
+typedef volatile int B __attribute__((aligned (2 * alignof (int))));
+B b[4]; /* { dg-error "alignment of array elements is greater than element size" } */
+typedef const int C __attribute__((aligned (2 * alignof (int))));
+C c[4]; /* { dg-error "alignment of array elements is greater than element size" } */