GCC supports an "aligned" attribute to specify a minimum alignment for
types/objects. However, if an object is allocated on the stack and
its alignment exceeds the "preferred stack boundary", then GCC 4.2
silently ignores the alignment.
This bit us 4 years ago when the SCSI stack started allocating mutexes
on the stack: HPPA mutexes need to be 16-byte aligned, but HPPA's
stack is naturally only 8-byte aligned.
Since newer GCC properly support overly aligned stack allocations, it
seems prudent to at least make base GCC emit a warning if its going to
ignore an alignment request.
With the diff below, compiling a source file like this:
typedef int __attribute__((aligned(512))) aligned_int;
aligned_int good;
void foo() {
aligned_int bad;
}
now produces a warning like this:
$ cc -c test.c
test.c: In function 'foo':
test.c:6: warning: ignoring alignment for stack allocated 'bad'
I verified this doesn't break an amd64 kernel build, but I haven't had
time to look beyond that. Sharing in case anyone's interested and/or
wants to test further themselves.
Index: gcc/cfgexpand.c
===================================================================
RCS file: /home/matthew/cvs-mirror/cvs/src/gnu/gcc/gcc/cfgexpand.c,v
retrieving revision 1.4
diff -u -p -r1.4 cfgexpand.c
--- gcc/cfgexpand.c 6 May 2014 23:32:34 -0000 1.4
+++ gcc/cfgexpand.c 20 Jun 2014 22:55:53 -0000
@@ -159,8 +159,10 @@ get_decl_align_unit (tree decl)
align = DECL_ALIGN (decl);
align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
- if (align > PREFERRED_STACK_BOUNDARY)
+ if (align > PREFERRED_STACK_BOUNDARY) {
+ warning (0, "ignoring alignment for stack allocated %q+D", decl);
align = PREFERRED_STACK_BOUNDARY;
+ }
if (cfun->stack_alignment_needed < align)
cfun->stack_alignment_needed = align;