Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -2620,6 +2620,8 @@ "argument to 'section' attribute is not valid for this target: %0">; def warn_mismatched_section : Warning< "section does not match previous declaration">, InGroup
; +def warn_attribute_section_on_redeclaration : Warning< + "section attribute is specified on redeclared variable">, InGroup
; def err_anonymous_property: Error< "anonymous property is not supported">; Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -2432,6 +2432,12 @@ EmitGlobalVarDefinition(D); } + // Emit section information for extern variables. + if (D->hasExternalStorage()) { + if (const SectionAttr *SA = D->getAttr()) + GV->setSection(SA->getName()); + } + // Handle XCore specific ABI requirements. if (getTriple().getArch() == llvm::Triple::xcore && D->getLanguageLinkage() == CLanguageLinkage && Index: cfe/trunk/lib/Sema/SemaDecl.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -2607,6 +2607,16 @@ } } + // This redeclaration adds a section attribute. + if (New->hasAttr() && !Old->hasAttr()) { + if (auto *VD = dyn_cast(New)) { + if (VD->isThisDeclarationADefinition() != VarDecl::Definition) { + Diag(New->getLocation(), diag::warn_attribute_section_on_redeclaration); + Diag(Old->getLocation(), diag::note_previous_declaration); + } + } + } + if (!Old->hasAttrs()) return; Index: cfe/trunk/test/Sema/attr-section.c =================================================================== --- cfe/trunk/test/Sema/attr-section.c +++ cfe/trunk/test/Sema/attr-section.c @@ -19,3 +19,7 @@ void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}} enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}} + +extern int a; // expected-note {{previous declaration is here}} +int *b = &a; +extern int a __attribute__((section("foo,zed"))); // expected-warning {{section attribute is specified on redeclared variable}}