Skip to content

build with 64-bit time_t on 32-bit platforms #82595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2025

Conversation

lhoward
Copy link
Contributor

@lhoward lhoward commented Jun 28, 2025

It is good practice to build with 64-bit time_t/timeval on 32-bit platforms to avoid the Y2038 issue. This is the default when building on Yocto for armv7, for example. Unfortunately suseconds_t is not an alias to a type of the correct width (unlike time_t).

Question: on release/6.1, tv_usec is assumed to be Int32, but on main it is Int, but appears to be the same commit hash?

git blame main stdlib/public/Platform/Platform.swift

e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 350) @available(SwiftStdlib 5.7, *)
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 351) extension timeval {
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 352)   @available(SwiftStdlib 5.7, *)
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 353)   public init(_ duration: Duration) {
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 354)     let comps = duration.components
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 355)   // Linux platforms define timeval as Int/Int
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 356)   self.init(tv_sec: Int(comps.seconds),
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 357)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 358)   }
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 359) }

git blame release/6.1 stdlib/public/Platform/Platform.swift

e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 455) @available(SwiftStdlib 5.7, *)
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 456) extension timeval {
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 457)   @available(SwiftStdlib 5.7, *)
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 458)   public init(_ duration: Duration) {
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 459)     let comps = duration.components
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 460) #if os(Linux)
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 461)   // Linux platforms define timeval as Int/Int
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 462)   self.init(tv_sec: Int(comps.seconds),
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 463)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 464) #else
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 465)     // Darwin platforms define timeval as Int/Int32
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 466)     self.init(tv_sec: Int(comps.seconds),
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 467)               tv_usec: Int32(comps.attoseconds / 1_000_000_000_000))
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 468) #endif
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 469)   }
e675b310f89b (Philippe Hausler    2022-02-17 09:32:46 -0800 470) }

It is good practice to build with 64-bit time_t/timeval on 32-bit platforms to
avoid the Y2038 issue. This is the default when building on Yocto for armv7,
for example. Unfortunately suseconds_t is not an alias to a type of the correct
width (unlike time_t).
@jeremy-prater
Copy link

jeremy-prater commented Jun 28, 2025

time_t being 64-bit on 32-bit native systems is a yes. Required.

@xtremekforever
Copy link
Contributor

@al45tair @MaxDesiatov

@xtremekforever
Copy link
Contributor

xtremekforever commented Jun 28, 2025

This patch is for any 32-bit platform, so that could include i686, armv5-armv7, and maybe WASI as well. However, be advised that if this change is made to Swift, code in swift-nio that uses this API will require modifications as well to compile properly when Int is the same size as Int32.

It also has me thinking @MaxDesiatov, how does WASI handle this stuff? Is timeval also 32-bits on that platform? @kateinoigakukun

@lhoward
Copy link
Contributor Author

lhoward commented Jun 28, 2025

This patch is for any 32-bit platform, so that could include i686, armv5-armv7, and maybe WASI as well. However, be advised that if this change is made to Swift, code in swift-nio that uses this API will require modifications as well to compile properly when Int is the same size as Int32.

The change in this PR doesn't affect the API that stdlib exports. The SwiftNIO issue is orthogonal (it's the same issue, but it's independent of stdlib being fixed to support 64-bit time_t on 32-bit systems, except to the extent that stdlib is a dependency).

@MaxDesiatov
Copy link
Contributor

@swift-ci smoke test

@MaxDesiatov MaxDesiatov requested review from kateinoigakukun and al45tair and removed request for kateinoigakukun June 30, 2025 13:18
@phausler phausler merged commit 451f309 into swiftlang:main Jul 1, 2025
3 checks passed
lhoward added a commit to lhoward/swift that referenced this pull request Jul 1, 2025
It is good practice to build with 64-bit `time_t`/timeval on 32-bit
platforms to avoid the Y2038 issue. This is the default when building on
Yocto for armv7, for example. Unfortunately `suseconds_t` is not an
alias to a type of the correct width (unlike time_t).

Question: on release/6.1, tv_usec is assumed to be `Int32`, but on main
it is `Int`, but appears to be the same commit hash?

```
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 350) @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 351) extension timeval {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 352)   @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 353)   public init(_ duration: Duration) {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 354)     let comps = duration.components
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 355)   // Linux platforms define timeval as Int/Int
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 356)   self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 357)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 358)   }
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 359) }
```

```
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 455) @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 456) extension timeval {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 457)   @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 458)   public init(_ duration: Duration) {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 459)     let comps = duration.components
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 460) #if os(Linux)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 461)   // Linux platforms define timeval as Int/Int
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 462)   self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 463)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 464) #else
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 465)     // Darwin platforms define timeval as Int/Int32
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 466)     self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 467)               tv_usec: Int32(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 468) #endif
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 469)   }
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 470) }
```
susmonteiro pushed a commit to susmonteiro/swift that referenced this pull request Jul 2, 2025
It is good practice to build with 64-bit `time_t`/timeval on 32-bit
platforms to avoid the Y2038 issue. This is the default when building on
Yocto for armv7, for example. Unfortunately `suseconds_t` is not an
alias to a type of the correct width (unlike time_t).

Question: on release/6.1, tv_usec is assumed to be `Int32`, but on main
it is `Int`, but appears to be the same commit hash?

#### git blame main stdlib/public/Platform/Platform.swift

```
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 350) @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 351) extension timeval {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 352)   @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 353)   public init(_ duration: Duration) {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 354)     let comps = duration.components
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 355)   // Linux platforms define timeval as Int/Int
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 356)   self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 357)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 358)   }
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 359) }
```

#### git blame release/6.1 stdlib/public/Platform/Platform.swift

```
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 455) @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 456) extension timeval {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 457)   @available(SwiftStdlib 5.7, *)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 458)   public init(_ duration: Duration) {
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 459)     let comps = duration.components
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 460) #if os(Linux)
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 461)   // Linux platforms define timeval as Int/Int
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 462)   self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 463)               tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 464) #else
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 465)     // Darwin platforms define timeval as Int/Int32
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 466)     self.init(tv_sec: Int(comps.seconds),
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 467)               tv_usec: Int32(comps.attoseconds / 1_000_000_000_000))
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 468) #endif
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 469)   }
e675b31 (Philippe Hausler    2022-02-17 09:32:46 -0800 470) }
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants