v
v copied to clipboard
Test failed in 32-bit environment: vlib/builtin/map_of_floats_test.v
Describe the bug
Execute the test in 32-bit environment: ./test_v test vlib/builtin/map_of_floats_test.v
The following error occurs:
FAIL 3985.912 ms vlib/builtin/map_of_floats_test.v
{1.0: 'one'}
{3.14: 'pi', 1.0: 'one'}
D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\src\\v-0.4.4\\vlib\\builtin\\map_of_floats_test.v:24: fn test_map_of_f64
> assert k in [1.0, 3.14]
Left value: 3.14
Right value: [1.0, 3.14]
gcc -v
output:
Using built-in specs.
COLLECT_GCC=D:\gym\softwares\msys64\mingw32\bin\gcc.exe
COLLECT_LTO_WRAPPER=D:/gym/softwares/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/13.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../gcc-13.2.0/configure --prefix=/mingw32 --with-local-prefix=/mingw32/local --build=i686-w64-mingw32 --host=i686-w64-mingw32 --target=i686-w64-mingw32 --with-native-system-header-dir=/mingw32/include --libexecdir=/mingw32/lib --enable-bootstrap --enable-checking=release --with-arch=pentium4 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw32 --with-mpfr=/mingw32 --with-mpc=/mingw32 --with-isl=/mingw32 --with-pkgversion='Rev3, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --disable-libstdcxx-debug --disable-sjlj-exceptions --with-dwarf2 --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Rev3, Built by MSYS2 project)
Reproduction Steps
Execute in msys2/MINGW32
console:
gcc -std=c99 -municode -g -w -o test_v0.exe vc/v_win.c -ladvapi32 -lws2_32
./test_v0 -keepc -g -showcc -cc gcc -o test_v.exe cmd/v
./test_v test vlib/builtin/map_of_floats_test.v
Expected Behavior
Test passed.
Current Behavior
Test failed.
Possible Solution
No response
Additional Information/Context
No response
V version
0.4.4
Environment details (OS name and version, etc.)
V full version: V 0.4.4 ac2dcc2 OS: windows, Microsoft Windows 7 רҵ▒▒ v7601 64-bit Processor: 4 cpus, 32bit, little endian,
getwd: D:\gym\test\mingw-w64-packages\mingw-w64-v\src\v-0.4.4 vexe: D:\gym\test\mingw-w64-packages\mingw-w64-v\src\v-0.4.4\test_v.exe vexe mtime: 2024-01-12 08:36:54
vroot: OK, value: D:\gym\test\mingw-w64-packages\mingw-w64-v\src\v-0.4.4 VMODULES: OK, value: D:/gym/test/mingw-w64-packages/mingw-w64-v/vmodules/mingw-w64-i686-v-0.4.4-1 VTMP: OK, value: D:\gym\test\mingw-w64-packages\mingw-w64-v\tmp\mingw-w64-i686-v-0.4.4-1\v_0
Git version: Error: 'git' is not recognized as an internal or external command, operable program or batch file.
Git vroot status: Error: 'git' is not recognized as an internal or external command, operable program or batch file. .git/config present: false
CC version: cc (Rev3, Built by MSYS2 project) 13.2.0 thirdparty/tcc: N/A
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.
Related tests:
-
assert 3.14 in [1.0, 3.14]
success -
k := 3.14; assert k in [1.0, 3.14]
failed -
k := 3.14; assert k in [1.0, k]
success -
k := 3.14; a := [1.0, 3.14]; assert k in a
succeeded -
k := f64(3.14); a := [f64(1.0), f64(k)]; assert k in a
succeeded -
k := f64(3.14); assert k in [f64(1.0), f64(3.14)]
success -
k := 3.14; assert k in [1.0, f64(3.14)]
success
C backend code test:
#include <stdio.h>
typedef double f64;
void main() {
f64 k = 3.14;
if (!((3.14 == 1.0 || 3.14 == 3.14))) {
printf("Assertion failed...111\n");
}
if (!((k == 1.0 || k == 3.14))) {
printf("Assertion failed...222\n");
}
}
-
gcc -o test test.c && ./test
is successful in msys2/MINGW{32,64} -
gcc -std=c99 -o test test.c && ./test
succeeded under msys2/MINGW64 but failed under msys2/MINGW32
Execute gcc -std=c99 -o test test.c && ./test
under msys2/MINGW32. Output:
Assertion failed...222
However, there is no output when executing gcc -std=gnu99 -o test test.c && ./test
under msys2/MINGW32.
This seems related to gcc-mingw32 bug posted at https://groups.google.com/g/linux.debian.bugs.dist/c/Gz87kv8qZ-c
Force the use of -std=gnu99
and the test will pass.
# echo ${MINGW_PACKAGE_PREFIX}
mingw-w64-i686
# gcc -std=c99 -municode -g -w -o ${MINGW_PACKAGE_PREFIX}-v0.exe vc/v_win.c -ladvapi32 -lws2_32
# ./${MINGW_PACKAGE_PREFIX}-v0 -keepc -g -showcc -cc gcc -o ${MINGW_PACKAGE_PREFIX}-v.exe cmd/v
> C compiler cmd: gcc "@D:\gym\test\mingw-w64-packages\mingw-w64-v\tmp\mingw-w64-i686-v-0.4.4-1\v_0\mingw-w64-i686-v.exe.tmp.c.rsp"
> C compiler response file "D:\gym\test\mingw-w64-packages\mingw-w64-v\tmp\mingw-w64-i686-v-0.4.4-1\v_0\mingw-w64-i686-v.exe.tmp.c.rsp":
-fwrapv -g -no-pie -o "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\src\\v-0.4.4\\mingw-w64-i686-v.exe" -Wl,-stack=16777216 -Werror=implicit-function-declaration -I "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\src\\v-0.4.4\\thirdparty\\stdatomic\\win" "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\tmp\\mingw-w64-i686-v-0.4.4-1\\v_0\\mingw-w64-i686-v.exe.tmp.c" -std=c99 -D_DEFAULT_SOURCE -municode -ldbghelp -lws2_32 -ladvapi32 -lshell32
# CFLAGS=-std=c99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/builtin/map_of_floats_test.v
{1.0: 'one'}
{3.14: 'pi', 1.0: 'one'}
vlib/builtin/map_of_floats_test.v:24: fn test_map_of_f64
> assert k in [1.0, 3.14]
Left value: 3.14
Right value: [1.0, 3.14]
# CFLAGS=-std=gnu99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/builtin/map_of_floats_test.v
{1.0: 'one'}
{3.14: 'pi', 1.0: 'one'}
Force the use of
-std=gnu99
and the test will pass.# echo ${MINGW_PACKAGE_PREFIX} mingw-w64-i686 # gcc -std=c99 -municode -g -w -o ${MINGW_PACKAGE_PREFIX}-v0.exe vc/v_win.c -ladvapi32 -lws2_32 # ./${MINGW_PACKAGE_PREFIX}-v0 -keepc -g -showcc -cc gcc -o ${MINGW_PACKAGE_PREFIX}-v.exe cmd/v > C compiler cmd: gcc "@D:\gym\test\mingw-w64-packages\mingw-w64-v\tmp\mingw-w64-i686-v-0.4.4-1\v_0\mingw-w64-i686-v.exe.tmp.c.rsp" > C compiler response file "D:\gym\test\mingw-w64-packages\mingw-w64-v\tmp\mingw-w64-i686-v-0.4.4-1\v_0\mingw-w64-i686-v.exe.tmp.c.rsp": -fwrapv -g -no-pie -o "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\src\\v-0.4.4\\mingw-w64-i686-v.exe" -Wl,-stack=16777216 -Werror=implicit-function-declaration -I "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\src\\v-0.4.4\\thirdparty\\stdatomic\\win" "D:\\gym\\test\\mingw-w64-packages\\mingw-w64-v\\tmp\\mingw-w64-i686-v-0.4.4-1\\v_0\\mingw-w64-i686-v.exe.tmp.c" -std=c99 -D_DEFAULT_SOURCE -municode -ldbghelp -lws2_32 -ladvapi32 -lshell32
# CFLAGS=-std=c99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/builtin/map_of_floats_test.v {1.0: 'one'} {3.14: 'pi', 1.0: 'one'} vlib/builtin/map_of_floats_test.v:24: fn test_map_of_f64 > assert k in [1.0, 3.14] Left value: 3.14 Right value: [1.0, 3.14] # CFLAGS=-std=gnu99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/builtin/map_of_floats_test.v {1.0: 'one'} {3.14: 'pi', 1.0: 'one'}
But -std=gnu99
will cause the vlib/gg/m4/m4_test.v
test to fail:
# CFLAGS=-std=c99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/gg/m4/m4_test.v
# CFLAGS=-std=gnu99 ./${MINGW_PACKAGE_PREFIX}-v -no-std vlib/gg/m4/m4_test.v
vlib/gg/m4/m4_test.v:233: fn test_proj
> assert gg.m4.mul_vec(ort, gg.m4.Vec4{....}) == gg.m4.Vec4{....}
Left value:
|2.421e-08,-2.235e-08,0 ,1 |
Right value:
|0 ,0 ,0 ,1 |
This seems related to gcc-mingw32 bug posted at https://groups.google.com/g/linux.debian.bugs.dist/c/Gz87kv8qZ-c
Thanks, I will test further.
In order to clarify the source of the error, I used the following test code (test.c
):
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
union {
double f64;
uint64_t u64;
} buf;
void main() {
buf.f64 = 3.14;
printf("sizeof(3.14) = %d\n", sizeof(3.14));
printf("sizeof(buf.f64) = %d\n", sizeof(buf.f64));
printf("val = 0x%llx\n", buf.u64);
printf("val = %lld\n", buf.u64);
assert(3.14 == buf.f64);
}
Use gcc-mingw32:
# gcc -v
Using built-in specs.
COLLECT_GCC=D:\gym\softwares\msys64\mingw32\bin\gcc.exe
COLLECT_LTO_WRAPPER=D:/gym/softwares/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/13.2.0/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../gcc-13.2.0/configure --prefix=/mingw32 --with-local-prefix=/mingw32/local --build=i686-w64-mingw32 --host=i686-w64-mingw32 --target=i686-w64-mingw32 --with-native-system-header-dir=/mingw32/include --libexecdir=/mingw32/lib --enable-bootstrap --enable-checking=release --with-arch=pentium4 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts --enable-libstdcxx-time --disable-libstdcxx-pch --enable-lto --enable-libgomp --disable-libssp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw32 --with-mpfr=/mingw32 --with-mpc=/mingw32 --with-isl=/mingw32 --with-pkgversion='Rev3, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --disable-libstdcxx-debug --disable-sjlj-exceptions --with-dwarf2 --with-boot-ldflags=-static-libstdc++ --with-stage1-ldflags=-static-libstdc++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Rev3, Built by MSYS2 project)
# gcc -std=c99 -o test test.c && ./test
Assertion failed: 3.14 == buf.f64, file test.c, line 17
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
sizeof(3.14) = 8
sizeof(buf.f64) = 8
val = 0x40091eb851eb851f
val = 4614253070214989087
# gcc -std=gnu99 -o test test.c && ./test
sizeof(3.14) = 8
sizeof(buf.f64) = 8
val = 0x40091eb851eb851f
val = 4614253070214989087
Use c99 and gnu99 to generate assembly code:
gcc -std=c99 -S -o ${MINGW_PACKAGE_PREFIX}-test.c99.s test.c
.file "test.c"
.text
.def _printf; .scl 3; .type 32; .endef
_printf:
LFB9:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ebx
subl $36, %esp
.cfi_offset 3, -12
leal 12(%ebp), %eax
movl %eax, -16(%ebp)
movl -16(%ebp), %ebx
movl $1, (%esp)
movl __imp____acrt_iob_func, %eax
call *%eax
movl %ebx, 8(%esp)
movl 8(%ebp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call ___mingw_vfprintf
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl -4(%ebp), %ebx
leave
.cfi_restore 5
.cfi_restore 3
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE9:
.globl _buf
.bss
.align 8
_buf:
.space 8
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC1:
.ascii "sizeof(3.14) = %d\12\0"
LC2:
.ascii "sizeof(buf.f64) = %d\12\0"
LC3:
.ascii "val = 0x%llx\12\0"
LC4:
.ascii "val = %lld\12\0"
LC6:
.ascii "test.c\0"
LC7:
.ascii "3.14 == buf.f64\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB30:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
fldl LC0
fstpl _buf
movl $8, 4(%esp)
movl $LC1, (%esp)
call _printf
movl $8, 4(%esp)
movl $LC2, (%esp)
call _printf
movl _buf, %eax
movl _buf+4, %edx
movl %eax, 4(%esp)
movl %edx, 8(%esp)
movl $LC3, (%esp)
call _printf
movl _buf, %eax
movl _buf+4, %edx
movl %eax, 4(%esp)
movl %edx, 8(%esp)
movl $LC4, (%esp)
call _printf
fldl _buf
fldt LC5
fucomip %st(1), %st
jp L8
fldt LC5
fucomip %st(1), %st
fstp %st(0)
je L7
jmp L6
L8:
fstp %st(0)
L6:
movl $17, 8(%esp)
movl $LC6, 4(%esp)
movl $LC7, (%esp)
movl __imp___assert, %eax
call *%eax
L7:
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE30:
.section .rdata,"dr"
.align 8
LC0:
.long 1374389535
.long 1074339512
.align 16
LC5:
.long 1546188227
.long -923417969
.long 16384
.ident "GCC: (Rev3, Built by MSYS2 project) 13.2.0"
.def ___mingw_vfprintf; .scl 2; .type 32; .endef
gcc -std=gnu99 -S -o ${MINGW_PACKAGE_PREFIX}-test.gnu99.s test.c
.file "test.c"
.text
.def _printf; .scl 3; .type 32; .endef
_printf:
LFB9:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ebx
subl $36, %esp
.cfi_offset 3, -12
leal 12(%ebp), %eax
movl %eax, -16(%ebp)
movl -16(%ebp), %ebx
movl $1, (%esp)
movl __imp____acrt_iob_func, %eax
call *%eax
movl %ebx, 8(%esp)
movl 8(%ebp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call ___mingw_vfprintf
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl -4(%ebp), %ebx
leave
.cfi_restore 5
.cfi_restore 3
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE9:
.globl _buf
.bss
.align 8
_buf:
.space 8
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC1:
.ascii "sizeof(3.14) = %d\12\0"
LC2:
.ascii "sizeof(buf.f64) = %d\12\0"
LC3:
.ascii "val = 0x%llx\12\0"
LC4:
.ascii "val = %lld\12\0"
LC5:
.ascii "test.c\0"
LC6:
.ascii "3.14 == buf.f64\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB30:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
fldl LC0
fstpl _buf
movl $8, 4(%esp)
movl $LC1, (%esp)
call _printf
movl $8, 4(%esp)
movl $LC2, (%esp)
call _printf
movl _buf, %eax
movl _buf+4, %edx
movl %eax, 4(%esp)
movl %edx, 8(%esp)
movl $LC3, (%esp)
call _printf
movl _buf, %eax
movl _buf+4, %edx
movl %eax, 4(%esp)
movl %edx, 8(%esp)
movl $LC4, (%esp)
call _printf
fldl _buf
fldl LC0
fucomip %st(1), %st
jp L8
fldl LC0
fucomip %st(1), %st
fstp %st(0)
je L7
jmp L6
L8:
fstp %st(0)
L6:
movl $17, 8(%esp)
movl $LC5, 4(%esp)
movl $LC6, (%esp)
movl __imp___assert, %eax
call *%eax
L7:
nop
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE30:
.section .rdata,"dr"
.align 8
LC0:
.long 1374389535
.long 1074339512
.ident "GCC: (Rev3, Built by MSYS2 project) 13.2.0"
.def ___mingw_vfprintf; .scl 2; .type 32; .endef
The difference in assembly code is as follows:
# diff -urN ${MINGW_PACKAGE_PREFIX}-test.c99.s ${MINGW_PACKAGE_PREFIX}-test.gnu99.s
--- mingw-w64-i686-test.c99.s 2024-01-20 11:24:38.115500000 +0800
+++ mingw-w64-i686-test.gnu99.s 2024-01-20 11:24:44.581500000 +0800
@@ -48,9 +48,9 @@
.ascii "val = 0x%llx\12\0"
LC4:
.ascii "val = %lld\12\0"
-LC6:
+LC5:
.ascii "test.c\0"
-LC7:
+LC6:
.ascii "3.14 == buf.f64\0"
.text
.globl _main
@@ -87,10 +87,10 @@
movl $LC4, (%esp)
call _printf
fldl _buf
- fldt LC5
+ fldl LC0
fucomip %st(1), %st
jp L8
- fldt LC5
+ fldl LC0
fucomip %st(1), %st
fstp %st(0)
je L7
@@ -99,8 +99,8 @@
fstp %st(0)
L6:
movl $17, 8(%esp)
- movl $LC6, 4(%esp)
- movl $LC7, (%esp)
+ movl $LC5, 4(%esp)
+ movl $LC6, (%esp)
movl __imp___assert, %eax
call *%eax
L7:
@@ -116,10 +116,5 @@
LC0:
.long 1374389535
.long 1074339512
- .align 16
-LC5:
- .long 1546188227
- .long -923417969
- .long 16384
.ident "GCC: (Rev3, Built by MSYS2 project) 13.2.0"
.def ___mingw_vfprintf; .scl 2; .type 32; .endef
gcc -std=c99
loads the long doulbe
constant using fldt LC5
, while gcc -std=gnu99
loads the doulbe
constant using fldl LC0
.
Modify fldt LC5
in the ${MINGW_PACKAGE_PREFIX}-test.c99.s
file to fldl LC0
, and the test is successful.
before fixing:
# gcc -o test ${MINGW_PACKAGE_PREFIX}-test.c99.s && ./test
Assertion failed: 3.14 == buf.f64, file test.c, line 17
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
sizeof(3.14) = 8
sizeof(buf.f64) = 8
val = 0x40091eb851eb851f
val = 4614253070214989087
After modification:
# gcc -o test ${MINGW_PACKAGE_PREFIX}-test.c99.s && ./test
sizeof(3.14) = 8
sizeof(buf.f64) = 8
val = 0x40091eb851eb851f
val = 4614253070214989087
# gcc -o test ${MINGW_PACKAGE_PREFIX}-test.gnu99.s && ./test
sizeof(3.14) = 8
sizeof(buf.f64) = 8
val = 0x40091eb851eb851f
val = 4614253070214989087
Since the v semantics depends on the semantics of C I think we have to understand if this is a Bug in GCC or if this is just undefined behavior in the C standard. The GCC issue above, taking the same code and running it clang -m32 -std=c99
works.
Since the v semantics depends on the semantics of C I think we have to understand if this is a Bug in GCC or if this is just undefined behavior in the C standard. The GCC issue above, taking the same code and running it
clang -m32 -std=c99
works.
It's a gcc bug. In order to avoid this bug, I always use -std=gnu99
for testing.
https://sourceforge.net/p/mingw-w64/mailman/message/58769159/
Is anyone using the mingw32 platform? If GCC has not fixed the bug, or at least bothered to investigate the finer details of the C standard, in 12(!) years, perhaps the platform is not that relevant to support?