summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp10
-rw-r--r--clang/test/Sema/attr-section.c4
4 files changed, 22 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1420dabf1e9..0b3c9fed6bd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2620,6 +2620,8 @@ def err_attribute_section_invalid_for_target : Error<
"argument to 'section' attribute is not valid for this target: %0">;
def warn_mismatched_section : Warning<
"section does not match previous declaration">, InGroup<Section>;
+def warn_attribute_section_on_redeclaration : Warning<
+ "section attribute is specified on redeclared variable">, InGroup<Section>;
def err_anonymous_property: Error<
"anonymous property is not supported">;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 03a3e36b831..89185c89518 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2432,6 +2432,12 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
EmitGlobalVarDefinition(D);
}
+ // Emit section information for extern variables.
+ if (D->hasExternalStorage()) {
+ if (const SectionAttr *SA = D->getAttr<SectionAttr>())
+ GV->setSection(SA->getName());
+ }
+
// Handle XCore specific ABI requirements.
if (getTriple().getArch() == llvm::Triple::xcore &&
D->getLanguageLinkage() == CLanguageLinkage &&
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 33f02c5b7f4..c99dbd944b0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2607,6 +2607,16 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
}
}
+ // This redeclaration adds a section attribute.
+ if (New->hasAttr<SectionAttr>() && !Old->hasAttr<SectionAttr>()) {
+ if (auto *VD = dyn_cast<VarDecl>(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;
diff --git a/clang/test/Sema/attr-section.c b/clang/test/Sema/attr-section.c
index c64b10d80ff..2fb4dbd6bfd 100644
--- a/clang/test/Sema/attr-section.c
+++ b/clang/test/Sema/attr-section.c
@@ -19,3 +19,7 @@ void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previou
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}}
OpenPOWER on IntegriCloud