/* If TYPE_SIZE_UNIT overflowed, then it is certainly larger than
TYPE_ALIGN_UNIT. */
&& !TREE_OVERFLOW (TYPE_SIZE_UNIT (element))
- && !integer_zerop (TYPE_SIZE_UNIT (element))
- && compare_tree_int (TYPE_SIZE_UNIT (element),
- TYPE_ALIGN_UNIT (element)) < 0)
- error ("alignment of array elements is greater than element size");
+ && !integer_zerop (TYPE_SIZE_UNIT (element)))
+ {
+ if (compare_tree_int (TYPE_SIZE_UNIT (element),
+ TYPE_ALIGN_UNIT (element)) < 0)
+ error ("alignment of array elements is greater than "
+ "element size");
+ else if (TYPE_ALIGN_UNIT (element) > 1
+ && (wi::zext (wi::to_wide (TYPE_SIZE_UNIT (element)),
+ ffs_hwi (TYPE_ALIGN_UNIT (element)) - 1)
+ != 0))
+ error ("size of array element is not a multiple of its "
+ "alignment");
+ }
break;
}
--- /dev/null
+/* PR tree-optimization/97164 */
+/* { dg-do compile } */
+
+typedef struct { int *a; char b[64]; } A __attribute__((aligned (64)));
+struct B { A d[4]; } b; /* { dg-error "size of array element is not a multiple of its alignment" } */
+void foo (void);
+
+int *
+bar (void)
+{
+ struct B *h = &b;
+ if (h->d[1].a)
+ foo ();
+ return h->d[1].a;
+}
+/* { dg-do compile } */
/* { dg-skip-if "small alignment" { pdp11-*-* } } */
extern void abort (void);
} Bar __attribute__((__aligned__(128)));
typedef struct Foo {
- Bar bar[4];
+ Bar bar[4]; /* { dg-error "size of array element is not a multiple of its alignment" } */
} Foo;
Foo foo[4];
+/* { dg-do compile } */
+/* { dg-options "" } */
/* { dg-skip-if "small alignment" { pdp11-*-* } } */
typedef __attribute__((aligned(16)))
unsigned long long w[3];
} UINT192;
-UINT192 bid_Kx192[32];
+UINT192 bid_Kx192[32]; /* { dg-error "size of array element is not a multiple of its alignment" } */
extern void abort (void);