Refactor how -fno-semantic-interposition sets dso_local on default visibility external linkage definitions

The idea is that the CC1 default for ELF should set dso_local on default
visibility external linkage definitions in the default -mrelocation-model pic
mode (-fpic/-fPIC) to match COFF/Mach-O and make output IR similar.

The refactoring is made available by 2820a2ca3a.

Currently only x86 supports local aliases. We move the decision to the driver.
There are three CC1 states:

* -fsemantic-interposition: make some linkages interposable and make default visibility external linkage definitions dso_preemptable.
* (default): selected if the target supports .Lfoo$local: make default visibility external linkage definitions dso_local
* -fhalf-no-semantic-interposition: if neither option is set or the target does not support .Lfoo$local: like -fno-semantic-interposition but local aliases are not used. So references can be interposed if not optimized out.

Add -fhalf-no-semantic-interposition to a few tests using the half-based semantic interposition behavior.
This commit is contained in:
Fangrui Song 2020-12-31 13:59:45 -08:00
parent 219d00e0d9
commit d1fd72343c
25 changed files with 117 additions and 88 deletions

View File

@ -322,7 +322,8 @@ ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
"visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic interposition")
BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0,
"Like -fno-semantic-interposition but don't use local aliases")
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
"stack protector mode")
ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,

View File

@ -3793,7 +3793,7 @@ defm ipa_cp : BooleanFFlag<"ipa-cp">,
Group<clang_ignored_gcc_optimization_f_Group>;
defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
def fsemantic_interposition : Flag<["-"], "fsemantic-interposition">, Group<f_Group>, Flags<[CC1Option]>;
def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>, Flags<[CC1Option]>;
def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>;
defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
@ -4722,6 +4722,8 @@ def pic_level : Separate<["-"], "pic-level">,
HelpText<"Value for __PIC__">;
def pic_is_pie : Flag<["-"], "pic-is-pie">,
HelpText<"File is for a position independent executable">;
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
HelpText<"Like -fno-semantic-interposition but don't use local aliases">;
def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
HelpText<"Disable validation of precompiled headers">,
MarshallingInfoFlag<"PreprocessorOpts->DisablePCHValidation">;

View File

@ -534,9 +534,6 @@ void CodeGenModule::Release() {
if (Context.getLangOpts().SemanticInterposition)
// Require various optimization to respect semantic interposition.
getModule().setSemanticInterposition(1);
else if (Context.getLangOpts().ExplicitNoSemanticInterposition)
// Allow dso_local on applicable targets.
getModule().setSemanticInterposition(0);
if (CodeGenOpts.EmitCodeView) {
// Indicate that we want CodeView in the metadata.
@ -961,15 +958,15 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
return false;
if (RM != llvm::Reloc::Static && !LOpts.PIE) {
// On ELF, if -fno-semantic-interposition is specified, we can set dso_local
// if using a local alias is preferable (can avoid GOT indirection).
// Currently only x86 supports local alias.
if (!TT.isOSBinFormatELF() ||
!CGM.getLangOpts().ExplicitNoSemanticInterposition ||
!GV->canBenefitFromLocalAlias())
// On ELF, if -fno-semantic-interposition is specified and the target
// supports local aliases, there will be neither CC1
// -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
// dso_local if using a local alias is preferable (can avoid GOT
// indirection).
if (!GV->canBenefitFromLocalAlias())
return false;
// The allowed targets need to match AsmPrinter::getSymbolPreferLocal.
return TT.isX86();
return !(CGM.getLangOpts().SemanticInterposition ||
CGM.getLangOpts().HalfNoSemanticInterposition);
}
// A definition cannot be preempted from an executable.

View File

@ -4561,12 +4561,31 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
// The default is -fno-semantic-interposition. We render it just because we
// require explicit -fno-semantic-interposition to infer dso_local.
if (Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
options::OPT_fno_semantic_interposition))
if (RelocationModel != llvm::Reloc::Static && !IsPIE)
A->render(Args, CmdArgs);
// -fsemantic-interposition is forwarded to CC1: set the
// "SemanticInterposition" metadata to 1 (make some linkages interposable) and
// make default visibility external linkage definitions dso_preemptable.
//
// -fno-semantic-interposition: if the target supports .Lfoo$local local
// aliases (make default visibility external linkage definitions dso_local).
// This is the CC1 default for ELF to match COFF/Mach-O.
//
// Otherwise use Clang's traditional behavior: like
// -fno-semantic-interposition but local aliases are not used. So references
// can be interposed if not optimized out.
if (Triple.isOSBinFormatELF()) {
Arg *A = Args.getLastArg(options::OPT_fsemantic_interposition,
options::OPT_fno_semantic_interposition);
if (RelocationModel != llvm::Reloc::Static && !IsPIE) {
// The supported targets need to call AsmPrinter::getSymbolPreferLocal.
bool SupportsLocalAlias = Triple.isX86();
if (!A)
CmdArgs.push_back("-fhalf-no-semantic-interposition");
else if (A->getOption().matches(options::OPT_fsemantic_interposition))
A->render(Args, CmdArgs);
else if (!SupportsLocalAlias)
CmdArgs.push_back("-fhalf-no-semantic-interposition");
}
}
{
std::string Model;

View File

@ -3197,9 +3197,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
}
Opts.SemanticInterposition = Args.hasArg(OPT_fsemantic_interposition);
// An explicit -fno-semantic-interposition infers dso_local.
Opts.ExplicitNoSemanticInterposition =
Args.hasArg(OPT_fno_semantic_interposition);
Opts.HalfNoSemanticInterposition =
Args.hasArg(OPT_fhalf_no_semantic_interposition);
// -mrtd option
if (Arg *A = Args.getLastArg(OPT_mrtd)) {

View File

@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// REQUIRES: aarch64-registered-target
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-128
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-512
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=128 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=CHECK-128
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -O1 -emit-llvm -o - %s -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=CHECK-512
#include <arm_sve.h>

View File

@ -1,23 +0,0 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fno-semantic-interposition %s -o - | FileCheck %s
/// For ELF -fpic/-fPIC, if -fno-semantic-interposition is specified, mark
/// defined variables and functions dso_local. ifunc isn't marked.
// CHECK: @var = dso_local global i32 0, align 4
// CHECK: @ext_var = external global i32, align 4
int var;
extern int ext_var;
// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
int ifunc(void) __attribute__((ifunc("ifunc_resolver")));
// CHECK: define dso_local i32 @func()
// CHECK: declare i32 @ext()
int func(void) { return 0; }
int ext(void);
static void *ifunc_resolver() { return func; }
int foo() {
return var + ext_var + ifunc() + func() + ext();
}

View File

@ -1,9 +1,38 @@
// RUN: %clang_cc1 -emit-llvm -fsemantic-interposition %s -o - | FileCheck --check-prefix=INTERPOSITION %s
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck --check-prefix=NO %s
/// With explicit -fno-semantic-interposition, add a module flag to inform the
/// backend that dso_local can be inferred.
// RUN: %clang_cc1 -emit-llvm -fno-semantic-interposition %s -o - | FileCheck --check-prefix=EXPLICIT_NO %s
/// -fno-semantic-interposition is the default and local aliases (via dso_local) are allowed.
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 %s -o - | FileCheck %s --check-prefixes=CHECK,NOMETADATA
// INTERPOSITION: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 1}
// NO-NOT: "SemanticInterposition"
// EXPLICIT_NO: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 0}
/// -fsemantic-interposition sets a module metadata.
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fsemantic-interposition %s -o - | FileCheck %s --check-prefixes=PREEMPT,METADATA
/// Traditional half-baked behavior: interprocedural optimizations are allowed
/// but local aliases are not used.
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition %s -o - | FileCheck %s --check-prefixes=PREEMPT,NOMETADATA
// CHECK: @var = dso_local global i32 0, align 4
// CHECK: @ext_var = external global i32, align 4
// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
// CHECK: define dso_local i32 @func()
// CHECK: declare i32 @ext()
// PREEMPT: @var = global i32 0, align 4
// PREEMPT: @ext_var = external global i32, align 4
// PREEMPT: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*)
// PREEMPT: define i32 @func()
// PREEMPT: declare i32 @ext()
// METADATA: !{{[0-9]+}} = !{i32 1, !"SemanticInterposition", i32 1}
// NOMETADATA-NOT: "SemanticInterposition"
int var;
extern int ext_var;
int ifunc(void) __attribute__((ifunc("ifunc_resolver")));
int func(void) { return 0; }
int ext(void);
static void *ifunc_resolver() { return func; }
int foo() {
return var + ext_var + ifunc() + func() + ext();
}

View File

@ -1,7 +1,7 @@
// Cross comdat example
// Parent VTable is in a comdat section.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// The inline function is emitted in each module with the same comdat
// CHECK: $_ZTS1A = comdat any

View File

@ -1,7 +1,7 @@
// Check the vtable layout for classes with key functions defined in different
// translation units. This TU only manifests the vtable for A.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
#include "cross-tu-header.h"

View File

@ -1,7 +1,7 @@
// Check the vtable layout for classes with key functions defined in different
// translation units. This TU manifests the vtable for B.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
#include "cross-tu-header.h"

View File

@ -1,7 +1,7 @@
// Diamond inheritance.
// A more complicated multiple inheritance example that includes longer chain of inheritance and a common ancestor.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// CHECK-DAG: %class.B = type { %class.A }
// CHECK-DAG: %class.A = type { i32 (...)** }

View File

@ -1,7 +1,7 @@
// Diamond virtual inheritance.
// This should cover virtual inheritance, construction vtables, and VTTs.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// Class A contains a vtable ptr, then int, then padding
// CHECK-DAG: %class.B = type { i32 (...)**, %class.A.base }

View File

@ -1,7 +1,7 @@
// Check the layout of the vtable for a child class that inherits a virtual
// function but does not override it.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
class A {
public:

View File

@ -1,8 +1,8 @@
// The VTable is not in a comdat but the inline methods are.
// This doesnt affect the vtable or the stubs we emit.
// RUN: %clang_cc1 %s -triple=aarch64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=x86_64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// RUN: %clang_cc1 %s -triple=x86_64 -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// CHECK: $_ZTI1A.rtti_proxy = comdat any

View File

@ -1,6 +1,6 @@
// Multiple inheritance.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// CHECK: %class.C = type { %class.A, %class.B }
// CHECK: %class.A = type { i32 (...)** }

View File

@ -1,7 +1,7 @@
// Check that no alias is emitted when the vtable is already dso_local. This can
// happen if the class is hidden.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s --check-prefix=DEFAULT-VIS
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s --check-prefix=DEFAULT-VIS
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fvisibility hidden | FileCheck %s --check-prefix=HIDDEN-VIS
// DEFAULT-VIS: @_ZTV1A.local = private unnamed_addr constant

View File

@ -2,7 +2,7 @@
// We instead emit zero for the pure virtual function component. See PR43094 for
// details.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// CHECK: @_ZTV1A.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8* }** @_ZTI1A.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 0, i32 trunc (i64 sub (i64 ptrtoint (void (%class.A*)* dso_local_equivalent @_ZN1A3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4

View File

@ -1,7 +1,7 @@
// Check the layout of the vtable for a child class that inherits a virtual
// function but does override it.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// CHECK: @_ZTV1B.local = private unnamed_addr constant { [4 x i32] } { [4 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint ({ i8*, i8*, i8* }** @_ZTI1B.rtti_proxy to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B3fooEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (void (%class.B*)* dso_local_equivalent @_ZN1B3barEv to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @_ZTV1B.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4

View File

@ -3,7 +3,7 @@
// of a soft incremental rollout. This ABI should only be used if the flag for
// it is passed on Fuchsia.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck --check-prefix=RELATIVE-ABI %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck --check-prefix=RELATIVE-ABI %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm -fno-experimental-relative-c++-abi-vtables | FileCheck --check-prefix=DEFAULT-ABI %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -S -o - -emit-llvm | FileCheck --check-prefix=DEFAULT-ABI %s

View File

@ -1,6 +1,6 @@
// Check the layout of the vtable for a normal class.
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables | FileCheck %s
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -S -o - -emit-llvm -fexperimental-relative-c++-abi-vtables -fhalf-no-semantic-interposition | FileCheck %s
// We should be emitting comdats for each of the virtual function RTTI proxies
// CHECK: $_ZTI1A.rtti_proxy = comdat any

View File

@ -2,12 +2,27 @@
// RUN: %clang -target x86_64 %s -Werror -fPIC -fsemantic-interposition -c -### 2>&1 | FileCheck %s
// CHECK: "-fsemantic-interposition"
/// Require explicit -fno-semantic-interposition to infer dso_local.
// RUN: %clang -target x86_64 %s -Werror -fPIC -fsemantic-interposition -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=EXPLICIT_NO %s
// EXPLICIT_NO: "-fno-semantic-interposition"
/// No-op for -fno-pic/-fpie.
// RUN: %clang -target x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s
// RUN: %clang -target x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NOOP %s
// NOOP-NOT: "-fsemantic-interposition"
// NOOP-NOT: "-fno-semantic-interposition"
// RUN: %clang -target x86_64 %s -Werror -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
// RUN: %clang -target x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=NO %s
// RUN: %clang -target x86_64 %s -Werror -fPIE -fsemantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
/// If -fno-semantic-interposition is specified and the target supports local
/// aliases, neither CC1 option is set.
// RUN: %clang -target i386 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
// RUN: %clang -target x86_64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=NO %s
// NO-NOT: "-fsemantic-interposition"
// NO-NOT: "-fno-semantic-interposition"
// NO-NOT: "-fhalf-no-semantic-interposition"
/// If neither -fsemantic-interposition or -fno-semantic-interposition is specified,
/// or -fno-semantic-interposition is specified but the target does not support
/// local aliases, use the traditional half-baked behavor: interprocedural
/// optimizations are allowed but local aliases are not used. If references are
/// not optimized out, semantic interposition at runtime is possible.
// RUN: %clang -target aarch64 %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s
// RUN: %clang -target ppc64le %s -Werror -fPIC -fno-semantic-interposition -c -### 2>&1 | FileCheck --check-prefix=HALF %s
// RUN: %clang -target x86_64 %s -Werror -fPIC -c -### 2>&1 | FileCheck --check-prefix=HALF %s
//
// HALF: "-fhalf-no-semantic-interposition"

View File

@ -855,7 +855,6 @@ public:
/// Returns whether semantic interposition is to be respected.
bool getSemanticInterposition() const;
bool noSemanticInterposition() const;
/// Set whether semantic interposition is to be respected.
void setSemanticInterposition(bool);

View File

@ -483,10 +483,8 @@ MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {
if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {
const Module &M = *GV.getParent();
if (TM.getRelocationModel() != Reloc::Static &&
M.getPIELevel() == PIELevel::Default)
if (GV.isDSOLocal() || (TM.getTargetTriple().isX86() &&
GV.getParent()->noSemanticInterposition()))
return getSymbolWithGlobalValueBase(&GV, "$local");
M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())
return getSymbolWithGlobalValueBase(&GV, "$local");
}
return TM.getSymbol(&GV);
}

View File

@ -601,13 +601,6 @@ void Module::setSemanticInterposition(bool SI) {
addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI);
}
bool Module::noSemanticInterposition() const {
// Conservatively require an explicit zero value for now.
Metadata *MF = getModuleFlag("SemanticInterposition");
auto *Val = cast_or_null<ConstantAsMetadata>(MF);
return Val && cast<ConstantInt>(Val->getValue())->getZExtValue() == 0;
}
void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
OwnedMemoryBuffer = std::move(MB);
}