From b4587293a53a4da4553a1a28ca460d0c84c6e5df Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 5 May 2014 20:21:03 +0000 Subject: [PATCH] Fix pr19653. Warn if an alias requests a section other than the aliasee section. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207997 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 ++ lib/CodeGen/CodeGenModule.cpp | 34 +++++++++++++++------- lib/CodeGen/CodeGenModule.h | 2 ++ test/CodeGen/alias.c | 5 ++++ test/Sema/attr-alias-elf.c | 8 +++++ 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7c4f988353..eadf4e747c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2106,6 +2106,9 @@ def err_alias_to_undefined : Error< def warn_alias_to_weak_alias : Warning< "alias will always resolve to %0 even if weak definition of alias %1 is overridden">, InGroup; +def warn_alias_with_section : Warning< + "alias will not be in section '%0' but in the same section as the aliasee">, + InGroup; def err_duplicate_mangled_name : Error< "definition with same mangled name as another definition">; def err_cyclic_alias : Error< diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index caa4f24899..9c60eb55f8 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -238,11 +238,6 @@ void CodeGenModule::checkAliases() { Diags.Report(AA->getLocation(), diag::err_alias_to_undefined); } - // We have to handle alias to weak aliases in here. LLVM itself disallows - // this since the object semantics would not match the IL one. For - // compatibility with gcc we implement it by just pointing the alias - // to its aliasee's aliasee. We also warn, since the user is probably - // expecting the link to be weak. llvm::Constant *Aliasee = Alias->getAliasee(); llvm::GlobalValue *AliaseeGV; if (auto CE = dyn_cast(Aliasee)) { @@ -253,6 +248,19 @@ void CodeGenModule::checkAliases() { } else { AliaseeGV = cast(Aliasee); } + + if (const SectionAttr *SA = D->getAttr()) { + StringRef AliasSection = SA->getName(); + if (AliasSection != AliaseeGV->getSection()) + Diags.Report(SA->getLocation(), diag::warn_alias_with_section) + << AliasSection; + } + + // We have to handle alias to weak aliases in here. LLVM itself disallows + // this since the object semantics would not match the IL one. For + // compatibility with gcc we implement it by just pointing the alias + // to its aliasee's aliasee. We also warn, since the user is probably + // expecting the link to be weak. if (auto GA = dyn_cast(AliaseeGV)) { if (GA->mayBeOverridden()) { Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias) @@ -585,7 +593,7 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) { /// variables (these details are set in EmitGlobalVarDefinition for variables). void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D, llvm::GlobalValue *GV) { - SetCommonAttributes(D, GV); + setNonAliasAttributes(D, GV); } void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D, @@ -711,13 +719,17 @@ void CodeGenModule::SetCommonAttributes(const Decl *D, if (D->hasAttr()) addUsedGlobal(GV); +} + +void CodeGenModule::setNonAliasAttributes(const Decl *D, + llvm::GlobalValue *GV) { + assert(!isa(GV)); + SetCommonAttributes(D, GV); if (const SectionAttr *SA = D->getAttr()) GV->setSection(SA->getName()); - // Alias cannot have attributes. Filter them here. - if (!isa(GV)) - getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); + getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this); } void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, @@ -728,7 +740,7 @@ void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, F->setLinkage(llvm::Function::InternalLinkage); - SetCommonAttributes(D, F); + setNonAliasAttributes(D, F); } static void setLinkageAndVisibilityForGV(llvm::GlobalValue *GV, @@ -1879,7 +1891,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // common vars aren't constant even if declared const. GV->setConstant(false); - SetCommonAttributes(D, GV); + setNonAliasAttributes(D, GV); // Emit the initializer function if necessary. if (NeedsGlobalCtor || NeedsGlobalDtor) diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 419324d7d8..4a1573b849 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -1050,6 +1050,8 @@ private: /// NOTE: This should only be called for definitions. void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV); + void setNonAliasAttributes(const Decl *D, llvm::GlobalValue *GV); + /// SetFunctionDefinitionAttributes - Set attributes for a global definition. void SetFunctionDefinitionAttributes(const FunctionDecl *D, llvm::GlobalValue *GV); diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c index 4a89b13be9..98449d36ed 100644 --- a/test/CodeGen/alias.c +++ b/test/CodeGen/alias.c @@ -16,6 +16,7 @@ extern void f1(void) __attribute((alias("f0"))); // CHECKBASIC-DAG: @f1 = alias void ()* @f0 // CHECKBASIC-DAG: @test8_foo = alias weak bitcast (void ()* @test8_bar to void (...)*) // CHECKBASIC-DAG: @test8_zed = alias bitcast (void ()* @test8_bar to void (...)*) +// CHECKBASIC-DAG: @test9_zed = alias void ()* @test9_bar // CHECKBASIC: define void @f0() [[NUW:#[0-9]+]] { // Make sure that aliases cause referenced values to be emitted. @@ -54,3 +55,7 @@ int outer_weak(int a) { return inner_weak_a(a); } void test8_bar() {} void test8_foo() __attribute__((weak, alias("test8_bar"))); void test8_zed() __attribute__((alias("test8_foo"))); + +void test9_bar(void) { } +void test9_zed(void) __attribute__((section("test"))); +void test9_zed(void) __attribute__((alias("test9_bar"))); diff --git a/test/Sema/attr-alias-elf.c b/test/Sema/attr-alias-elf.c index 01bc1879dc..04d13924ac 100644 --- a/test/Sema/attr-alias-elf.c +++ b/test/Sema/attr-alias-elf.c @@ -56,3 +56,11 @@ typedef int b4; void test2_bar() {} void test2_foo() __attribute__((weak, alias("test2_bar"))); void test2_zed() __attribute__((alias("test2_foo"))); // expected-warning {{alias will always resolve to test2_bar even if weak definition of alias test2_foo is overridden}} + +void test3_bar() { } +void test3_foo() __attribute__((section("test"))); // expected-warning {{alias will not be in section 'test' but in the same section as the aliasee}} +void test3_foo() __attribute__((alias("test3_bar"))); + +__attribute__((section("test"))) void test4_bar() { } +void test4_foo() __attribute__((section("test"))); +void test4_foo() __attribute__((alias("test4_bar"))); -- 2.40.0