ychen created this revision. ychen added reviewers: probinson, mizvekov. Herald added a project: All. ychen requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
follow up d30e2eefc3cf8dfd2210aefd62f13a6e7c011b43 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136744 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/Sema/tls_alignment.cpp
Index: clang/test/Sema/tls_alignment.cpp =================================================================== --- clang/test/Sema/tls_alignment.cpp +++ clang/test/Sema/tls_alignment.cpp @@ -58,27 +58,34 @@ bar5.some_data[5]; } - -// Verify alignment check where a dependent type is involved. -// The check is (correctly) not performed on "t", but the check still is -// performed on the structure as a whole once it has been instantiated. - template<class T> struct templated_tls { static __thread T t; T other_t __attribute__(( aligned(64) )); }; -__thread templated_tls<int> blah; // expected-error{{alignment (64) of thread-local variable}} - -int blag() { - return blah.other_t * 2; -} + __thread templated_tls<int> blah; // expected-error{{alignment (64) of thread-local variable}} - -// Verify alignment check where the alignment is a template parameter. -// The check is only performed during instantiation. template <int N> struct S { + struct alignas(64) B {}; + struct alignas(N) C {}; + static inline void f() { + thread_local B b; // expected-error{{alignment (64) of thread-local variable}} + thread_local C c; // expected-error{{alignment (64) of thread-local variable}} + } + template<int J> static inline thread_local int b alignas(J) = J; // expected-error{{alignment (64) of thread-local variable}} static int __thread __attribute__((aligned(N))) x; // expected-error{{alignment (64) of thread-local variable}} }; -S<64> s_instance; // expected-note{{in instantiation of template class 'S<64>' requested here}} +int blag() { + // Verify alignment check where the alignment is a template parameter. + // The check is only performed during instantiation. + S<64> s_instance; // expected-note{{in instantiation of template class 'S<64>' requested here}} + + // Verify alignment for dependent local variables. + S<64>::f(); // expected-note{{in instantiation of member function 'S<64>::f' requested here}} + + // Verify alignment check where a dependent type is involved. + // The check is (correctly) not performed on "t", but the check still is + // performed on the structure as a whole once it has been instantiated. + return blah.other_t * 2 + S<64>::b<64>; // expected-note{{in instantiation of static data member 'S<64>::b' requested here}} +} Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1179,6 +1179,9 @@ if (Var->isStaticLocal()) SemaRef.CheckStaticLocalForDllExport(Var); + if (Var->getTLSKind()) + SemaRef.CheckThreadLocalForLargeAlignment(Var); + return Var; } Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -14032,6 +14032,29 @@ } } +void Sema::CheckThreadLocalForLargeAlignment(VarDecl *VD) { + assert(VD->getTLSKind()); + + if (!Context.getTargetInfo().isTLSSupported()) + return; + + // Perform TLS alignment check here after attributes attached to the variable + // which may affect the alignment have been processed. Only perform the check + // if the target has a maximum TLS alignment (zero means no constraints). + if (unsigned MaxAlign = Context.getTargetInfo().getMaxTLSAlign()) { + // Protect the check so that it's not performed on dependent types and + // dependent alignments (we can't determine the alignment in that case). + if (!VD->hasDependentAlignment()) { + CharUnits MaxAlignChars = Context.toCharUnitsFromBits(MaxAlign); + if (Context.getDeclAlign(VD) > MaxAlignChars) { + Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum) + << (unsigned)Context.getDeclAlign(VD).getQuantity() << VD + << (unsigned)MaxAlignChars.getQuantity(); + } + } + } +} + /// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform /// any semantic actions necessary after any initializer has been attached. void Sema::FinalizeDeclaration(Decl *ThisDecl) { @@ -14075,25 +14098,12 @@ checkAttributesAfterMerging(*this, *VD); - // Perform TLS alignment check here after attributes attached to the variable - // which may affect the alignment have been processed. Only perform the check - // if the target has a maximum TLS alignment (zero means no constraints). - if (unsigned MaxAlign = Context.getTargetInfo().getMaxTLSAlign()) { - // Protect the check so that it's not performed on dependent types and - // dependent alignments (we can't determine the alignment in that case). - if (VD->getTLSKind() && !VD->hasDependentAlignment()) { - CharUnits MaxAlignChars = Context.toCharUnitsFromBits(MaxAlign); - if (Context.getDeclAlign(VD) > MaxAlignChars) { - Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum) - << (unsigned)Context.getDeclAlign(VD).getQuantity() << VD - << (unsigned)MaxAlignChars.getQuantity(); - } - } - } - if (VD->isStaticLocal()) CheckStaticLocalForDllExport(VD); + if (VD->getTLSKind()) + CheckThreadLocalForLargeAlignment(VD); + // Perform check for initializers of device-side global variables. // CUDA allows empty constructors as initializers (see E.2.3.1, CUDA // 7.5). We must also apply the same checks to all __shared__ Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -3013,6 +3013,7 @@ void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); void CheckStaticLocalForDllExport(VarDecl *VD); + void CheckThreadLocalForLargeAlignment(VarDecl *VD); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef<Decl *> Group);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits