From: Reid Kleckner Date: Wed, 4 Mar 2015 23:39:17 +0000 (+0000) Subject: Implement section pragma feedback on r205810 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=54ccb9465233d79b0dd0c887860bde588c309a76;p=clang Implement section pragma feedback on r205810 Mostly short-circuits some conditionals. Adds target validation of sections passed to these pragmas. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231317 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4915be49c3..828bc6f675 100644 --- a/include/clang/Sema/Sema.h +++ b/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/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index e3b66bf913..5a29bad29f 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b1268cc233..462854417e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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()) { 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 *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() && Stack->CurrentValue) - var->addAttr( - SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, - Stack->CurrentValue->getString(), - Stack->CurrentPragmaLocation)); + if (Stack->CurrentValue && !var->hasAttr()) { + var->addAttr(SectionAttr::CreateImplicit( + Context, SectionAttr::Declspec_allocate, + Stack->CurrentValue->getString(), Stack->CurrentPragmaLocation)); + } if (const SectionAttr *SA = var->getAttr()) if (UnifySection(SA->getName(), SectionFlags, var)) var->dropAttr(); @@ -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/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 4552ad9609..86aaf3a920 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/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()) {