llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.71k stars 11.87k forks source link

[libc++] tzdata 2024b breaks timezone parsing in std::chrono #107779

Closed steveWang closed 1 month ago

steveWang commented 1 month ago
$ clang --version
clang version 18.1.8
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /sbin

Reproducing code:

#include <chrono>
#include <iostream>

int main() {
  std::cout << std::chrono::get_tzdb().current_zone()->name() << "\n";
  return 0;
}

With tzdata-2024a, this prints out my local timezone (America/New_York) as I'd expect, but with tzdata-2024b, this prints out Etc/UTC (as it cannot find any timezones other than Etc/UTC and Etc/GMT).

I suspect this is due to a change in tzdata.zi to use %z, which the current parsing logic in tzdb.cpp doesn't seem to handle at all.

The main data form now uses %z.

https://lists.iana.org/hyperkitty/list/tz-announce@iana.org/message/IZ7AO6WRE3W3TWBL5IR6PMQUL433BQIE/

I was also able to reproduce with g++, although supposedly that project added handling in https://github.com/gcc-mirror/gcc/commit/0ca8d56f2085715f27ee536c6c344bc47af49cdd (which doesn't seem to have made the cut for gcc 14.2.0).

Ebbo commented 1 month ago

I can confirm that - Version 2024b-1 introduces the bug, while Version 2024a-2 works as expected.

SelfHostedToast commented 1 month ago

I can confirm that - Version 2024b-1 introduces the bug, while Version 2024a-2 works as expected.

Downgrading from version 2024b-1 to 2024a-2 also fixed the issue for me. Thanks!

steveWang commented 1 month ago

(Note that there seems to be a different issue making the rounds re: the inclusion of "April" in this release, but it looks like libc++'s implementation supports that.)

steveWang commented 1 month ago

Hm. I chatted with @jyknight and concluded that my issue was that I was building against libstdc++, as time_zone.cpp seems to support %z.

I'll have to check if this still reproduces with libc++ 19 or later.

dpriedel commented 1 month ago

I too am experiencing this problem with my program compiled with g++ 14.2.0

C++ exception with description "std::chrono::tzdb: cannot locate zone: Australia/Perth" thrown in the test body

Otherwise, my system seems to be functioning normally. Correct time displays in Gnome top bar.

steveWang commented 1 month ago

Okay. It seems that current HEAD does in fact have support for %z, but, I need to build with -fexperimental-library in order to enable the relevant headers.

# Building against libstdc++.so.6.0.33
$ ./bin/clang++ tz.cc -std=c++20 -fno-exceptions
$ ./a.out
Etc/UTC

# Building against libc++ at 620b8d994b8abdcf31271d9f4db7e7422fc9bd65
$ ./bin/clang++ tz.cc -std=c++20 -stdlib=libc++ -fno-exceptions -fexperimental-library
$ LD_LIBRARY_PATH=$PWD/lib ./a.out
America/New_York
mgorny commented 1 month ago

Isn't this a GCC bug then? I can reproduce with g++ too.

pinskia commented 1 month ago

Isn't this a GCC bug then? I can reproduce with g++ too.

which version of GCC? It was mentioned there was a change on the version of the trunk. Anyways the GCC version is filed as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116657 .

mgorny commented 1 month ago

GCC 14.2.1 snapshot as of 20240817.

mgorny commented 1 month ago

Ok, so I've tested quickly, and it seems that libc++ 18 doesn't have this yet, while 19.1.0rc3 seems to work fine. So I think there's nothing to do on LLVM end here?

steveWang commented 1 month ago

So I think there's nothing to do on LLVM end here?

Yeah. It looks libc++ hasn't yet marked P0355R7 as complete for C++20 support (https://github.com/llvm/llvm-project/issues/99982), so the -fexperimental-library compiler flag protection is still reasonable (and there's no need to explicitly cherrypick the relevant changes into an existing release branch).

jwakely commented 1 month ago

Not an LLVM issue, this should be closed.

jwakely commented 1 month ago

I suspect this is due to a change in tzdata.zi to use %z, which the current parsing logic in tzdb.cpp doesn't seem to handle at all.

GCC trunk handles it, but gcc-14 doesn't. Arch Linux seems to have enabled the %z format in the 2024b package, which is actually unrelated to the 2024b update (if they had enabled %z for the 2024a package, that would have failed the same way).

steveWang commented 1 month ago

The 2024b update changed the main source files to use %z, as I mentioned in the initial post. Quoting the long-form changes:

The main source files' time zone abbreviations now use %z, supported by zic since release 2015f and used in vanguard form since release 2022b.

This isn't solely an Arch Linux issue, as any other distributions that use the main data are also affected until they release a new libstdc++ with support for %z.

ldionne commented 1 month ago

Closing since this isn't a libc++ issue, see thread above.