-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type: attributed types should check for aligned
attr for computing alignment
#370
Conversation
Actually, this doesn't entirely fix things because it looks like alignment can only be adjusted downward by a typedef: __attribute__((aligned(2))) typedef struct { int a; } X;
_Static_assert(_Alignof(X) == 2, "");
typedef struct { int a; } __attribute__((aligned(2))) Y;
_Static_assert(_Alignof(Y) == 4, ""); // fails in arocc
typedef struct { int a; } __attribute__((aligned(16))) Z;
_Static_assert(_Alignof(Z) == 16, "");
|
@@ -890,7 +890,7 @@ pub fn alignof(ty: Type, comp: *const Compilation) u29 { | |||
.@"enum" => if (ty.data.@"enum".isIncomplete() and !ty.data.@"enum".fixed) 0 else ty.data.@"enum".tag_ty.alignof(comp), | |||
.typeof_type, .decayed_typeof_type => ty.data.sub_type.alignof(comp), | |||
.typeof_expr, .decayed_typeof_expr => ty.data.expr.ty.alignof(comp), | |||
.attributed => ty.data.attributed.base.alignof(comp), | |||
.attributed => ty.requestedAlignment(comp) orelse ty.data.attributed.base.alignof(comp), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks layout test 0002
typedef struct {
long long c;
} __attribute__((aligned(1))) X;
_Static_assert(sizeof(X) == 8, "");
_Static_assert(_Alignof(X) == 8, "");
The _Alignof
fails because the requested alignment is being returned, rather than the computed alignment.
one odd thing : I don't see why this change is different to the record check at the top of the fn? Doesn't that return the requested alignment for all non-records?
If you want to keep this, then you can change the record check to not fall-though, and do the recursion right there. Then this might work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case it is a record (attributed record). As far as I can tell a couple things are going on: __attribute__((aligned(N)))
directly on a record overrides the record's computed alignment, unless it's being asked to decrease the alignment. Putting the attribute on a typedef, however, can decrease the alignment. So in the example you just posted, the attribute is on the anonymous struct, which is being typedef'ed to the name X
. Since the attribute is directly on the struct, it can't reduce the alignment to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
But you can tell if the attributes are in front of or behind the typedef, and respond accordingly? So if Type
looks like .attribute -> .typeof_type -> .record
you return the attribute. If it looks like .typeof_type -> .attribute -> .record
you return the computed record alignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof_type
is for typeof(X)
, not typedefs. The problem is that, conceptually, alignof()
a record type needs to consider attributes if it's a typedef'ed type, and not consider them if it's not. But I don't think that info is currently available at the time alignof
is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think it's compiler-dependent. For MSVC it looks like decels before the typedef are "for" the record, not the type.
Fixes #367