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

[cxx-interop] Bitfield setter/getter for SWIFT_UNSAFE_REFERENCE crashes frontend #80182

Closed
ADKaster opened this issue Mar 20, 2025 · 7 comments · Fixed by #80197
Closed

[cxx-interop] Bitfield setter/getter for SWIFT_UNSAFE_REFERENCE crashes frontend #80182

ADKaster opened this issue Mar 20, 2025 · 7 comments · Fixed by #80197
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. c++ interop Feature: Interoperability with C++ c++ to swift Feature → c++ interop: c++ to swift crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels

Comments

@ADKaster
Copy link
Contributor

ADKaster commented Mar 20, 2025

Description

A SWIFT_UNSAFE_REFERENCE class with a getter/setter for a bitfield member crashes the frontend when using `-emit-clang-header-path

Reproduction

Test.h

#pragma once

#include <swift/bridging>

class S {
public:
  bool is_marked() const { return m_marked; }
  void set_marked(bool b) { m_marked = b; }
private:
  bool m_marked : 1 { false };
} SWIFT_UNSAFE_REFERENCE;

module.modulemap

module MyCxx {
   header "Test.h"
   requires cplusplus
   export *
}

main.swift

import MyCxx

func doSomethingWith(_ s: S) {}

Test with:

swift-frontend -typecheck \
  -I. \
  -cxx-interoperability-mode=default \
  -emit-clang-header-path MyModule-Swift.h \
  -module-name MyModule \
  -I$(swiftc -print-target-info | jq -r '.paths.runtimeResourcePath + "/../../include"') \
  main.swift

Stack dump

mutating function in a class
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.      Program arguments: swift-frontend -typecheck -I. -cxx-interoperability-mode=default -emit-clang-header-path MyModule-Swift.h -module-name MyModule -I/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/lib/swift/../../include main.swift
1.      Swift version 6.2-dev (LLVM 162ee50b401fff2, Swift 57288d13c9f3c02)
2.      Compiling with effective version 5.10
3.      While verifying AccessorDecl setter for m_marked (at /home/andrew/ladybird-org/swift-test-apps/bitfield-member/./Test.h:10:8)
4.      While verifying FuncDecl setter for m_marked (at /home/andrew/ladybird-org/swift-test-apps/bitfield-member/./Test.h:10:8)
 #0 0x00005e42246d8498 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x8b29498)
 #1 0x00005e42246d5fbe llvm::sys::RunSignalHandlers() (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x8b26fbe)
 #2 0x00005e42246d8b31 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x0000742adf845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x0000742adf89eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x0000742adf89eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x0000742adf89eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x0000742adf84527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x0000742adf8288ff abort ./stdlib/abort.c:81:7
 #9 0x00005e421e70d1e3 (anonymous namespace)::Verifier::verifyChecked(swift::FuncDecl*) ASTVerifier.cpp:0:0
#10 0x00005e421e6f7388 (anonymous namespace)::Verifier::walkToDeclPost(swift::Decl*) ASTVerifier.cpp:0:0
#11 0x00005e421e70e223 (anonymous namespace)::Traversal::doIt(swift::Decl*) ASTWalker.cpp:0:0
#12 0x00005e421e712598 (anonymous namespace)::Traversal::visit(swift::Decl*) ASTWalker.cpp:0:0
#13 0x00005e421e70e213 (anonymous namespace)::Traversal::doIt(swift::Decl*) ASTWalker.cpp:0:0
#14 0x00005e421e70e113 swift::Decl::walk(swift::ASTWalker&) (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x2b5f113)
#15 0x00005e421e6f4820 swift::verify(swift::Decl*) (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x2b45820)
#16 0x00005e421e41ed19 swift::ClangImporter::verifyAllModules() (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x286fd19)
#17 0x00005e421e62226a swift::ASTContext::verifyAllLoadedModules() const (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0x2a7326a)
#18 0x00005e421cad9491 performEndOfPipelineActions(swift::CompilerInstance&) FrontendTool.cpp:0:0
#19 0x00005e421cad58de performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) FrontendTool.cpp:0:0
#20 0x00005e421cad49b5 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0xf259b5)
#21 0x00005e421c87012b swift::mainEntry(int, char const**) (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0xcc112b)
#22 0x0000742adf82a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#23 0x0000742adf82a28b call_init ./csu/../csu/libc-start.c:128:20
#24 0x0000742adf82a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#25 0x00005e421c86f125 _start (/home/andrew/.local/share/swiftly/toolchains/main-snapshot-2025-03-14/usr/bin/swift-frontend+0xcc0125)
Aborted (core dumped)

Expected behavior

Compiles with no issues

Environment

Swift version 6.2-dev (LLVM 162ee50b401fff2, Swift 57288d1)
Target: x86_64-unknown-linux-gnu
Build config: +assertions

Ubuntu 24.04

Additional information

No response

@ADKaster ADKaster added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels labels Mar 20, 2025
@ADKaster
Copy link
Contributor Author

Note that this blocks marking GC::Cell and GC::Cell::Visitor as SWIFT_UNSAFE_REFERENCE in Ladybird. If there's a better way to model a GC-allocated type in swift I'm all ears though. I'd really rather swift see these types (and their derived types) as "look but don't touch". cc @Xazax-hun

@Xazax-hun
Copy link
Contributor

I was able to reproduce this issue, thanks for the concise example! Could you make m_marked a regular bool instead of a bit field to temporarily work around this issue while I am looking into a solution?

@Xazax-hun Xazax-hun self-assigned this Mar 21, 2025
@Xazax-hun Xazax-hun added c++ interop Feature: Interoperability with C++ c++ to swift Feature → c++ interop: c++ to swift labels Mar 21, 2025
Xazax-hun pushed a commit that referenced this issue Mar 21, 2025
In Swift, only value types can have mutating instance member functions
or computed properties. The importer logic was violating this invariant
when generating setters for bit fields of shared references.

Fixes #80182
@Xazax-hun
Copy link
Contributor

I have a fix, fortunately it was not too bad: #80197

Do you need this to be back ported to a stable release? No promises, but can look into it if you need it sooner than 6.2.

@ADKaster
Copy link
Contributor Author

ADKaster commented Mar 21, 2025

Thanks for the quick fix! I don't think I'm super worried about back ports for a while 😅. As long as it builds on main that will be good enough for our Linux uses. Though if 6.2 is current main that sounds like it wouldn't make it until the next Xcode release?

I can look at using regular bools for this class when building "for swift". Though the fact that we have 3 bit fields, two bools and one enum class: bool suggests that we really want the compact data format.

@Xazax-hun
Copy link
Contributor

Xazax-hun commented Mar 21, 2025

Sounds great!

Though if 6.2 is current main that sounds like it wouldn't make it until the next Xcode release?

Unfortunately, I cannot share anything about the release schedule.

Xazax-hun pushed a commit that referenced this issue Mar 21, 2025
In Swift, only value types can have mutating instance member functions
or computed properties. The importer logic was violating this invariant
when generating setters for bit fields of shared references.

Fixes #80182
Xazax-hun pushed a commit that referenced this issue Mar 21, 2025
In Swift, only value types can have mutating instance member functions
or computed properties. The importer logic was violating this invariant
when generating setters for bit fields of shared references.

Fixes #80182
@ADKaster
Copy link
Contributor Author

Gotcha. In that case, it would be great to see this in 6.1-dev or similar.

Though I am coming across another issue that makes it so I cannot import GC into my LibWeb module, which is proving interesting to reduce.

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. c++ interop Feature: Interoperability with C++ c++ to swift Feature → c++ interop: c++ to swift crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
@Xazax-hun @ADKaster and others