-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[cxx-interop] Fix metadata mismatch regarding fields of structs #81035
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
base: main
Are you sure you want to change the base?
Conversation
@swift-ci please smoke test |
f36ff56
to
a39010b
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.
This is great, thanks for tracking this down! I am not super confident about some details, asked some questions inline. Maybe we should get someone more familiar with type metadata reviewed this PR.
@@ -1845,7 +1845,7 @@ namespace { | |||
|
|||
void addLayoutInfo() { | |||
// uint32_t NumFields; | |||
B.addInt32(getNumFields(getType())); |
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 wonder if we need to do something similar for ClassContextDescriptorBuilder
too.
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 am less sure about emitInitializeFieldOffsetVector
and co. Maybe those are good as is but maybe we want to ask someone familiar with type metadata.
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 wonder if we need to do something similar for ClassContextDescriptorBuilder too.
Yes I think you're right. I intend to check if we need a similar fix for classes and add those changes in a future PR
Regarding emitInitializeFieldOffsetVector
, I'm also not sure. I'll investigate this further
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.
emitInitializeFieldOffsetVector
should include all fields. We are using that information to handle values in value witness functions.
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.
@drexin would it be a problem to have a discrepancy between the fields in emitInitializeFieldOffsetVector
and the fields in StructContextDescriptorBuilder
/FieldTypeMetadataBuilder
?
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.
Hm, I am not sure. cc: @mikeash
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.
Reflection relies on the indexes in the field offset vector and the indexes of the descriptor's fields lining up. In theory you could get away with having additional entries at the end of the field offset vector, but not in the middle, and not more field records than field offsets.
@@ -64,7 +65,8 @@ template <class Impl> class StructMetadataVisitor | |||
// Struct field offsets. | |||
asImpl().noteStartOfFieldOffsets(); | |||
for (VarDecl *prop : Target->getStoredProperties()) | |||
asImpl().addFieldOffset(prop); | |||
if (!isPrivateField(prop)) |
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 wonder if we can get out of sync with emitInitializeFieldOffsetVector
here.
a39010b
to
a49738e
Compare
@swift-ci please smoke test |
a49738e
to
abd2549
Compare
@swift-ci please smoke test |
// CHECK-linux-gnu: 42 | ||
// CHECK-linux-gnu: shared_ptr<CInt>() | ||
printStdSharedPtrOfString() | ||
// CHECK-macosx: basic_string<CChar, std.__1.char_traits<CChar>, std.__1.allocator<CChar>>() |
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.
Alternatively, you could add regexes that match on all platforms. I don't have a preference.
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.
Thanks for the suggestion!
Hopefully we will soon fix the conformance of std::string
to CustomStringConvertible
. Then we can remove all these os options, since the value of the string will be printed instead of the type name.
That said, I don't mind switching to regex
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.
Good point, the string one is temporary (maybe not the shared_ptr one though). Let's leave it as is.
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.
Oh right!
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 think using regexes would be a bit more reliable here, since that would ensure the correct behavior on platforms that aren't listed here, e.g. Android or FreeBSD. The regex could be really permissive: something like {{.*}}.basic_string<CChar, {{.*}}>
should do the trick.
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.
Sure, I'll make this change.
abd2549
to
2a99a7d
Compare
@swift-ci please smoke test |
// CHECK-linux-gnu: 42 | ||
// CHECK-linux-gnu: shared_ptr<CInt>() | ||
printStdSharedPtrOfString() | ||
// CHECK-macosx: basic_string<CChar, std.__1.char_traits<CChar>, std.__1.allocator<CChar>>() |
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.
Good point, the string one is temporary (maybe not the shared_ptr one though). Let's leave it as is.
2a99a7d
to
bdacdd0
Compare
@swift-ci please smoke test |
@swift-ci Please test macOS platform |
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.
This looks great, thanks!
I only have a couple of comments on testing.
@@ -0,0 +1,24 @@ | |||
#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_STD_TYPES_H |
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.
Can we reuse an existing test header in this directory, e.g. std-string-and-vector.h
or std-vector.h
and std-unique-ptr.h
, instead of adding a new one?
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.
Sure!
// CHECK-linux-gnu: 42 | ||
// CHECK-linux-gnu: shared_ptr<CInt>() | ||
printStdSharedPtrOfString() | ||
// CHECK-macosx: basic_string<CChar, std.__1.char_traits<CChar>, std.__1.allocator<CChar>>() |
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 think using regexes would be a bit more reliable here, since that would ensure the correct behavior on platforms that aren't listed here, e.g. Android or FreeBSD. The regex could be really permissive: something like {{.*}}.basic_string<CChar, {{.*}}>
should do the trick.
bdacdd0
to
3efa921
Compare
@swift-ci please smoke test |
In #78467 and #78961, we stopped emitting metadata for private C++ fields. However, this created a mismatch between the fields emitted and the number of fields + their offsets in the StructDescriptor.
rdar://147263490