diff options
author | Paul Robinson <paul_robinson@playstation.sony.com> | 2015-07-14 20:52:32 +0000 |
---|---|---|
committer | Paul Robinson <paul_robinson@playstation.sony.com> | 2015-07-14 20:52:32 +0000 |
commit | d30e2eefc3cf8dfd2210aefd62f13a6e7c011b43 (patch) | |
tree | da56b0a2d44bbea3502c01394eb565e2faaff7c6 /clang/lib/Sema/SemaDecl.cpp | |
parent | 16270a0b09f6918f9785aad0cbf531798f297d6c (diff) | |
download | bcm5719-llvm-d30e2eefc3cf8dfd2210aefd62f13a6e7c011b43.tar.gz bcm5719-llvm-d30e2eefc3cf8dfd2210aefd62f13a6e7c011b43.zip |
Add a "maximum TLS alignment" characteristic to the target info, so it
can be different from the normal variable maximum.
Add an error diagnostic for when TLS variables exceed maximum TLS alignment.
Currenty only PS4 sets an explicit maximum TLS alignment.
Patch by Charles Li!
llvm-svn: 242198
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5646099015b..99d4a79c466 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9828,6 +9828,16 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { FinalizeVarWithDestructor(var, recordType); } +/// \brief Determines if a variable's alignment is dependent. +static bool hasDependentAlignment(VarDecl *VD) { + if (VD->getType()->isDependentType()) + return true; + for (auto *I : VD->specific_attrs<AlignedAttr>()) + if (I->isAlignmentDependent()) + return true; + return false; +} + /// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform /// any semantic actions necessary after any initializer has been attached. void @@ -9841,6 +9851,22 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { 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() && !hasDependentAlignment(VD)) { + 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(); + } + } + } + // Static locals inherit dll attributes from their function. if (VD->isStaticLocal()) { if (FunctionDecl *FD = |