Can we get consistent assertion behavior in the latest release Swift compiler across host platforms?

I have been noticing issues raised for compiler assertion crashes this year with the OSS macOS release toolchains, which are not reproducible with the Xcode or linux release toolchains, presumably because those assertions are disabled in those builds. In particular, @marcprux has filed issues like these, and I raised this problem in the forum five months ago.

I understand that it may be a contentious issue of whether the release compiler should have these assertions enabled or disabled, but I'd at least like to argue for consistency across platforms and builds, ie the latest release should make the same choice for all release compiler builds. I just raised the issue with @compnerd and @etcwilde, and @compnerd tells us that the release Windows compiler has these assertions enabled.

This is not going to be a great dev experience, if the Swift 6.1.2 compiler on linux can compile those samples linked, but the Swift 6.1.2 compiler on Windows can't.

Let me emphasize that I'm only talking about the latest patch releases like 6.1.2, the nightly snapshot builds are excluded from this discussion.

I'd like to see some consensus reached on this topic by the Swift teams, and I suspect a growing amount of Swift devs would also.

5 Likes

From a supportability point of view, the windows toolchain really does rely on the assertions heavily. The assertions have almost always found real issues that would silently potentially cause invalid code generation. or potentially allow invalid code through. I think that given the resources available for Windows, the assertions are not reasonable to disable.

We are waiting on @mishal_shah to coordiinat getting Rename toolchain msi and cab files to include name of variant (asserts) by mhegazy · Pull Request #428 · swiftlang/swift-installer-scripts · GitHub merged which will allow us to package both an Asserts and NoAsserts toolchain and the user can then select if they want to ignore the issues and build the code anyway.

1 Like

I've been consistently running into this issue for months, and have had to refactor and rearchitect a ton of perfectly valid swift code, with pure swift dependencies just to avoid compiler crashes.

This affects Skip.tools android apps, because the android sdk relies on the macOS toolchain. I started running into this as well when I was testing out the new swiftly toolchain manager.

I did notice that the last couple changes to the build toolchain are related to adding flags that allow you to target macOS specifically, and one about adding an assertions flag. Could this be an unintended interaction between those flags?

Unfortunately, programs that only compile with a no-asserts toolchain aren’t quite perfectly valid. At the very least it means you’re exercising some compiler code path that’s not covered by tests, so it could regress in a future release. We’ve also seen bugs where an input program that trips an assertion then silently miscompiles without asserts.

6 Likes

Unfortunately, programs that only compile with a no-asserts toolchain aren’t quite perfectly valid. At the very least it means you’re exercising some compiler code path that’s not covered by tests, so it could regress in a future release. We’ve also seen bugs where an input program that trips an assertion then silently miscompiles without asserts.

So does that mean that the Xcode toolchain has these assertions enabled, but generates code in a more correct way? Or does the xcode toolchain disable these assertions, potentially allowing through code that can silently miscompile?

If thats the case should people be concerned about using these features in production systems?

1 Like

https://github.com/swiftlang/swift/issues/82529

I’m coming back to this a few months later and I don’t think I’ve seen any movement.

The macOS toolchain crashes when compiling valid code on the main swift release, and the most recent 6.2 snapshot.

This issue has a minimum reproduction. It’s using newer parameter pack features. As more and more libraries adopt code that trips these assertions, projects that are using the macOS toolchain get harder and harder to compile.

Is anybody else experiencing this? Popular libraries like swift-sharing trip these assertions when I use swiftly and try to build them using the command line.

The code is not valid, because it trips an assertion. I believe this pattern can miscompile in some cases, and there’s a bug that needs to be fixed.

2 Likes

What is the rationale for the OSS toolchain enabling assertions beside shining light on bugs in the compiler itself?

Assume that a correct piece of swift code triggers an assertion failure in the OSS toolchain because the compiler does a bad transformation in SIL (or IR), then a swift-dev can compile their project using the xcode stock toolchain but not the OSS toolchain.

At least for my project, this makes the OSS toolchain nearly unusable because the SIL assertion failure might come from a dependency that I do not have control over or just from a bad transformation in the compiler.

It’s mostly that, yeah. Asserts builds produce far more actionable crash reports for compiler developers.

I understand that compiler bugs are frustrating, and having two build configurations for the toolchain is suboptimal. I do believe that an assertion should either be checked all or the time, or removed from the code — there shouldn’t be such a thing as an approximately correct precondition.

Even though it will address your immediate issue, disabling assertions in the OSS toolchain is going to move things in the wrong direction rather than improving the stability of the compiler in the long term.

The point I want to emphasize is if you’re seeing assertion failures regularly, it means you’re hitting code paths in the compiler which are not tested by the test suite, because CI always runs the compiler with assertions on. I would not trust the compiler’s output in this scenario.

2 Likes

Thanks for addressing our concerns somewhat. However,

How is Xcode handling these cases: is it simply disabling the assertions or is it doing something different where you can then trust it to compile such code?

I'm sure you can see the problem in saying you don't want to disable assertions because of the problems it would cause, then seemingly doing so anyway in Xcode and linux.

I understand that this is probably a contentious issue internally and maybe there is no way to get the cross-platform consistency I asked for given current constraints, but it is harming the cross-platform Swift experience, and it may help to at least know why certain platforms have them enabled and others don't.

And there is always the option to use the linux toolchain and cross-compile using that instead or build a Swift toolchain yourself from source, so nobody can say there aren't release valves.

1 Like

Just to add some real-world color here, we at Skip are regularly getting reports of code that builds and runs fine for iOS is raising an assertion when building for Android, especially for some of the more notorious Swift compiler 6 bugs like Parameter pack compilation crash "This isn't an lvalue" with 6.0.3 OSS toolchain but works with Xcode toolchain · Issue #79870 · swiftlang/swift · GitHub. This makes it seem like the Swift Android SDK is buggy, when in fact it is the OSS host toolchain that is exhibiting different behavior from the Xcode toolchain. This, of course, will also affect the static Linux and WASM SDKs, and any other Swift SDK due to the need to align with the OSS toolchain rather than Xcode's.

The code is not valid, because it trips an assertion. I believe this pattern can miscompile in some cases, and there’s a bug that needs to be fixed.

I don't think we've yet gotten a response about why Xcode's toolchain doesn't have assertions enabled. Is it for performance, or some other reason? Isn't there consternation at the prospect of invalid assertion-tripping code being allowed to miscompile and make its way into production iOS apps?

5 Likes