forked from OSchip/llvm-project
Relaxing the alignment requirements for fields in a transparent_union. Emits the diagnostic only when subsequent alignments are more strict than the alignment required by the first field.
Fixes PR15134 llvm-svn: 200277
This commit is contained in:
parent
bdc2fc3635
commit
54fe5eb8cb
|
@ -2664,8 +2664,13 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D,
|
|||
uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
|
||||
for (; Field != FieldEnd; ++Field) {
|
||||
QualType FieldType = Field->getType();
|
||||
// FIXME: this isn't fully correct; we also need to test whether the
|
||||
// members of the union would all have the same calling convention as the
|
||||
// first member of the union. Checking just the size and alignment isn't
|
||||
// sufficient (consider structs passed on the stack instead of in registers
|
||||
// as an example).
|
||||
if (S.Context.getTypeSize(FieldType) != FirstSize ||
|
||||
S.Context.getTypeAlign(FieldType) != FirstAlign) {
|
||||
S.Context.getTypeAlign(FieldType) > FirstAlign) {
|
||||
// Warn if we drop the attribute.
|
||||
bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
|
||||
unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
|
||||
|
|
|
@ -70,4 +70,22 @@ typedef union {
|
|||
int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4'; transparent_union attribute ignored}}
|
||||
} TU5 __attribute__((transparent_union));
|
||||
|
||||
|
||||
union pr15134 {
|
||||
unsigned int u;
|
||||
struct {
|
||||
unsigned int expo:2;
|
||||
unsigned int mant:30;
|
||||
} __attribute__((packed));
|
||||
// The packed attribute is acceptable because it defines a less strict
|
||||
// alignment than required by the first field of the transparent union.
|
||||
} __attribute__((transparent_union));
|
||||
|
||||
union pr15134v2 {
|
||||
struct { // expected-note {{alignment of first field is 32 bits}}
|
||||
unsigned int u1;
|
||||
unsigned int u2;
|
||||
};
|
||||
struct { // expected-warning {{alignment of field '' (64 bits) does not match the alignment of the first field in transparent union; transparent_union attribute ignored}}
|
||||
unsigned int u3;
|
||||
} __attribute__((aligned(8)));
|
||||
} __attribute__((transparent_union));
|
||||
|
|
Loading…
Reference in New Issue