-
Notifications
You must be signed in to change notification settings - Fork 3.5k
-fshort-wchar is broken with -O2/-Os #26579
Copy link
Copy link
Open
Description
Using -fshort-wchar with em++ produces incorrect results that vary depending on the optimization level.
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 5.0.4 (62e22652509fbe7a00609ce48a653d0d66f27ba5)
clang version 23.0.0git (https:/github.com/llvm/llvm-project dcaab6dd99a33edbf98ad1ade0ea0d196b797910)
Target: wasm32-unknown-emscripten
Thread model: posix
Failing command line in full:
I've tested with the following code (
u16.cpp
wchar.cpp
wcslen.cpp
).
Command line:
em++ -fshort-wchar u16.cpp -O0 && env node ./a.out.js
em++ -fshort-wchar u16.cpp -O2 && env node ./a.out.js
em++ -fshort-wchar u16.cpp -Os && env node ./a.out.js
Results:
length: 10 == 10
find: 6 == -1
length: 10 == 10
find: 6 == -1
length: 10 == 56
find: 6 == -1
u16string::size() — fails when -Os is used
u16string::find() — always fails
u16.cpp:
#include <stdio.h>
#include <string>
int main()
{
std::u16string s = u"0123456789";
std::u16string::size_type l = s.size();
printf("length: %d == %zd\n", 10, l);
std::u16string::size_type p = s.find(u"678");
printf("find: %d == %zd\n", 6, p);
return 0;
}wchar_t behavior is also unstable.
The my_wcslen() function malfunctions when -O2 or -Os is used.
Command line:
make
Results:
em++ -fshort-wchar -c wcslen.cpp -O0
em++ -fshort-wchar -c wchar.cpp -O0
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.js
wchar_t size: 2
len: 10 == 10
em++ -fshort-wchar -c wcslen.cpp -O2
em++ -fshort-wchar -c wchar.cpp -O2
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.js
wchar_t size: 2
len: 10 == 5
em++ -fshort-wchar -c wcslen.cpp -Os
em++ -fshort-wchar -c wchar.cpp -Os
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.js
wchar_t size: 2
len: 10 == 5
wcslen.cpp:
#include <wchar.h>
extern "C" size_t my_wcslen(const wchar_t* s)
{
const wchar_t* e = s;
while (*e) {
++e;
}
return e - s;
}wchar.cpp:
#include <stdio.h>
#include <wchar.h>
extern "C" size_t my_wcslen(const wchar_t* s);
int
main()
{
printf("wchar_t size: %zu\n", sizeof(wchar_t));
wchar_t str[] = L"0123456789";
size_t l1 = sizeof(str) / sizeof(str[0]) - 1;
size_t l2 = my_wcslen(str);
printf("len: %zu == %zu\n", l1, l2);
return 0;
}Makefile:
OPTFLAGS =
run: run0 run2 runs
run0: OPTFLAGS = -O0
run0:
em++ -fshort-wchar -c wcslen.cpp $(OPTFLAGS)
em++ -fshort-wchar -c wchar.cpp $(OPTFLAGS)
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.js
run2: OPTFLAGS = -O2
run2:
em++ -fshort-wchar -c wcslen.cpp $(OPTFLAGS)
em++ -fshort-wchar -c wchar.cpp $(OPTFLAGS)
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.js
runs: OPTFLAGS = -Os
runs:
em++ -fshort-wchar -c wcslen.cpp $(OPTFLAGS)
em++ -fshort-wchar -c wchar.cpp $(OPTFLAGS)
em++ -fshort-wchar -o wchar.js wchar.o wcslen.o
env node ./wchar.jsThis wcslen bug is reproducible when my_wcslen() is compiled in a separate translation unit.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels