Skip to content

Conversation

@Xazax-hun
Copy link
Contributor

@Xazax-hun Xazax-hun commented Dec 18, 2025

When a base class is annotated as shared reference we can occasionally infer that the derived types also need to be shared references. Unfortunately, we did not generate the correct code for some of those scenarios. When the reference counted base is not at the offset zero we need to do offset adjustments before we pass the pointer to the reference counting functions. We did not do those offset calculations.

I looked into implementing the codegen for the offset calculation directly in Swift but it needed significantly more work than I anticipated. We need to invoke the frontend to get the path to the base class and we also need to deal with virtual inheritance, alignment and some other considerations.

This PR ends up generating a Clang shim instead and the derived to base conversion happens in this shim. As a result, we piggy-back on Clang making all the correct offset calculations. This patch also had to change how certain aspects of shared references are implemented to be compatible with this approach:

  • Instead of always looking at the base classes to querry the retain/release operations we now propagate the corresponding annotations once per types. This also has the beneficial effects that we traverse the inheritance hierarchy less often.
  • To generate the correct diagnostics, I reuse the result of the refcount operation query.
  • We do not want these generated functions to be inherited, so added a set to exempt them from cloning.
  • Tweaked the lookup logic for retain/release a bit as these generated clang methods are not found by lookup. We rely on looking up the imported methods instead.

rdar://166227787

@Xazax-hun Xazax-hun added the c++ interop Feature: Interoperability with C++ label Dec 18, 2025
@Xazax-hun Xazax-hun force-pushed the fix-multiple-inheritance-refcounts branch from 59564f4 to b0da742 Compare December 18, 2025 17:00
Copy link
Contributor

@egorzhdan egorzhdan left a comment

Choose a reason for hiding this comment

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

Looks great! Just a couple minor comments.

When a base class is annotated as shared reference we can occasionally
infer that the derived types also need to be shared references.
Unfortunately, we did not generate the correct code for some of those
scenarios. When the reference counted base is not at the offset zero we
need to do offset adjustments before we pass the pointer to the
reference counting functions. We did not do those offset calculations.

I looked into implementing the codegen for the offset calculation
directly in Swift but it needed significantly more work than I
anticipated. We need to invoke the frontend to get the path to the base
class and we also need to deal with virtual inheritance, alignment and
some other considerations.

This PR ends up generating a Clang shim instead and the derived to base
conversion happens in this shim. As a result, we piggy-back on Clang
making all the correct offset calculations. This patch also had to
change how certain aspects of shared references are implemented to be
compatible with this approach:
* Instead of always looking at the base classes to querry the
  retain/release operations we now propagate the corresponding
  annotations once per types. This also has the beneficial effects that
  we traverse the inheritance hierarchy less often.
* To generate the correct diagnostics, I reuse the result of the
  refcount operation query.
* We do not want these generated functions to be inherited, so added a
  set to exempt them from cloning.
* Tweaked the lookup logic for retain/release a bit as these generated
  clang methods are not found by lookup. We rely on looking up the
  imported methods instead.

rdar://166227787
rdar://165635002
@Xazax-hun Xazax-hun force-pushed the fix-multiple-inheritance-refcounts branch from b0da742 to 35bcc99 Compare December 18, 2025 18:15
@Xazax-hun
Copy link
Contributor Author

@swift-ci please smoke test

@Xazax-hun
Copy link
Contributor Author

@swift-ci please smoke test Windows

@Xazax-hun
Copy link
Contributor Author

@swift-ci please smoke test macOS

@j-hui
Copy link
Contributor

j-hui commented Dec 20, 2025

@swift-ci please smoke test Windows

@Xazax-hun Xazax-hun merged commit 0134baf into swiftlang:main Dec 20, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ interop Feature: Interoperability with C++

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants