v.gen.c: add tests to ensure the same calling convention is used on exported functions for -m32/-m64 (#11977)
parent
9b6e07e2a6
commit
9be16eba63
|
@ -401,7 +401,8 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
||||||
for attr in node.attrs {
|
for attr in node.attrs {
|
||||||
if attr.name == 'export' {
|
if attr.name == 'export' {
|
||||||
g.writeln('// export alias: $attr.arg -> $name')
|
g.writeln('// export alias: $attr.arg -> $name')
|
||||||
export_alias := '$type_name ${attr.arg}($arg_str)'
|
calling_conv := if msvc_attrs.len > 0 { '$msvc_attrs ' } else { '' }
|
||||||
|
export_alias := '$type_name $calling_conv${attr.arg}($arg_str)'
|
||||||
g.definitions.writeln('VV_EXPORTED_SYMBOL $export_alias; // exported fn $node.name')
|
g.definitions.writeln('VV_EXPORTED_SYMBOL $export_alias; // exported fn $node.name')
|
||||||
g.writeln('$export_alias {')
|
g.writeln('$export_alias {')
|
||||||
g.write('\treturn ${name}(')
|
g.write('\treturn ${name}(')
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
module test
|
||||||
|
|
||||||
|
fn C._vinit(int, voidptr)
|
||||||
|
fn C.GC_INIT()
|
||||||
|
|
||||||
|
const (
|
||||||
|
foo = 1
|
||||||
|
bar = (foo << 5) + 9
|
||||||
|
)
|
||||||
|
|
||||||
|
[export: Tatltuae]
|
||||||
|
pub fn test_tatltuae() int {
|
||||||
|
return test.foo + test.bar
|
||||||
|
}
|
||||||
|
|
||||||
|
[export: DllMain]
|
||||||
|
[windows_stdcall]
|
||||||
|
fn main(hinst voidptr, fdw_reason int, lp_reserved voidptr) bool {
|
||||||
|
match fdw_reason {
|
||||||
|
C.DLL_PROCESS_ATTACH {
|
||||||
|
$if static_boehm ? {
|
||||||
|
C.GC_INIT()
|
||||||
|
}
|
||||||
|
C._vinit(0, 0)
|
||||||
|
}
|
||||||
|
C.DLL_THREAD_ATTACH {}
|
||||||
|
C.DLL_THREAD_DETACH {}
|
||||||
|
C.DLL_PROCESS_DETACH {}
|
||||||
|
else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import dl
|
||||||
|
import os
|
||||||
|
|
||||||
|
type Func = fn () int
|
||||||
|
|
||||||
|
fn run_test(cc_used string) {
|
||||||
|
cc_flag := match cc_used {
|
||||||
|
'tcc64' { '-cc tcc' }
|
||||||
|
'gcc64' { '-cc gcc' }
|
||||||
|
'clang64' { '-cc clang' }
|
||||||
|
'msvc64' { '-cc msvc' }
|
||||||
|
'tcc32' { '-cc tcc -m32 -d no_backtrace' }
|
||||||
|
'gcc32' { '-cc gcc -m32' }
|
||||||
|
'clang32' { '-cc clang -m32' }
|
||||||
|
'msvc32' { '-cc msvc -m32' }
|
||||||
|
else { '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
assert os.system('"${@VEXE}" $cc_flag -o create_win_${cc_used}.dll -shared create_win_dll.v') == 0
|
||||||
|
assert os.exists('create_win_${cc_used}.dll')
|
||||||
|
handle := dl.open('create_win_${cc_used}.dll', 0)
|
||||||
|
assert handle != 0
|
||||||
|
test := Func(dl.sym(handle, 'Tatltuae'))
|
||||||
|
assert test() == 42
|
||||||
|
assert test() != 666
|
||||||
|
// dl.close(handle) // works for gcc, clang and msvc but crashes with tcc
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_create_and_dllmain() {
|
||||||
|
os.chdir(os.dir(@FILE)) or {}
|
||||||
|
$if windows {
|
||||||
|
$if x64 {
|
||||||
|
$if tinyc {
|
||||||
|
run_test('tcc64')
|
||||||
|
}
|
||||||
|
$if gcc {
|
||||||
|
run_test('gcc64')
|
||||||
|
}
|
||||||
|
$if clang {
|
||||||
|
run_test('clang64')
|
||||||
|
}
|
||||||
|
$if msvc {
|
||||||
|
run_test('msvc64')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$if x32 {
|
||||||
|
$if tinyc {
|
||||||
|
run_test('tcc32')
|
||||||
|
}
|
||||||
|
$if gcc {
|
||||||
|
run_test('gcc32')
|
||||||
|
}
|
||||||
|
$if clang {
|
||||||
|
run_test('clang32')
|
||||||
|
}
|
||||||
|
$if msvc {
|
||||||
|
// run_test('msvc32') // something wrong as it passes when it should fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue