Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2611,6 +2611,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: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2431,6 +2431,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: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -2607,6 +2607,14 @@ } } + // This redeclaration adds a section attribute to a declaration that has + // already been ODR-used. + if (New->hasAttr() && !Old->hasAttr() && + Old->isUsed()) { + Diag(New->getLocation(), diag::warn_attribute_section_on_redeclaration); + Diag(Old->getLocation(), diag::note_previous_declaration); + } + if (!Old->hasAttrs()) return; Index: test/CodeGenCXX/extern-section-attribute.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/extern-section-attribute.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu | FileCheck %s + +extern int aa __attribute__((section(".sdata"))); +// CHECK-DAG: @aa = external global i32, section ".sdata", align 4 + +extern int bb __attribute__((section(".sdata"))) = 1; +// CHECK-DAG: @bb = global i32 1, section ".sdata", align 4 + +int foo() { + return aa + bb; +} Index: test/Sema/attr-section.c =================================================================== --- test/Sema/attr-section.c +++ 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}}