From 420efd83934ee78f04d73880e2ed1b7fdef3328c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 13 May 2012 02:42:42 +0000 Subject: [PATCH] Produce a warning for mismatched section attributes. Completest pr9356. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156727 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 1 + include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ include/clang/Sema/Sema.h | 2 ++ lib/Sema/SemaDecl.cpp | 3 +++ lib/Sema/SemaDeclAttr.cpp | 20 +++++++++++++++++--- test/Sema/attr-section.c | 4 ++++ 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 17852ae1e1..8493257ba5 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -25,6 +25,7 @@ def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">; def : DiagGroup<"attributes">; def : DiagGroup<"bad-function-cast">; def Availability : DiagGroup<"availability">; +def Section : DiagGroup<"section">; def AutoImport : DiagGroup<"auto-import">; def ConstantConversion : DiagGroup<"constant-conversion">; def LiteralConversion : DiagGroup<"literal-conversion">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index ddb8b280fb..2b7875b332 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1567,10 +1567,14 @@ def warn_objc_redundant_literal_use : Warning< def err_only_annotate_after_access_spec : Error< "access specifier can only have annotation attributes">; + def err_attribute_section_invalid_for_target : Error< "argument to 'section' attribute is not valid for this target: %0">; def err_attribute_section_local_variable : Error< "'section' attribute is not valid on local variables">; +def warn_mismatched_section : Warning< + "section does not match previous declaration">, InGroup
; + def err_attribute_aligned_not_power_of_two : Error< "requested alignment is not a power of 2">; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index b43a69929f..3e03befba9 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1572,6 +1572,8 @@ public: bool mergeDLLExportAttr(Decl *D, SourceRange Range, bool Inherited); bool mergeFormatAttr(Decl *D, SourceRange Range, bool Inherited, StringRef Format, int FormatIdx, int FirstArg); + bool mergeSectionAttr(Decl *D, SourceRange Range, bool Inherited, + StringRef Name); bool mergeDeclAttribute(Decl *New, InheritableAttr *Attr); void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 64caf2bacc..9828c180b1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1678,6 +1678,9 @@ bool Sema::mergeDeclAttribute(Decl *D, InheritableAttr *Attr) { return mergeFormatAttr(D, FA->getRange(), true, FA->getType(), FA->getFormatIdx(), FA->getFirstArg()); + if (SectionAttr *SA = dyn_cast(Attr)) + return mergeSectionAttr(D, SA->getRange(), true, SA->getName()); + if (!DeclHasAttr(D, Attr)) { InheritableAttr *NewAttr = cast(Attr->clone(Context)); NewAttr->setInherited(true); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 7c290f76ee..947fe7af91 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2286,6 +2286,22 @@ static void handleReqdWorkGroupSize(Sema &S, Decl *D, WGSize[2])); } +bool Sema::mergeSectionAttr(Decl *D, SourceRange Range, bool Inherited, + StringRef Name) { + if (SectionAttr *ExistingAttr = D->getAttr()) { + if (ExistingAttr->getName() == Name) + return false; + Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); + Diag(Range.getBegin(), diag::note_previous_attribute); + return false; + } + SectionAttr *Attr = ::new (Context) SectionAttr(Range, Context, Name); + if (Inherited) + Attr->setInherited(true); + D->addAttr(Attr); + return true; +} + static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Attribute has no arguments. if (!checkAttributeNumArgs(S, Attr, 1)) @@ -2313,9 +2329,7 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); return; } - - D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context, - SE->getString())); + S.mergeSectionAttr(D, Attr.getRange(), false, SE->getString()); } diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c index a932525408..69ca732517 100644 --- a/test/Sema/attr-section.c +++ b/test/Sema/attr-section.c @@ -13,3 +13,7 @@ void test() { __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}} __attribute__((section("NEAR,x"))) static int n2; // ok. } + +// pr9356 +void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}} +void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}} -- 2.40.0