-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[cxx-interop] Fix a crash with [[no_unique_address]] #80786
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
Conversation
cf5df84
to
75838d6
Compare
@swift-ci please smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering whether skipping this field is really the right approach, and whether there are other alternatives. Can you say more about why these overlapping fields are problematic for Swift at the moment?
Absolutely, I would love to support this and that would be the right approach long term. We use |
75838d6
to
664efc6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would really prefer to just fix the IRGen bug here instead of declining to import a field just because it has this attribute on it. We should try to get Swift out of the business of making assumptions about C/C++ layout, which we should be able to do in three ways:
- We can completely get out of the business of constructing an LLVM struct type for the C struct by just using Clang's
convertTypeForMemory
API. - We can build the
FieldInfos
by walking the Swift stored properties and just using Clang'sgetLLVMFieldNumber
API to get the field number within the above. - We can construct the spare bit vector by starting with all bits set and then clearing bits as appropriate for individual subobjects. We might need some new methods on
ClusteredBitVector
to support that kind of mutation, but that should be straightforward becauseAPInt
should directly support the operations we'd need.
Absolutely! I think that is the correct thing to do here. Unfortunately, I believe it is a bit more involved so I'd like to land this workaround until we can get to the proper fix.
Actually, we still can import zero sized fields or fields with this attribute that do not have their tail padding reused to other fields. Currently, it looks like it is not that easy to trigger this kind of layout optimization in Clang, so this might not be too restrictive for a short term workaround.
I agree, but I think fixing the LLVM struct type and the spare bit vector might not be sufficient. Specifically, we generate Would you be OK with this workaround temporarily? |
664efc6
to
5291e21
Compare
@swift-ci please smoke test |
Yes, if you can change this to only apply to fields that actually have their tail padding used for something, that seems much less likely to have unwanted impact in the short term.
Hmm. Yes, that's a much nastier problem; we need to make sure we're not generating code that writes beyond |
I attempt to do something like that in this PR, I have |
As it is, you're going to refuse to import in every field of non-POD type with tail padding. Well, hmm, except that it's only when they have the attribute; maybe that makes it okay in practice because people rarely use this attribute. Still, it would certainly be more conservative to only do this when it actually matters for layout. |
Makes sense. I update the PR to check the offset of the next field (if there is one). |
Swift does not support storing fields in the padding of the previous fields just yet, so let's not import fields like that from C++. Represent them as opaque blobs instead. Fixes #80764 rdar://149072458
5291e21
to
939ee49
Compare
@swift-ci please smoke test |
Explanation: Swift does not support storing fields in the padding of the previous fields just yet, so let's not import fields like that from C++. Represent them as opaque blobs instead. Issue: rdar://149072458 Risk: Low, the fix is targeted at a scenario that was crashing before. Testing: Regression test added. Original PR: #80786 Reviewer:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks for fleshing out the test!
…c import In swiftlang#80786, we started importing certain padded fields as opaque blobs. Part of this logic involved querying those fields' ASTRecordLayout. However, dependendent types (which are imported symbolically) do not have an ASTRecordLayout, so calling getASTRecordLayout() would lead to an assertion error for class templates where a no_unique_address field is some kind of dependent C++ record type. This patch avoids the field padding check during symbolic import mode because that check is only relevant for codegen anyway. rdar://150067288
…c import In swiftlang#80786, we started importing certain padded fields as opaque blobs. Part of this logic involved querying those fields' ASTRecordLayout. However, dependent types (which are imported symbolically) do not have an ASTRecordLayout, so calling Clang's getASTRecordLayout() would lead to an assertion error for class templates where a no_unique_address field is some kind of dependent C++ record type. This patch avoids the field padding check during symbolic import mode because that check is only relevant for codegen anyway. rdar://150067288
…c import In swiftlang#80786, we started importing certain padded fields as opaque blobs. Part of this logic involved querying those fields' ASTRecordLayout. However, dependent types (which are imported symbolically) do not have an ASTRecordLayout, so calling Clang's getASTRecordLayout() would lead to an assertion error for class templates where a no_unique_address field is some kind of dependent C++ record type. This patch avoids the field padding check during symbolic import mode because that check is only relevant for codegen anyway. rdar://150067288
…c import In swiftlang#80786, we started importing certain padded fields as opaque blobs. Part of this logic involved querying those fields' ASTRecordLayout. However, dependent types (which are imported symbolically) do not have an ASTRecordLayout, so calling Clang's getASTRecordLayout() would lead to an assertion error for class templates where a no_unique_address field is some kind of dependent C++ record type. This patch avoids the field padding check during symbolic import mode because that check is only relevant for codegen anyway. rdar://150067288 (cherry picked from commit 1fdb239)
Swift does not support storing fields in the padding of the previous fields just yet, so let's not import fields like that from C++. Represent them as opaque blobs instead.
Fixes #80764
rdar://149072458