diff options
| author | Reid Kleckner <reid@kleckner.net> | 2015-03-04 23:39:17 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2015-03-04 23:39:17 +0000 |
| commit | 2a1332245fcbde7a61675c0d22801e2f55f23512 (patch) | |
| tree | e433e4368853e5322c76298805b44de50e32b9b4 /clang | |
| parent | 0eb0efbb630284ffdf569aca9a68c7e15f8397c3 (diff) | |
| download | bcm5719-llvm-2a1332245fcbde7a61675c0d22801e2f55f23512.tar.gz bcm5719-llvm-2a1332245fcbde7a61675c0d22801e2f55f23512.zip | |
Implement section pragma feedback on r205810
Mostly short-circuits some conditionals. Adds target validation of
sections passed to these pragmas.
llvm-svn: 231317
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 12 |
4 files changed, 27 insertions, 8 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4915be49c3d..828bc6f6750 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2822,6 +2822,7 @@ public: bool checkStringLiteralArgumentAttr(const AttributeList &Attr, unsigned ArgNum, StringRef &Str, SourceLocation *ArgLocation = nullptr); + bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); bool checkMSInheritanceAttrOnDefinition( CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceAttr::Spelling SemanticSpelling); diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index e3b66bf9134..5a29bad29f4 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -422,6 +422,9 @@ void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, if (Action & PSK_Pop && Stack->Stack.empty()) Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName << "stack empty"; + if (SegmentName && + !checkSectionName(SegmentName->getLocStart(), SegmentName->getString())) + return; Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b1268cc2336..462854417e1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7403,7 +7403,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setInvalidDecl(); } - if (D.isFunctionDefinition() && CodeSegStack.CurrentValue && + // Apply an implicit SectionAttr if #pragma code_seg is active. + if (CodeSegStack.CurrentValue && D.isFunctionDefinition() && !NewFD->hasAttr<SectionAttr>()) { NewFD->addAttr( SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, @@ -9497,7 +9498,9 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } - if (var->isThisDeclarationADefinition() && + // Apply section attributes and pragmas to global variables. + bool GlobalStorage = var->hasGlobalStorage(); + if (GlobalStorage && var->isThisDeclarationADefinition() && ActiveTemplateInstantiations.empty()) { PragmaStack<StringLiteral *> *Stack = nullptr; int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read; @@ -9510,11 +9513,11 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Stack = &DataSegStack; SectionFlags |= ASTContext::PSF_Write; } - if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue) - var->addAttr( - SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, - Stack->CurrentValue->getString(), - Stack->CurrentPragmaLocation)); + if (Stack->CurrentValue && !var->hasAttr<SectionAttr>()) { + var->addAttr(SectionAttr::CreateImplicit( + Context, SectionAttr::Declspec_allocate, + Stack->CurrentValue->getString(), Stack->CurrentPragmaLocation)); + } if (const SectionAttr *SA = var->getAttr<SectionAttr>()) if (UnifySection(SA->getName(), SectionFlags, var)) var->dropAttr<SectionAttr>(); @@ -9557,7 +9560,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } Expr *Init = var->getInit(); - bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); + bool IsGlobal = GlobalStorage && !var->isStaticLocal(); QualType baseType = Context.getBaseElementType(type); if (!var->getDeclContext()->isDependentContext() && diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4552ad9609e..86aaf3a9207 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2342,6 +2342,15 @@ SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, AttrSpellingListIndex); } +bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) { + std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName); + if (!Error.empty()) { + Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error; + return false; + } + return true; +} + static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Make sure that there is a string literal as the sections's single // argument. @@ -2350,6 +2359,9 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) return; + if (!S.checkSectionName(LiteralLoc, Str)) + return; + // If the target wants to validate the section specifier, make it happen. std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str); if (!Error.empty()) { |

