From: David Majnemer Date: Tue, 7 Apr 2015 02:37:09 +0000 (+0000) Subject: [Sema] Don't permit dependent alignments on non-dependent typedef-names X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd329541bee4decfa9a632abad77b87f1cf153e4;p=clang [Sema] Don't permit dependent alignments on non-dependent typedef-names A dependent alignment attribute (like __attribute__((aligned(...))) or __declspec(align(...))) on a non-dependent typedef or using declaration poses a considerable challenge: the type is _not_ dependent, the size _may_ be dependent if the type is used as an array type, the alignment _is_ dependent. It is reasonable for a compiler to be able to query the size and alignment of a complete type. Let's help that become an invariant. This fixes PR22042. Differential Revision: http://reviews.llvm.org/D8693 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234280 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index bf0a4608e9..03635ab3e2 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2134,6 +2134,8 @@ def error_cannot_find_suitable_accessor : Error< def err_alignment_not_power_of_two : Error< "requested alignment is not a power of 2">; +def err_alignment_dependent_typedef_name : Error< + "requested alignment is dependent but declaration is not dependent">; def err_attribute_aligned_too_great : Error< "requested alignment must be %0 bytes or smaller">; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 4ef62b9bb5..05a81a8293 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2863,6 +2863,16 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E)) return; + if (E->isValueDependent()) { + if (const auto *TND = dyn_cast(D)) { + if (!TND->getUnderlyingType()->isDependentType()) { + S.Diag(Attr.getLoc(), diag::err_alignment_dependent_typedef_name) + << E->getSourceRange(); + return; + } + } + } + S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(), Attr.isPackExpansion()); } diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp index f51146ccd3..e3690ea926 100644 --- a/test/SemaCXX/alignof.cpp +++ b/test/SemaCXX/alignof.cpp @@ -84,3 +84,16 @@ template void n(T) { static_assert(sizeof(k) == alignof(long long), ""); } template void n(long long); + +namespace PR22042 { +template +void Fun(T A) { + typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}} + int k1[__alignof__(T1)]; +} + +template +struct S { + typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}} +}; +}