diff options
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 094e5b5..1a12208 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Sema.h" +#include "TargetAttributesSema.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" @@ -925,14 +926,19 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { // If the target wants to validate the section specifier, make it happen. std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); - if (Error.empty()) { - D->addAttr(::new (S.Context) SectionAttr(SE->getString())); + if (!Error.empty()) { + S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) + << Error; return; } - S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) - << Error; - + // This attribute cannot be applied to local variables. + if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { + S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); + return; + } + + D->addAttr(::new (S.Context) SectionAttr(SE->getString())); } static void HandleCDeclAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1959,7 +1965,10 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D, // Just ignore break; default: - S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); + // Ask target about the attribute. + const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); + if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) + S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); break; } } |