Prior to this, the following would fail:
template <typename T> using NaturallyAligned [[gnu::aligned(sizeof(T))]] = T; struct S { char x[2]; }; using AlignedS = NaturallyAligned<S>; static_assert(alignof(AlignedS) == 2); // alignof(AlignedS) == 1
This is because clang ignores attributes on type aliases when evaluating type info and instead resolves to alignment of the replacement type T.
This patch attempts to check if the associated type declaration is an alias that contains an attribute and return whatever the value is indicated by the alignment expression.
I don't think this approach is going to work out well. There are many cases this gets wrong, fixing them would require reinventing template substitution here, and generally we shouldn't be doing this substitution as part of alignment computation at all -- we should have TreeTransform produce the right alignment value during template instantiation and just pull it back out of the Type here. We can't really use the same approach as we do for TypedefDecls, though, because we don't instantiate a TypeAliasDecl for each use of a TypeAliasTemplateDecl, so there's nowhere to hang an instantiated attribute. But the handling for TypedefTypes is also fairly painful, so I think we should be considering an approach that makes both of them more elegant. Here's what I suggest: