Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Jun 2017 03:04:19 -0700
From:      Mark Millard <markmi@dsl-only.net>
To:        Justin Hibbits <jhibbits@FreeBSD.org>
Cc:        FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD Current <freebsd-current@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>
Subject:   Re: head -r320458 (e.g.) amd64 -> powerpc (32-bit) cross-buildworld fails for time libc++ static_asserts and overflow/underflow of long long (system clang/clang++ 4 based build)
Message-ID:  <AFCE7DA0-E8D2-4FC7-9E2F-78011E54F1A0@dsl-only.net>
In-Reply-To: <5B12D9A6-C9A2-4B0D-B32D-D04D7DB1E3BC@dsl-only.net>
References:  <D8AB364D-9E4B-470A-A858-842E73530C3B@dsl-only.net> <5B12D9A6-C9A2-4B0D-B32D-D04D7DB1E3BC@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
[The libc++ code in question appears to not be ready for
32-bit contexts with 64 bit times. Disable
experimental/filesystem for now? I've submitted
llvm bugzilla 33638 for the issue and have
added it to llvm's 25780, the FreeBSD META for
clang.]

On 2017-Jun-29, at 2:21 AM, Mark Millard <markmi@dsl-only.net> wrote:

> [TARGET_ARCH=3Dpowerpc64 fails similarly in its world32
> part of its build.]
>=20
> On 2017-Jun-29, at 1:33 AM, Mark Millard <markmi@dsl-only.net> wrote:
>=20
>> Beyond static_assert failures and overflow/underflow of long long
>> it also it complains in some cases about:
>>=20
>> static_assert expression is not an integral constant expression
>>=20
>>=20
>> [I will note that attempting a gcc 4.2.1 build did not
>> stop and report such things for its libstdc++. The below
>> is somehow libc++ and/or clang 4 specific.]
>>=20
>>=20
>> Context:
>>=20
>> # uname -apKU
>> FreeBSD FreeBSDx64OPC 12.0-CURRENT FreeBSD 12.0-CURRENT  r320458M  =
amd64 amd64 1200036 1200036
>>=20
>> buildworld for TARGET_ARCH=3Dpowerpc resulted in:
>>=20
>> --- filesystem/operations.o ---
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:579:1: =
error: static_assert failed ""
>> static_assert(is_representable({max_time_t, 999999999}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:580:1: =
error: static_assert failed ""
>> static_assert(is_representable({max_time_t, 1000000000}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:581:1: =
error: static_assert failed ""
>> static_assert(is_representable({min_time_t, 0}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:603:1: =
error: static_assert failed ""
>> static_assert(!is_representable(file_time_type::max()), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:604:1: =
error: static_assert failed ""
>> static_assert(!is_representable(file_time_type::min()), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:605:15:=
 error: static_assert expression is not an integral constant expression
>> static_assert(is_representable(file_time_type(seconds(max_time_t))), =
"");
>>             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> /usr/src/contrib/libc++/include/chrono:386:59: note: value =
9223372036854775807000000 is outside the range of representable values =
of type 'long long'
>>                          static_cast<_Ct>(__fd.count()) * =
static_cast<_Ct>(_Period::num)));
>>                                                         ^
>> /usr/src/contrib/libc++/include/chrono:413:12: note: in call to =
'&__duration_cast<duration<long long, std::__1::ratio<1, 1> >, =
std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000> > =
>()->operator()(seconds(max_time_t))'
>>   return __duration_cast<duration<_Rep, _Period>, =
_ToDuration>()(__fd);
>>          ^
>> /usr/src/contrib/libc++/include/chrono:560:26: note: in call to =
'duration_cast(seconds(max_time_t))'
>>               : =
__rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
>>                        ^
>> /usr/src/contrib/libc++/include/__config:390:15: note: expanded from =
macro '_VSTD'
>> #define _VSTD std::_LIBCPP_NAMESPACE
>>             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:605:47:=
 note: in call to 'duration(seconds(max_time_t), 0)'
>> static_assert(is_representable(file_time_type(seconds(max_time_t))), =
"");
>>                                             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:606:15:=
 error: static_assert expression is not an integral constant expression
>> static_assert(is_representable(file_time_type(seconds(min_time_t))), =
"");
>>             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> /usr/src/contrib/libc++/include/chrono:386:59: note: value =
-9223372036854775808000000 is outside the range of representable values =
of type 'long long'
>>                          static_cast<_Ct>(__fd.count()) * =
static_cast<_Ct>(_Period::num)));
>>                                                         ^
>> /usr/src/contrib/libc++/include/chrono:413:12: note: in call to =
'&__duration_cast<duration<long long, std::__1::ratio<1, 1> >, =
std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000> > =
>()->operator()(seconds(min_time_t))'
>>   return __duration_cast<duration<_Rep, _Period>, =
_ToDuration>()(__fd);
>>          ^
>> /usr/src/contrib/libc++/include/chrono:560:26: note: in call to =
'duration_cast(seconds(min_time_t))'
>>               : =
__rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
>>                        ^
>> /usr/src/contrib/libc++/include/__config:390:15: note: expanded from =
macro '_VSTD'
>> #define _VSTD std::_LIBCPP_NAMESPACE
>>             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:606:47:=
 note: in call to 'duration(seconds(min_time_t), 0)'
>> static_assert(is_representable(file_time_type(seconds(min_time_t))), =
"");
>>                                             ^
>> . . .
>> --- lib__L ---
>> 7 errors generated.
>> *** [filesystem/operations.o] Error code 1
>>=20
>> make[5]: stopped in /usr/src/lib/libc++experimental
>> .ERROR_TARGET=3D'filesystem/operations.o'
>> =
.ERROR_META_FILE=3D'/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/lib=
/libc++experimental/_usr_obj_powerpcvtsc_clang_powerpc.powerpc_usr_src_lib=
_libc++experimental_filesystem_operations.o.meta'
>> .MAKE.LEVEL=3D'5'
>> MAKEFILE=3D''
>> .MAKE.MODE=3D'meta missing-filemon=3Dyes missing-meta=3Dyes =
silent=3Dyes verbose'
>> _ERROR_CMD=3D'c++  -target powerpc-unknown-freebsd12.0 =
--sysroot=3D/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/tmp =
-B/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/tmp/usr/bin  -O2 =
-pipe -fstack-protector-strong -Wno-empty-body -Wno-string-plus-int =
-Wno-unused-const-variable -Wno-tautological-compare -Wno-unused-value =
-Wno-parentheses-equality -Wno-unused-function -Wno-enum-conversion =
-Wno-unused-local-typedef -Wno-address-of-packed-member -Wno-switch =
-Wno-switch-enum -Wno-knr-promoted-parameter -Wno-parentheses =
-Qunused-arguments  -fpic -isystem /usr/src/contrib/libc++/include =
-nostdinc++ -nostdlib -D_LIBCPP_BUILDING_LIBRARY -DLIBCXXRT -std=3Dc++14 =
-Wno-c++11-extensions  -c =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp -o =
filesystem/operations.o;'
>> .CURDIR=3D'/usr/src/lib/libc++experimental'
>>=20
>>=20
>> # more =
/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/lib/libc++experimental/=
_usr_obj_powerpcvtsc_clang_powerpc.powerpc_usr_src_lib_libc++experimental_=
filesystem_operations.o.meta
>> # Meta data file =
/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/lib/libc++experimental/=
_usr_obj_powerpcvtsc_clang_powerpc.powerpc_usr_src_lib_libc++experimental_=
filesystem_operations.o.meta
>> CMD c++  -target powerpc-unknown-freebsd12.0 =
--sysroot=3D/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/tmp =
-B/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/tmp/usr/bin  -O2 =
-pipe -fstack-protector-strong -Wno-empty-body -Wno-string-plus-int =
-Wno-unused-const-variable -Wno-tautological-compare -Wno-unused-value =
-Wno-parentheses-equality -Wno-unused-function -Wno-enum-conversion =
-Wno-unused-local-typedef -Wno-address-of-packed-member -Wno-switch =
-Wno-switch-enum -Wno-knr-promoted-parameter -Wno-parentheses =
-Qunused-arguments  -fpic -isystem /usr/src/contrib/libc++/include =
-nostdinc++ -nostdlib -D_LIBCPP_BUILDING_LIBRARY -DLIBCXXRT -std=3Dc++14 =
-Wno-c++11-extensions  -c =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp -o =
filesystem/operations.o
>> CWD =
/usr/obj/powerpcvtsc_clang/powerpc.powerpc/usr/src/lib/libc++experimental
>> TARGET filesystem/operations.o
>> -- command output --
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:579:1: =
error: static_assert failed ""
>> static_assert(is_representable({max_time_t, 999999999}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:580:1: =
error: static_assert failed ""
>> static_assert(is_representable({max_time_t, 1000000000}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:581:1: =
error: static_assert failed ""
>> static_assert(is_representable({min_time_t, 0}), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:603:1: =
error: static_assert failed ""
>> static_assert(!is_representable(file_time_type::max()), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:604:1: =
error: static_assert failed ""
>> static_assert(!is_representable(file_time_type::min()), "");
>> ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:605:15:=
 error: static_assert expression is not an integral constant expression
>> static_assert(is_representable(file_time_type(seconds(max_time_t))), =
"");
>>             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> /usr/src/contrib/libc++/include/chrono:386:59: note: value =
9223372036854775807000000 is outside the range of representable values =
of type 'long long'
>>                          static_cast<_Ct>(__fd.count()) * =
static_cast<_Ct>(_Period::num)));
>>                                                         ^
>> /usr/src/contrib/libc++/include/chrono:413:12: note: in call to =
'&__duration_cast<duration<long long, std::__1::ratio<1, 1> >, =
std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000> > =
>()->operator()(seconds(max_time_t))'
>>   return __duration_cast<duration<_Rep, _Period>, =
_ToDuration>()(__fd);
>>          ^
>> /usr/src/contrib/libc++/include/chrono:560:26: note: in call to =
'duration_cast(seconds(max_time_t))'
>>               : =
__rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
>>                        ^
>> /usr/src/contrib/libc++/include/__config:390:15: note: expanded from =
macro '_VSTD'
>> #define _VSTD std::_LIBCPP_NAMESPACE
>>             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:605:47:=
 note: in call to 'duration(seconds(max_time_t), 0)'
>> static_assert(is_representable(file_time_type(seconds(max_time_t))), =
"");
>>                                             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:606:15:=
 error: static_assert expression is not an integral constant expression
>> static_assert(is_representable(file_time_type(seconds(min_time_t))), =
"");
>>             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> /usr/src/contrib/libc++/include/chrono:386:59: note: value =
-9223372036854775808000000 is outside the range of representable values =
of type 'long long'
>>                          static_cast<_Ct>(__fd.count()) * =
static_cast<_Ct>(_Period::num)));
>>                                                         ^
>> /usr/src/contrib/libc++/include/chrono:413:12: note: in call to =
'&__duration_cast<duration<long long, std::__1::ratio<1, 1> >, =
std::__1::chrono::duration<long long, std::__1::ratio<1, 1000000> > =
>()->operator()(seconds(min_time_t))'
>>   return __duration_cast<duration<_Rep, _Period>, =
_ToDuration>()(__fd);
>>          ^
>> /usr/src/contrib/libc++/include/chrono:560:26: note: in call to =
'duration_cast(seconds(min_time_t))'
>>               : =
__rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {}
>>                        ^
>> /usr/src/contrib/libc++/include/__config:390:15: note: expanded from =
macro '_VSTD'
>> #define _VSTD std::_LIBCPP_NAMESPACE
>>             ^
>> =
/usr/src/contrib/libc++/src/experimental/filesystem/operations.cpp:606:47:=
 note: in call to 'duration(seconds(min_time_t), 0)'
>> static_assert(is_representable(file_time_type(seconds(min_time_t))), =
"");
>>                                             ^
>> 7 errors generated.
>> *** Error code 1
>>=20
>>=20
>>=20
>> Build configuration:
>>=20
>>=20
>> # svnlite info /usr/src/ | grep "Re[plv]"
>> Relative URL: ^/head
>> Repository Root: svn://svn.freebsd.org/base
>> Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
>> Revision: 320458
>> Last Changed Rev: 320458
>>=20
>>=20
>> # more =
~/sys_build_scripts.amd64-host/make_powerpcvtsc_nodebug_clang_bootstrap-am=
d64-host.sh=20
>> kldload -n filemon && \
>> script =
~/sys_typescripts/typescript_make_powerpcvtsc_nodebug_clang_bootstrap-amd6=
4-host-$(date +%Y-%m-%d:%H:%M:%S) \
>> env __MAKE_CONF=3D"/root/src.configs/make.conf" SRCCONF=3D"/dev/null" =
SRC_ENV_CONF=3D"/root/src.configs/src.conf.powerpc-clang-bootstrap.amd64-h=
ost" \
>> WITH_META_MODE=3Dyes \
>> MAKEOBJDIRPREFIX=3D"/usr/obj/powerpcvtsc_clang" \
>> make $*
>>=20
>>=20
>> # more /root/src.configs/src.conf.powerpc-clang-bootstrap.amd64-host
>> TO_TYPE=3Dpowerpc
>> #
>> KERNCONF=3DGENERICvtsc-NODBG
>> TARGET=3D${TO_TYPE}
>> .if ${.MAKE.LEVEL} =3D=3D 0
>> TARGET_ARCH=3D${TO_TYPE}
>> .export TARGET_ARCH
>> .endif
>> #
>> WITH_CROSS_COMPILER=3D
>> WITHOUT_SYSTEM_COMPILER=3D
>> #
>> WITH_LIBCPLUSPLUS=3D
>> WITH_BINUTILS_BOOTSTRAP=3D
>> WITH_ELFTOOLCHAIN_BOOTSTRAP=3D
>> WITH_CLANG_BOOTSTRAP=3D
>> WITH_CLANG=3D
>> WITH_CLANG_IS_CC=3D
>> WITH_CLANG_FULL=3D
>> WITH_CLANG_EXTRAS=3D
>> WITH_LLD=3D
>> # lldb requires missing atomic 8-byte operations for powerpc (non-64)
>> WITHOUT_LLDB=3D
>> #
>> WITH_BOOT=3D
>> WITHOUT_LIB32=3D
>> #
>> WITHOUT_GCC_BOOTSTRAP=3D
>> WITHOUT_GCC=3D
>> WITHOUT_GCC_IS_CC=3D
>> WITHOUT_GNUCXX=3D
>> #
>> NO_WERROR=3D
>> #
>> # Use WERROR to avoid stopping at the likes of:
>> # error: implicit conversion from 'int' to 'int8_t' (aka 'signed =
char') changes value from 128 to -128 [-Werror,-Wconstant-conversion]
>> WERROR=3D
>> MALLOC_PRODUCTION=3D
>> #
>> WITH_REPRODUCIBLE_BUILD=3D
>> WITH_DEBUG_FILES=3D
>=20
>=20
> The world32 part of a TARGET_ARCH=3Dpowerpc64 cross-buildworld
> also gets the same errors.

Turns out the libc++ code in question looks like:

_LIBCPP_CONSTEXPR_AFTER_CXX11
bool is_representable(TimeSpec const& tm) {
  if (tm.tv_sec >=3D 0) {
    return (tm.tv_sec < max_seconds) ||
        (tm.tv_sec =3D=3D max_seconds && tm.tv_nsec <=3D max_nsec);
  } else if (tm.tv_sec =3D=3D (min_seconds - 1)) {
     return tm.tv_nsec >=3D min_nsec_timespec;
  } else {
    return (tm.tv_sec >=3D min_seconds);
  }
}
#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR
#if defined(__LP64__)
. . .
#else
static_assert(is_representable({max_time_t, 999999999}), "");
static_assert(is_representable({max_time_t, 1000000000}), "");
static_assert(is_representable({min_time_t, 0}), "");
#endif
#endif
                              =20
_LIBCPP_CONSTEXPR_AFTER_CXX11
bool is_representable(file_time_type const& tm) {
  auto secs =3D duration_cast<seconds>(tm.time_since_epoch());
  auto nsecs =3D duration_cast<nanoseconds>(tm.time_since_epoch() - =
secs);
  if (nsecs.count() < 0) {
    secs =3D secs +  seconds(1);
    nsecs =3D nsecs + seconds(1);
  }
  using TLim =3D numeric_limits<time_t>;
  if (secs.count() >=3D 0)
    return secs.count() <=3D TLim::max();
  return secs.count() >=3D TLim::min();
}
#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR
#if defined(__LP64__)
. . .
#else
static_assert(!is_representable(file_time_type::max()), "");
static_assert(!is_representable(file_time_type::min()), "");
static_assert(is_representable(file_time_type(seconds(max_time_t))), =
"");
static_assert(is_representable(file_time_type(seconds(min_time_t))), =
"");
#endif
#endif

_LIBCPP_CONSTEXPR_AFTER_CXX11
file_time_type convert_timespec(TimeSpec const& tm) {
  auto adj_msec =3D =
duration_cast<microseconds>(nanoseconds(tm.tv_nsec));
  if (tm.tv_sec >=3D 0) {
    auto Dur =3D seconds(tm.tv_sec) + microseconds(adj_msec);
    return file_time_type(Dur);
  } else if =
(duration_cast<microseconds>(nanoseconds(tm.tv_nsec)).count() =3D=3D 0) =
{
    return file_time_type(seconds(tm.tv_sec));
  } else { // tm.tv_sec < 0
    auto adj_subsec =3D duration_cast<microseconds>(seconds(1) - =
nanoseconds(tm.tv_nsec));
    auto Dur =3D seconds(tm.tv_sec + 1) - adj_subsec;
    return file_time_type(Dur);
  }
}
#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR
#if defined(__LP64__)
. . .
#else
// FIXME add tests for 32 bit builds
#endif
#endif

That "FIXME" likely gives a clue as to the status of
of the handling for ILP32 contexts.

There seems to be the expectation that IPL32 will not
have 64-bit time_t as well.


=3D=3D=3D
Mark Millard
markmi at dsl-only.net




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AFCE7DA0-E8D2-4FC7-9E2F-78011E54F1A0>