forked from OSchip/llvm-project
[CodeGen] Emit COFF symbol type for function aliases
On the level of the generated object files, both symbols (both original and alias) are generally indistinguishable - both are regular defined symbols. But previously, only the original function had the COFF ComplexType set to IMAGE_SYM_DTYPE_FUNCTION, while the symbol created via an alias had the type set to IMAGE_SYM_DTYPE_NULL. This matches what GCC does, which emits directives for setting the COFF symbol type for this kind of alias symbol too. This makes a difference when GNU ld.bfd exports symbols without dllexport directives or a def file - it seems to decide between function or data exports based on the COFF symbol type. This means that functions created via aliases, like some C++ constructors, are exported as data symbols (missing the thunk for calling without dllimport). The hasnt been an issue when doing the same with LLD, as LLD decides between function or data export based on the flags of the section that the symbol points at. This should fix the root cause of https://github.com/msys2/MINGW-packages/issues/10547. Differential Revision: https://reviews.llvm.org/D118328
This commit is contained in:
parent
93c9b39d25
commit
f7d2afbac9
|
@ -1647,8 +1647,18 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
|
|||
|
||||
// Set the symbol type to function if the alias has a function type.
|
||||
// This affects codegen when the aliasee is not a function.
|
||||
if (IsFunction)
|
||||
if (IsFunction) {
|
||||
OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
|
||||
if (TM.getTargetTriple().isOSBinFormatCOFF()) {
|
||||
OutStreamer->BeginCOFFSymbolDef(Name);
|
||||
OutStreamer->EmitCOFFSymbolStorageClass(
|
||||
GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC
|
||||
: COFF::IMAGE_SYM_CLASS_EXTERNAL);
|
||||
OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
|
||||
<< COFF::SCT_COMPLEX_TYPE_SHIFT);
|
||||
OutStreamer->EndCOFFSymbolDef();
|
||||
}
|
||||
}
|
||||
|
||||
emitVisibility(Name, GA.getVisibility());
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
; RUN: llc -mtriple=x86_64-windows-gnu -o - %s | FileCheck %s
|
||||
|
||||
%struct.MyStruct = type { i8 }
|
||||
|
||||
@_ZN8MyStructC1Ev = dso_local alias void (%struct.MyStruct*), void (%struct.MyStruct*)* @_ZN8MyStructC2Ev
|
||||
|
||||
define dso_local void @_ZN8MyStructC2Ev(%struct.MyStruct* %this) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: .def _ZN8MyStructC2Ev
|
||||
; CHECK-NEXT: .scl 2
|
||||
; CHECK-NEXT: .type 32
|
||||
; CHECK-NEXT: .endef
|
||||
; CHECK-NEXT: .globl _ZN8MyStructC2Ev
|
||||
; CHECK: {{^}}_ZN8MyStructC2Ev:
|
||||
|
||||
; CHECK: .globl _ZN8MyStructC1Ev
|
||||
; CHECK-NEXT: .def _ZN8MyStructC1Ev
|
||||
; CHECK-NEXT: .scl 2
|
||||
; CHECK-NEXT: .type 32
|
||||
; CHECK-NEXT: .endef
|
||||
; CHECK-NEXT: .set _ZN8MyStructC1Ev, _ZN8MyStructC2Ev
|
Loading…
Reference in New Issue