Skip to content

Fixes overflow trap when creating DispatchTime objects with large upt… #12387

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
Oct 16, 2017
Merged

Fixes overflow trap when creating DispatchTime objects with large upt… #12387

merged 1 commit into from
Oct 16, 2017

Conversation

ktopley-apple
Copy link
Contributor

@ktopley-apple ktopley-apple commented Oct 11, 2017

…imeNanoseconds values and re-enables the tests that failed.

Adds some additional tests.

(rdar://problem/34751238)

The change is in three parts:

  1. The value UInt64.max passed to the DispatchTime initializer means DISPATCH_TIME_FOREVER and should not be scaled using the Mach timebase.
  2. The scaling calculations need to detect overflow and clamp to UInt64.max if this occurs, making the value equal to DISPATCH_TIME_FOREVER
  3. The getter for the uptimeNanoseconds also needs to be protected against overflow and return UInt64.max if it occurs.

@ktopley-apple
Copy link
Contributor Author

@swift-ci please clean smoke test

+ UInt64(DispatchTime.timebaseInfo.numer - 1)) / UInt64(DispatchTime.timebaseInfo.numer)

// UInt64.max means distantFuture. Do not try to scale it.
if rawValue != UInt64.max && DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the scaling could always trigger an overflow, right? Is this sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I protected the operations with overflow checks, apart from the division which can't overflow, so I don't think anything else can trap.

Copy link
Contributor

@gparker42 gparker42 Oct 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what does this if do? Is it simply trying to optimize some values on some platforms?

Copy link
Contributor Author

@ktopley-apple ktopley-apple Oct 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first part lets UInt64.max get through unchanged, the second part avoids the arithmetic when there is no timebase scaling. So yes, the second part is an optimization (that was already there).

time = DispatchTime(uptimeNanoseconds: UInt64.max)
expectEqual(time.uptimeNanoseconds, UInt64.max)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any of these exercise the overflow paths. You should add values like UInt64.max-1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point and when I tried some of the larger values, it turns out that the forced ceiling of UInt64.max for the multiplication produces some odd results. I am going to revisit that.

@ktopley-apple
Copy link
Contributor Author

@swift-ci please clean smoke test

1 similar comment
@ktopley-apple
Copy link
Contributor Author

@swift-ci please clean smoke test

…imeNanoseconds values and re-enables the tests that failed.

Adds some additional tests.
@ktopley-apple
Copy link
Contributor Author

Squashed commits.

@ktopley-apple
Copy link
Contributor Author

@swift-ci please smoke test

@ktopley-apple ktopley-apple merged commit 95564f2 into swiftlang:master Oct 16, 2017
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.

4 participants