Produce a warning for mismatched section attributes. Completest pr9356.

llvm-svn: 156727
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 64caf2b..9828c18 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1678,6 +1678,9 @@
     return mergeFormatAttr(D, FA->getRange(), true, FA->getType(),
                            FA->getFormatIdx(), FA->getFirstArg());
 
+  if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr))
+    return mergeSectionAttr(D, SA->getRange(), true, SA->getName());
+
   if (!DeclHasAttr(D, Attr)) {
     InheritableAttr *NewAttr = cast<InheritableAttr>(Attr->clone(Context));
     NewAttr->setInherited(true);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7c290f7..947fe7a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2286,6 +2286,22 @@
                                                      WGSize[2]));
 }
 
+bool Sema::mergeSectionAttr(Decl *D, SourceRange Range, bool Inherited,
+                            StringRef Name) {
+  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
+    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 @@
     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());
 }