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-44] Checking protocol adherence of self in a static function produces LLVM ERROR #42667

Closed
swift-ci opened this issue Dec 4, 2015 · 6 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself IRGen LLVM IR generation

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 4, 2015

Previous ID SR-44
Radar None
Original Reporter dhogborg (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Apple Swift version 2.1 (swiftlang-700.1.101.6 clang-700.1.76)
Target: x86_64-apple-darwin15.0.0

XCode 7.1.1

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

md5: 21024ad993e0d6972717c96c9ea9af7d

Issue Description:

Xcode and Playgrounds thinks this is valid code. Not until swiftc try to compile it the error is discovered. At that point it's not clear where the error is located as Xcode does not give any more information than the comment below. Playgrounds generates a crash log when communication is interrupted unexpectedly.

Checking protocol adherence of a subclass in a static function is not caught by linter and produces a really unhelpful error message. This should be caught and referenced by line of code where the error is located.

protocol ChildProt : class {
    init()
    func name() -> String
}


class Parent {
    
    required init() {}
    
    static func queryChildren() -> [ChildProt] {
        // don't try to check a protocol adherence of self in a static function
        guard let prot = self as? ChildProt else {
            preconditionFailure()
        }
        return [prot.dynamicType.init()]
    }
    
}

class Child : Parent, ChildProt {
    
    var NAME = "John Doe"
    
    required init() {}
    
    func name() -> String {
        return self.NAME
    }
}

let child = Child.queryChildren().first!
child.name()

After hunting down the offending file, this is the error message produced by swiftc and presented in Xcode.

 Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

 PHI nodes must have at least one entry.  If the block is dead, the PHI should be removed!
 %50 = phi i8** , !dbg !530
 LLVM ERROR: Broken function found, compilation aborted!

Playground with example code attached

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 4, 2015

Comment by Roshan R (JIRA)

Can self even be used in a static function considering there isn't an instance for it to refer to?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 4, 2015

Comment by David Högborg (JIRA)

It can't. But the error produced should be clear and referencing the file and line of code in question.

@belkadan
Copy link
Contributor

belkadan commented Dec 8, 2015

In a class function, self refers to the class. This is true even when the function is declared static (that's just class + final).

Obviously we shouldn't crash here.

@slavapestov
Copy link
Member

This is still crashing for me with Swift 2.2, but it works fine on master. Does anyone know what got fixed? @DougGregor @rjmccall

@rjmccall
Copy link
Member

No idea.

@slavapestov
Copy link
Member

This no longer crashes the compiler, but note that the code itself is invalid because its casting self in a static method (which is a metatype) to a protocol value. Fixed version:

protocol ChildProt : class {
    init()
    func name() -> String
}


class Parent {
    
    required init() {}
    
    static func queryChildren() -> [ChildProt] {
        // don't try to check a protocol adherence of self in a static function
        guard let prot = self as? ChildProt.Type else {
            preconditionFailure()
        }
        return [prot.init()]
    }
    
}

class Child : Parent, ChildProt {
    
    var NAME = "John Doe"
    
    required init() {}
    
    func name() -> String {
        return self.NAME
    }
}

let child = Child.queryChildren().first!
child.name()

@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 IRGen LLVM IR generation
Projects
None yet
Development

No branches or pull requests

4 participants