Skip to content

Commit 6c5beca

Browse files
authored
0.7.1 --- no loop becomes a C runtime call, at any optimization (#20)
An optimizing compiler replaced wide_length's counting loop with wcslen and a byte loop in win.cpp with strlen. The C library above is openkal-musl, whose wchar_t is thirty-two bits, so its wcslen read the command line two units at a time: every argument of a program built with --release was shortened by a different amount. -fno-builtin keeps the loops, and the no-C-runtime-symbol check now builds the release profile as well as dev.
1 parent b7de5e2 commit 6c5beca

2 files changed

Lines changed: 23 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,9 +433,15 @@ jobs:
433433
# may supply a C runtime of its own; an implementation that reached for
434434
# this environment's would have its calls resolve to the program's, and
435435
# the program's would resolve back here.
436+
#
437+
# ⚠️ IN BOTH PROFILES. An optimizing compiler turns loops into calls ---
438+
# a counting loop into `strlen` or `wcslen` --- so objects built without
439+
# optimization can hold the property while the ones a release links do not.
436440
- name: The objects reference no C runtime symbol
437441
run: |
438-
rm -rf target && mcpp build --features standalone --target x86_64-windows-gnu
442+
for profile in dev release; do
443+
echo "--- profile $profile"
444+
rm -rf target && mcpp build --features standalone --target x86_64-windows-gnu --profile "$profile"
439445
objs="$(find target -path '*/obj/*' -name '*.o' ! -name '*.m.o')"
440446
test -n "$objs" || { echo "no objects were found; the check would pass vacuously" >&2; exit 1; }
441447
@@ -465,7 +471,8 @@ jobs:
465471
}
466472
done
467473
test "$bad" -eq 0
468-
echo "the implementation references no C runtime symbol"
474+
echo "the implementation references no C runtime symbol ($profile)"
475+
done
469476
470477
# A checker is only useful if it fails when it should.
471478
- name: The independence check detects a dependence

mcpp.toml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
namespace = "mcpplibs"
33
name = "openkal-windows"
4-
version = "0.7.0"
4+
version = "0.7.1"
55
description = "An implementation of openkal for Windows, written on the Win32 interfaces and the object manager beneath them, using no C runtime symbol."
66
license = "Apache-2.0"
77

@@ -65,7 +65,19 @@ ldflags = ["-lntdll", "-lsynchronization", "-lshell32", "-lkernel32", "-lbcrypt"
6565
# ABI has a C runtime; there the toolchain's defaults are correct, one of the two
6666
# toolchains that reach it would not recognise these spellings, and openkal has
6767
# nothing to say about how a program that has a runtime unwinds.
68-
cxxflags = ["-fno-exceptions", "-fno-rtti"]
68+
#
69+
# ⚠️ AND NO LOOP IS REPLACED BY A CALL, WHICH IS WHAT `-fno-builtin` IS FOR.
70+
#
71+
# An optimizing compiler recognises a loop that counts to a terminator and
72+
# emits a call to the library function that does the same. `wide_length` in
73+
# src/env.cpp counts sixteen-bit units and became `wcslen`; a byte loop in
74+
# src/win.cpp became `strlen`. Neither is this environment's: the C library
75+
# above is openkal-musl, whose `wchar_t` is thirty-two bits, so its `wcslen`
76+
# read the command line two units at a time and every argument of a program
77+
# built with `--release` came out shortened by a different amount. The dev
78+
# profile does not optimize and never showed it, which is also why the check
79+
# below now builds both profiles.
80+
cxxflags = ["-fno-exceptions", "-fno-rtti", "-fno-builtin"]
6981

7082
# The other ABI names them in the sources instead --- src/win.cpp for the four
7183
# above and src/random.cpp for bcrypt --- where its compilers record

0 commit comments

Comments
 (0)