]> granicus.if.org Git - clang/commit
Respect alignment of nested bitfields
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 10 Jul 2015 17:30:00 +0000 (17:30 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Fri, 10 Jul 2015 17:30:00 +0000 (17:30 +0000)
commit3517074ea2ddc51c1cd8b66ed1e127b939e3c3d7
treea771414f07bf93b62d9683038c93b1586ee15d61
parent8813b5b29ecb84b0f0a69ecf9f03b57d0979e3e1
Respect alignment of nested bitfields

tools/clang/test/CodeGen/packed-nest-unpacked.c contains this test:

struct XBitfield {
  unsigned b1 : 10;
  unsigned b2 : 12;
  unsigned b3 : 10;
};
struct YBitfield {
  char x;
  struct XBitfield y;
} __attribute((packed));
struct YBitfield gbitfield;

unsigned test7() {
  // CHECK: @test7
  // CHECK: load i32, i32* getelementptr inbounds (%struct.YBitfield, %struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 4
  return gbitfield.y.b2;
}

The "align 4" is actually wrong.  Accessing all of "gbitfield.y" as a single
i32 is of course possible, but that still doesn't make it 4-byte aligned as
it remains packed at offset 1 in the surrounding gbitfield object.

This alignment was changed by commit r169489, which also introduced changes
to bitfield access code in CGExpr.cpp.  Code before that change used to take
into account *both* the alignment of the field to be accessed within the
current struct, *and* the alignment of that outer struct itself; this logic
was removed by the above commit.

Neglecting to consider both values can cause incorrect code to be generated
(I've seen an unaligned access crash on SystemZ due to this bug).

In order to always use the best known alignment value, this patch removes
the CGBitFieldInfo::StorageAlignment member and replaces it with a
StorageOffset member specifying the offset from the start of the surrounding
struct to the bitfield's underlying storage.  This offset can then be combined
with the best-known alignment for a bitfield access lvalue to determine the
alignment to use when accessing the bitfield's storage.

Differential Revision: http://reviews.llvm.org/D11034

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241916 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/CGAtomic.cpp
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGObjCRuntime.cpp
lib/CodeGen/CGRecordLayout.h
lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGen/bitfield-2.c
test/CodeGen/packed-nest-unpacked.c