|
1 | 1 | #!/usr/bin/env bash |
2 | | -# macOS 27: libc++ 22 std.cppm loses INFINITY/NAN. Round 2: mechanism and candidate fixes. |
| 2 | +# macOS 27 round 3: which single flag makes libc++ 22's std module build in strict mode. |
3 | 3 | set +e |
4 | 4 | r() { echo "READING $*"; } |
5 | | -L="$LLVM_ROOT"; SDK=$(xcrun --show-sdk-path); S=$L/share/libc++/v1/std.cppm |
6 | | -r "llvm=$L cfg=$(tr '\n' ' ' < $L/bin/clang++.cfg)" |
7 | | -r "math.h 55-95:"; sed -n 55,95p $SDK/usr/include/math.h | sed 's/^/READING math.h| /' |
8 | | -FH=$($L/bin/clang -print-resource-dir)/include/float.h |
9 | | -r "clang float.h INFINITY region:"; grep -n -B4 -A3 'define INFINITY' $FH | sed 's/^/READING float.h| /' |
10 | | -AF=$(/usr/bin/clang -print-resource-dir)/include/float.h |
11 | | -r "apple float.h INFINITY region:"; grep -n -B4 -A3 'define INFINITY' $AF | sed 's/^/READING apple-float.h| /' |
| 5 | +L="$LLVM_ROOT"; SDK=$(xcrun --show-sdk-path); S=$L/share/libc++/v1/std.cppm; SC=$L/share/libc++/v1/std.compat.cppm |
12 | 6 | W=$(mktemp -d); cd $W |
13 | | -BASE=(--no-default-config -nostdinc++ -isystem $L/include/c++/v1 -isysroot $SDK -Wno-reserved-module-identifier) |
14 | | -try() { name=$1; shift; out=$("$@" 2>&1); rc=$?; r "$name rc=$rc $(printf '%s' "$out" | grep -m1 'error' | cut -c1-200)"; } |
15 | | -printf 'int main(){ return __has_feature(modules); }\n' > hf.cpp |
16 | | -try hasfeature-modules-in-precompile-of-plain $L/bin/clang++ "${BASE[@]}" -std=c++23 -fsyntax-only hf.cpp |
17 | | -printf 'export module m;\n#if __has_feature(modules)\n#error MODULES_ON\n#endif\n' > hf.cppm |
18 | | -try hasfeature-modules-in-module-interface $L/bin/clang++ "${BASE[@]}" -std=c++23 --precompile hf.cppm -o hf.pcm |
19 | | -try c++23 $L/bin/clang++ "${BASE[@]}" -std=c++23 --precompile $S -o a.pcm |
20 | | -try gnu++23 $L/bin/clang++ "${BASE[@]}" -std=gnu++23 --precompile $S -o b.pcm |
21 | | -try c++23-U-strict $L/bin/clang++ "${BASE[@]}" -std=c++23 -U__STRICT_ANSI__ --precompile $S -o c.pcm |
22 | | -try c++23-inc-math $L/bin/clang++ "${BASE[@]}" -std=c++23 -include math.h --precompile $S -o d.pcm |
23 | | -try c++23-fbuiltin-inf $L/bin/clang++ "${BASE[@]}" -std=c++23 "-DINFINITY=__builtin_inff()" "-DNAN=__builtin_nanf(\"\")" --precompile $S -o e.pcm |
24 | | -try c++26 $L/bin/clang++ "${BASE[@]}" -std=c++26 --precompile $S -o f.pcm |
25 | | -SDK26=/Library/Developer/CommandLineTools/SDKs/MacOSX26.5.sdk |
26 | | -BASE26=(--no-default-config -nostdinc++ -isystem $L/include/c++/v1 -isysroot $SDK26 -Wno-reserved-module-identifier) |
27 | | -try c++23-sdk26.5 $L/bin/clang++ "${BASE26[@]}" -std=c++23 --precompile $S -o g.pcm |
28 | | -# a program importing std, end to end, with the variant that works |
29 | | -for std in c++23 gnu++23; do |
30 | | - rm -rf p; mkdir p; cd p |
31 | | - $L/bin/clang++ "${BASE[@]}" -std=$std --precompile $S -o std.pcm >/dev/null 2>&1 |
32 | | - $L/bin/clang++ "${BASE[@]}" -std=$std -c std.pcm -o std.o >/dev/null 2>&1 |
33 | | - printf 'import std;\nint main(){ std::println("inf={} nan={}", std::numeric_limits<double>::infinity(), std::isnan(std::nan(""))); }\n' > m.cpp |
34 | | - $L/bin/clang++ "${BASE[@]}" -std=$std -fmodule-file=std=std.pcm -c m.cpp -o m.o >/dev/null 2>&1 |
35 | | - $L/bin/clang++ --no-default-config -isysroot $SDK -fuse-ld=lld -nostdlib++ m.o std.o $L/lib/libc++.a $L/lib/libc++abi.a -o m >/dev/null 2>&1 |
36 | | - r "program $std: $(./m 2>&1)" |
| 7 | +BASE=(--no-default-config -nostdinc++ -isystem $L/include/c++/v1 -isysroot $SDK -Wno-reserved-module-identifier -std=c++23) |
| 8 | +try() { name=$1; shift; out=$("$@" 2>&1); rc=$?; r "$name rc=$rc $(printf '%s' "$out" | grep -m1 -E 'error|warning' | cut -c1-220)"; } |
| 9 | +r "modulemap infinity_nan: $(grep -n -A3 'infinity_nan' $($L/bin/clang -print-resource-dir)/include/module.modulemap | tr '\n' ' ')" |
| 10 | +r "driver cc1 builtin-headers: $($L/bin/clang++ "${BASE[@]}" -### -fsyntax-only -x c++ /dev/null 2>&1 | tr ' ' '\n' | grep -i 'builtin-headers\|fmodules' | tr '\n' ' ')" |
| 11 | +try baseline $L/bin/clang++ "${BASE[@]}" --precompile $S -o a.pcm |
| 12 | +try builtin-in-sysmodules $L/bin/clang++ "${BASE[@]}" -Xclang -fbuiltin-headers-in-system-modules --precompile $S -o b.pcm |
| 13 | +try no-modulemaps $L/bin/clang++ "${BASE[@]}" -fno-implicit-module-maps --precompile $S -o c.pcm |
| 14 | +try need-inf-nan $L/bin/clang++ "${BASE[@]}" -D__need_infinity_nan --precompile $S -o d.pcm |
| 15 | +try defs-sdk-spelling $L/bin/clang++ "${BASE[@]}" "-DINFINITY=HUGE_VALF" "-DNAN=__builtin_nanf(\"0x7fc00000\")" --precompile $S -o e.pcm |
| 16 | +# the winner must also give std.compat and a working program, and must not warn in plain TUs |
| 17 | +printf '#include <cmath>\n#include <cfloat>\n#include <math.h>\n#include <float.h>\nint main(){ return INFINITY > 0 && NAN != NAN ? 0 : 1; }\n' > p.cpp |
| 18 | +printf '#include <math.h>\n#include <float.h>\nint main(void){ return INFINITY > 0 && NAN != NAN ? 0 : 1; }\n' > p.c |
| 19 | +for v in "builtin-in-sysmodules:-Xclang -fbuiltin-headers-in-system-modules" "defs-sdk-spelling:-DINFINITY=HUGE_VALF -DNAN=__builtin_nanf(\"0x7fc00000\")"; do |
| 20 | + name=${v%%:*}; flags=${v#*:} |
| 21 | + eval "F=($flags)" |
| 22 | + try "$name plain-c++ -Werror" $L/bin/clang++ "${BASE[@]}" "${F[@]}" -Werror -Wall p.cpp -o pcpp |
| 23 | + try "$name plain-c -Werror" $L/bin/clang --no-default-config -isysroot $SDK "${F[@]}" -std=c17 -Werror -Wall p.c -o pc |
| 24 | + try "$name std.compat" $L/bin/clang++ "${BASE[@]}" "${F[@]}" -fmodule-file=std=a.pcm --precompile $SC -o sc.pcm |
| 25 | + rm -rf prog; mkdir prog; cd prog |
| 26 | + $L/bin/clang++ "${BASE[@]}" "${F[@]}" --precompile $S -o std.pcm >/dev/null 2>&1 |
| 27 | + $L/bin/clang++ "${BASE[@]}" "${F[@]}" -c std.pcm -o std.o >/dev/null 2>&1 |
| 28 | + printf 'export module mm;\nimport std;\n#include <cmath>\nexport double inf() { return INFINITY; }\n' > mm.cppm |
| 29 | + $L/bin/clang++ "${BASE[@]}" "${F[@]}" -fmodule-file=std=std.pcm --precompile mm.cppm -o mm.pcm 2> mm.err |
| 30 | + $L/bin/clang++ "${BASE[@]}" "${F[@]}" -c mm.pcm -o mm.o >/dev/null 2>&1 |
| 31 | + printf 'import std;\nimport mm;\nint main(){ std::println("inf={} nan={}", inf(), std::isnan(std::nan(""))); }\n' > m.cpp |
| 32 | + $L/bin/clang++ "${BASE[@]}" "${F[@]}" -fmodule-file=std=std.pcm -fmodule-file=mm=mm.pcm -c m.cpp -o m.o 2> m.err |
| 33 | + $L/bin/clang++ --no-default-config -isysroot $SDK -fuse-ld=lld -nostdlib++ m.o mm.o std.o $L/lib/libc++.a $L/lib/libc++abi.a -o m 2> l.err |
| 34 | + r "$name program: $(./m 2>&1) | $(head -1 mm.err) $(head -1 m.err) $(head -1 l.err)" |
37 | 35 | cd .. |
38 | 36 | done |
| 37 | +# same flags on the macOS 26.5 SDK: must stay green |
| 38 | +SDK26=/Library/Developer/CommandLineTools/SDKs/MacOSX26.5.sdk |
| 39 | +B26=(--no-default-config -nostdinc++ -isystem $L/include/c++/v1 -isysroot $SDK26 -Wno-reserved-module-identifier -std=c++23) |
| 40 | +try sdk26-builtin-in-sysmodules $L/bin/clang++ "${B26[@]}" -Xclang -fbuiltin-headers-in-system-modules --precompile $S -o f.pcm |
| 41 | +try sdk26-plain-c++-Werror $L/bin/clang++ "${B26[@]}" -Xclang -fbuiltin-headers-in-system-modules -Werror -Wall p.cpp -o p26 |
39 | 42 | exit 0 |
0 commit comments