From 74519e1c8316347dc20d8408765c6b2275fd15ba Mon Sep 17 00:00:00 2001 From: Brad King Date: Sun, 23 Feb 2025 09:56:59 -0500 Subject: string(TIMESTAMP): Fix %s placeholder for year 2038 on Windows `difftime` returns a `double`, so commit 6727270b75 (CMake: Extend TIMESTAMP sub-commands with new unix time format specifier, 2016-02-16, v3.6.0-rc1~338^2) cast it to `long` to get an integer result. However, in the MSVC ABI, `long` is a 32-bit integer. Use an explicit 64-bit integer type instead. Fixes: #26716 --- Source/cmTimestamp.cxx | 4 +++- Tests/RunCMake/CMakeLists.txt | 5 ++++- Tests/RunCMake/string/RunCMakeTest.cmake | 8 ++++++++ Tests/RunCMake/string/Timestamp2038-stderr.txt | 1 + Tests/RunCMake/string/Timestamp2038.cmake | 3 +++ 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 Tests/RunCMake/string/Timestamp2038-stderr.txt create mode 100644 Tests/RunCMake/string/Timestamp2038.cmake diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index e690774..b7452eb 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -275,7 +276,8 @@ std::string cmTimestamp::AddTimestampComponent( return std::string(); } - return std::to_string(static_cast(difftime(timeT, unixEpoch))); + return std::to_string( + static_cast(std::difftime(timeT, unixEpoch))); } case 'f': // microseconds { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index fdf26ce..698fe6c 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -660,7 +660,10 @@ add_RunCMake_test(return) add_RunCMake_test(SarifOutput) add_RunCMake_test(separate_arguments) add_RunCMake_test(set_property) -add_RunCMake_test(string) +add_RunCMake_test(string + -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} + -DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR} + ) add_RunCMake_test(test_include_dirs) add_RunCMake_test(BundleUtilities) if(APPLE) diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake index 91a03da..5b395e1 100644 --- a/Tests/RunCMake/string/RunCMakeTest.cmake +++ b/Tests/RunCMake/string/RunCMakeTest.cmake @@ -21,6 +21,14 @@ run_cmake(JoinNoArgs) run_cmake(JoinNoVar) run_cmake(Timestamp) +if(NOT CMAKE_SYSTEM_NAME STREQUAL "AIX" # FIXME: Needs 64-bit build + AND NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS" # FIXME: Needs 64-bit build + AND NOT (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND + CMAKE_SYSTEM_PROCESSOR MATCHES "^(hppa|parisc64|sparc|sparc64)$" # FIXME: 32-bit time_t? + ) + ) + run_cmake(Timestamp2038) +endif() run_cmake(TimestampEmpty) run_cmake(TimestampInvalid) run_cmake(TimestampInvalid2) diff --git a/Tests/RunCMake/string/Timestamp2038-stderr.txt b/Tests/RunCMake/string/Timestamp2038-stderr.txt new file mode 100644 index 0000000..4a2eb50 --- /dev/null +++ b/Tests/RunCMake/string/Timestamp2038-stderr.txt @@ -0,0 +1 @@ +^RESULT=2038-01-20 05:00:00.000000 Wednesday=Wed January=Jan 38 day=020 wd=3 week=03 w_iso=03 %I=05 epoch=2147576400 TZ=GMT tz=\+0000$ diff --git a/Tests/RunCMake/string/Timestamp2038.cmake b/Tests/RunCMake/string/Timestamp2038.cmake new file mode 100644 index 0000000..adbc910 --- /dev/null +++ b/Tests/RunCMake/string/Timestamp2038.cmake @@ -0,0 +1,3 @@ +set(ENV{SOURCE_DATE_EPOCH} "2147576400") +string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S.%f %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s TZ=%Z tz=%z" UTC) +message("RESULT=${RESULT}") -- cgit v0.12