Jump to page: 1 2
Thread overview
[Issue 23846] std.math can't compile under macos rosetta
Apr 22, 2023
Caleb Xu
Apr 22, 2023
kinke
Apr 23, 2023
Caleb Xu
Apr 25, 2023
kinke
Apr 25, 2023
mhh
Apr 26, 2023
mhh
Apr 26, 2023
Caleb Xu
Apr 26, 2023
mhh
Apr 26, 2023
kinke
Apr 26, 2023
mhh
Apr 26, 2023
Caleb Xu
Apr 27, 2023
Dlang Bot
Apr 28, 2023
Dlang Bot
May 09, 2023
Scot
April 22, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

Caleb Xu <calebcenter@live.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |calebcenter@live.com

--- Comment #1 from Caleb Xu <calebcenter@live.com> ---
I am seeing a similar/same error in building dmd x64 on Intel-based macOS when trying to re-build DMD 2.103.0 as part of Homebrew packaging. So I think Rosetta can be ruled out as the culprit here.

We were able to build DMD 2.103.0 when it was initially released (~3 weeks ago) but it looks like it doesn't build anymore. My initial guess is that this may be related to Xcode 14.3 which was released recently and has been updated in Homebrew CI machines.

The following error is encountered when trying to build phobos:

/private/tmp/dmd-20230422-6518-pzw42y/dmd-2.103.0/generated/osx/release/64/dmd
-conf= -I/private/tmp/dmd-20230422-6518-pzw42y/dmd-2.103.0/druntime/import  -w
-de -preview=dip1000 -preview=dtorfields -preview=fieldwise -m64 -fPIC -O
-release -lib -ofgenerated/osx/release/64/libphobos2.a
/private/tmp/dmd-20230422-6518-pzw42y/dmd-2.103.0/druntime/../generated/osx/release/64/libdruntime.a
std/array.d std/ascii.d std/base64.d std/bigint.d std/bitmanip.d
std/checkedint.d std/compiler.d std/complex.d std/concurrency.d std/conv.d
std/csv.d std/demangle.d std/encoding.d std/exception.d std/file.d
std/functional.d std/getopt.d std/int128.d std/json.d std/mathspecial.d
std/meta.d std/mmfile.d std/numeric.d std/outbuffer.d std/package.d
std/parallelism.d std/path.d std/process.d std/random.d std/signals.d
std/socket.d std/stdint.d std/stdio.d std/string.d std/sumtype.d std/system.d
std/traits.d std/typecons.d std/uri.d std/utf.d std/uuid.d std/variant.d
std/zip.d std/zlib.d std/algorithm/comparison.d std/algorithm/iteration.d
std/algorithm/mutation.d std/algorithm/package.d std/algorithm/searching.d
std/algorithm/setops.d std/algorithm/sorting.d std/container/array.d
std/container/binaryheap.d std/container/dlist.d std/container/package.d
std/container/rbtree.d std/container/slist.d std/container/util.d
std/datetime/date.d std/datetime/interval.d std/datetime/package.d
std/datetime/stopwatch.d std/datetime/systime.d std/datetime/timezone.d
std/digest/crc.d std/digest/hmac.d std/digest/md.d std/digest/murmurhash.d
std/digest/package.d std/digest/ripemd.d std/digest/sha.d
std/experimental/allocator/common.d std/experimental/allocator/gc_allocator.d
std/experimental/allocator/mallocator.d
std/experimental/allocator/mmap_allocator.d
std/experimental/allocator/package.d std/experimental/allocator/showcase.d
std/experimental/allocator/typed.d
std/experimental/allocator/building_blocks/affix_allocator.d
std/experimental/allocator/building_blocks/aligned_block_list.d
std/experimental/allocator/building_blocks/allocator_list.d
std/experimental/allocator/building_blocks/ascending_page_allocator.d
std/experimental/allocator/building_blocks/bucketizer.d
std/experimental/allocator/building_blocks/fallback_allocator.d
std/experimental/allocator/building_blocks/free_list.d
std/experimental/allocator/building_blocks/free_tree.d
std/experimental/allocator/building_blocks/bitmapped_block.d
std/experimental/allocator/building_blocks/kernighan_ritchie.d
std/experimental/allocator/building_blocks/null_allocator.d
std/experimental/allocator/building_blocks/package.d
std/experimental/allocator/building_blocks/quantizer.d
std/experimental/allocator/building_blocks/region.d
std/experimental/allocator/building_blocks/scoped_allocator.d
std/experimental/allocator/building_blocks/segregator.d
std/experimental/allocator/building_blocks/stats_collector.d
std/experimental/logger/core.d std/experimental/logger/filelogger.d
std/experimental/logger/nulllogger.d std/experimental/logger/multilogger.d
std/experimental/logger/package.d std/format/package.d std/format/read.d
std/format/spec.d std/format/write.d std/format/internal/floats.d
std/format/internal/read.d std/format/internal/write.d std/logger/core.d
std/logger/filelogger.d std/logger/nulllogger.d std/logger/multilogger.d
std/logger/package.d std/math/algebraic.d std/math/constants.d
std/math/exponential.d std/math/hardware.d std/math/operations.d
std/math/package.d std/math/remainder.d std/math/rounding.d std/math/traits.d
std/math/trigonometry.d std/net/curl.d std/net/isemail.d std/uni/package.d
std/experimental/checkedint.d std/range/interfaces.d std/range/package.d
std/range/primitives.d std/regex/package.d std/regex/internal/generator.d
std/regex/internal/ir.d std/regex/internal/parser.d
std/regex/internal/backtracking.d std/regex/internal/tests.d
std/regex/internal/tests2.d std/regex/internal/thompson.d
std/regex/internal/kickstart.d std/windows/charset.d std/windows/registry.d
std/windows/syserror.d etc/c/curl.d etc/c/odbc/sql.d etc/c/odbc/sqlext.d
etc/c/odbc/sqltypes.d etc/c/odbc/sqlucode.d etc/c/sqlite3.d etc/c/zlib.d
std/algorithm/internal.d std/internal/cstring.d std/internal/memory.d
std/internal/digest/sha_SSSE3.d std/internal/math/biguintcore.d
std/internal/math/biguintnoasm.d std/internal/math/biguintx86.d
std/internal/math/errorfunction.d std/internal/math/gammafunction.d
std/internal/scopebuffer.d std/internal/test/dummyrange.d
std/internal/test/range.d std/internal/unicode_comp.d
std/internal/unicode_decomp.d std/internal/unicode_grapheme.d
std/internal/unicode_norm.d std/internal/unicode_tables.d
std/internal/windows/advapi32.d std/typetuple.d
generated/osx/release/64/etc/c/zlib/adler32.o
generated/osx/release/64/etc/c/zlib/compress.o
generated/osx/release/64/etc/c/zlib/crc32.o
generated/osx/release/64/etc/c/zlib/deflate.o
generated/osx/release/64/etc/c/zlib/gzclose.o
generated/osx/release/64/etc/c/zlib/gzlib.o
generated/osx/release/64/etc/c/zlib/gzread.o
generated/osx/release/64/etc/c/zlib/gzwrite.o
generated/osx/release/64/etc/c/zlib/infback.o
generated/osx/release/64/etc/c/zlib/inffast.o
generated/osx/release/64/etc/c/zlib/inflate.o
generated/osx/release/64/etc/c/zlib/inftrees.o
generated/osx/release/64/etc/c/zlib/trees.o
generated/osx/release/64/etc/c/zlib/uncompr.o
generated/osx/release/64/etc/c/zlib/zutil.o
  std/math/exponential.d(3791): Error: number `0x0.8p-126f` is not
representable as a `float`
  std/math/exponential.d(3791):
https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3791): Error: number `0x0.8p-126f` is not
representable as a `float`
  std/math/exponential.d(3791):
https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3793): Error: number `0x0.555556p-126f` is not
representable as a `float`
  std/math/exponential.d(3793):
https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3793): Error: number `0x0.555556p-126f` is not
representable as a `float`
  std/math/exponential.d(3793):
https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3804): Error: number `0x0.8p-1022` is not
representable as a `double`
  std/math/exponential.d(3804):        `real` literals can be written using the
`L` suffix. https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3804): Error: number `0x0.8p-1022` is not
representable as a `double`
  std/math/exponential.d(3804):        `real` literals can be written using the
`L` suffix. https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3806): Error: number `0x0.5555555555555p-1022` is not
representable as a `double`
  std/math/exponential.d(3806):        `real` literals can be written using the
`L` suffix. https://dlang.org/spec/lex.html#floatliteral
  std/math/exponential.d(3806): Error: number `0x0.5555555555555p-1022` is not
representable as a `double`
  std/math/exponential.d(3806):        `real` literals can be written using the
`L` suffix. https://dlang.org/spec/lex.html#floatliteral
  make: *** [generated/osx/release/64/libphobos2.a] Error 1

--
April 22, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

kinke <kinke@gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kinke@gmx.net

--- Comment #2 from kinke <kinke@gmx.net> ---
(In reply to Caleb Xu from comment #1)
> We were able to build DMD 2.103.0 when it was initially released (~3 weeks ago) but it looks like it doesn't build anymore. My initial guess is that this may be related to Xcode 14.3 which was released recently and has been updated in Homebrew CI machines.

Thanks for this insight. DMD uses the C runtime's `strto{f,d}` to check for over/underflows of float/double literals (in `Port.isFloat{32,64}LiteralOutOfRange()`). So an Apple libc change might indeed be the culprit. - LDC isn't affected, it uses LLVM functionality to parse floating-point literals.

--
April 23, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #3 from Caleb Xu <calebcenter@live.com> ---
(In reply to kinke from comment #2)
> Thanks for this insight. DMD uses the C runtime's `strto{f,d}` to check for over/underflows of float/double literals (in `Port.isFloat{32,64}LiteralOutOfRange()`). So an Apple libc change might indeed be the culprit. - LDC isn't affected, it uses LLVM functionality to parse floating-point literals.

Thanks for the tip. I tried this simple C program (based on strto{d,f} invocations from [1], [2]) on a machine with the new Xcode and it outputs four "true"s as expected. So far this seems to work, at least as far as not throwing an error when parsing the strings into float/double:

#include <stdio.h>
#include <stdlib.h>

int main() {
    float float1 = strtof("0x0.8p-126f", NULL);
    printf("%s\n", (float1 != 0) ? "true" : "false");

    float float2 = strtof("0x0.555556p-126f", NULL);
    printf("%s\n", (float2 != 0) ? "true" : "false");

    double double1 = strtod("0x0.8p-1022", NULL);
    printf("%s\n", (double1 != 0) ? "true" : "false");

    double double2 = strtod("0x0.5555555555555p-1022", NULL);
    printf("%s\n", (double2 != 0) ? "true" : "false");
}

[1]: https://github.com/dlang/dmd/blob/34c57751f8f50f623740387599f02c4ace34ee6a/compiler/src/dmd/root/port.d#L91 [2]: https://github.com/dlang/dmd/blob/34c57751f8f50f623740387599f02c4ace34ee6a/compiler/src/dmd/root/port.d#L114

--
April 25, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #4 from kinke <kinke@gmx.net> ---
(In reply to Caleb Xu from comment #3)
> I tried this simple C program (based on strto{d,f}
> invocations from [1], [2]) on a machine with the new Xcode and it outputs
> four "true"s as expected. So far this seems to work, at least as far as not
> throwing an error when parsing the strings into float/double:

What matters is whether strtof/d sets `errno` to ERANGE (e.g., https://github.com/dlang/dmd/blob/34c57751f8f50f623740387599f02c4ace34ee6a/compiler/src/dmd/root/port.d#L94).

--
April 25, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

mhh <maxhaton@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxhaton@gmail.com

--- Comment #5 from mhh <maxhaton@gmail.com> ---
The weird thing is that it *does* return the value still, which I think the standard doesn't really want it to due.

--
April 26, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #6 from mhh <maxhaton@gmail.com> ---
It isn't enough to check ERANGE - underflow can (I think it's implementation defined) trigger ERANGE but if the result is nonzero it's still supposed to be correctly rounded.

--
April 26, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #7 from Caleb Xu <calebcenter@live.com> ---
Good catch, the example program was not checking errno. I've repeated the test with a slightly modified example program:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    float float1 = strtof("0x0.8p-126f", NULL);
    printf("%s\n", (float1 != 0) ? "true" : "false");
    printf("%d\n", errno);

    float float2 = strtof("0x0.555556p-126f", NULL);
    printf("%s\n", (float2 != 0) ? "true" : "false");
    printf("%d\n", errno);

    double double1 = strtod("0x0.8p-1022", NULL);
    printf("%s\n", (double1 != 0) ? "true" : "false");
    printf("%d\n", errno);

    double double2 = strtod("0x0.5555555555555p-1022", NULL);
    printf("%s\n", (double2 != 0) ? "true" : "false");
    printf("%d\n", errno);
}

This time, the output with the newer Xcode toolchain is:

true
34
true
34
true
34
true
34

So looks like errno is indeed ERANGE here.

--
April 26, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #8 from mhh <maxhaton@gmail.com> ---
I can't find anything that obviously changed in the apple source but they don't do changelogs so hard to guess.

I'll patch the compiler soon tho. Subnormal non-hex floats should probably warn

--
April 26, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #9 from kinke <kinke@gmx.net> ---
(In reply to mhh from comment #5)
> The weird thing is that it *does* return the value still, which I think the standard doesn't really want it to due.

Does it? DMD doesn't use the value at all, it uses the `strtold` result. It just uses strtof/d to check for over/underflows of non-real literals.

> It isn't enough to check ERANGE - underflow can (I think it's implementation defined) trigger ERANGE but if the result is nonzero it's still supposed to be correctly rounded.

https://en.cppreference.com/w/c/string/byte/strtof says it returns HUGE_VAL when setting ERANGE.

> I've repeated the test with a slightly modified example program

[You'd need to reset `errno` before each call for a proper test.]

--
April 26, 2023
https://issues.dlang.org/show_bug.cgi?id=23846

--- Comment #10 from mhh <maxhaton@gmail.com> ---
Yes it does.

Huge val (i.e. infinity) is returned on overflow when the number is too large but not when it underflows which is the case here.

The result of an underflow is nonetheless still a valid finite float, but with less precision in the mantissa. So it needs to check the result too if ERANGE is returned.

Microsoft don't define underflow in their docs so it's possible their behaviour is different.

--
« First   ‹ Prev
1 2