r200277 - 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.
Aaron Ballman
aaron at aaronballman.com
Mon Jan 27 17:47:35 PST 2014
Author: aaronballman
Date: Mon Jan 27 19:47:34 2014
New Revision: 200277
URL: http://llvm.org/viewvc/llvm-project?rev=200277&view=rev
Log:
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
Modified:
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/Sema/transparent-union.c
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=200277&r1=200276&r2=200277&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Jan 27 19:47:34 2014
@@ -2664,8 +2664,13 @@ static void handleTransparentUnionAttr(S
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)
Modified: cfe/trunk/test/Sema/transparent-union.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/transparent-union.c?rev=200277&r1=200276&r2=200277&view=diff
==============================================================================
--- cfe/trunk/test/Sema/transparent-union.c (original)
+++ cfe/trunk/test/Sema/transparent-union.c Mon Jan 27 19:47:34 2014
@@ -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));
More information about the cfe-commits
mailing list