Skip to content
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

[SR-1258] switch on invalid rawValue results takes first case #43866

Closed
josephlord opened this issue Apr 18, 2016 · 4 comments
Closed

[SR-1258] switch on invalid rawValue results takes first case #43866

josephlord opened this issue Apr 18, 2016 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation

Comments

@josephlord
Copy link

Previous ID SR-1258
Radar None
Original Reporter @josephlord
Type Bug
Status Resolved
Resolution Done
Environment

The above code shows the Swift behaviour in the Playground.

It hit the issue in real use (see above link) when running in the iOS 8 simulator with my application build in Xcode 7.3 with the iOS 9 SDK.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, LanguageFeatureRequest
Assignee None
Priority Medium

md5: b9d88ff543f06fd169250b06744501c0

Issue Description:

When some an enum with a rawValue type actually has a raw value outside of the valid range and there is no default in the switch type the first case is taken and there is no runtime error or crash reported. This is dangerous behaviour admittedly requiring an error to have been made (in non-Swift code usually) to cause the invalid value to exist but even the biggest and fruitiest of companies has been known to make such mistakes (zero value NSFetchedResultsChangeType received|http://stackoverflow.com/a/32978387/1476206]).

for i in -2..<8 {

let changeType:NSFetchedResultsChangeType = unsafeBitCast(i, NSFetchedResultsChangeType.self)

switch changeType {
case .Move:
    print("Move - \(changeType.rawValue)")
case .Update:
    print("Update - \(changeType.rawValue)")
case .Insert:
    print("Insert - \(changeType.rawValue)")
case .Delete:
    print("Delete - \(changeType.rawValue)")
}

}

/* Move - 18446744073709551614
 Move - 18446744073709551615
 Move - 0
 Insert - 1
 Delete - 2
 Move - 3
 Update - 4
 Move - 5
 Move - 6
 Move - 7 */

The unsafeBitCast is used to force the error within Swift but the more likely real case in an error in code written in an unsafe language being returned or passed into Swift code.

I think the very least that should be done by Swift is to raise an assertion in these situations and probably a PreConditionFailure.

@josephlord
Copy link
Author

I've had a look into the source code and I think the issue is at line 755 in GenEnum.cpp. That it creates an unreachable block makes the behaviour undefined for values that don't have a case.

What I'd like to is replace the `IGF.Builder.CreateUnreachable();` call with one to create an assertionFailure call instead (or something similar that optimises based on unreachability in normal release code). It should also only change for enums with a raw value but that is the next thing I need to investigate.

This is my first proper attempt to make a compiler change.

@josephlord
Copy link
Author

A further thought maybe the issue is more general than I'm looking at and I should be looking to make reaching "Unreachable" code an error in debug? Any thoughts about whether this is a good idea/possible and whether it needs a separate bug or even swift-evolution proposal?

@josephlord
Copy link
Author

jckarter on Twitter: "The issue there is that imported NS_ENUMs ought to be considered "open" enums, so switching always requires a default." https://twitter.com/jckarter/status/723184633169338369

I'm preparing an evolution proposal.

@belkadan
Copy link
Contributor

This got implemented in Swift 4.2; the compiler will now deterministically trap when an @objc enum has an unexpected value.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation
Projects
None yet
Development

No branches or pull requests

2 participants