-
Notifications
You must be signed in to change notification settings - Fork 342
Reland "[modules] Fix miscompilation when using two RecordDecl definitions with the same name." #3829
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
Reland "[modules] Fix miscompilation when using two RecordDecl definitions with the same name." #3829
Conversation
@swift-ci test |
The plan is to re-land this change on "next" but keep it out of release-specific branches for now. When we fix known projects relying on using definitions from multiple modules, this change is ready for release. If you see problems with the change or with the plan, I appreciate your feedback. |
I'll take a look shortly. From a quick glance, it looks like the same patch. The example below is why the patch was reverted last time:
|
How does CodeGen for |
Right, Swift will turn the type into a Swift type and generate it like it would any other Swift struct. We really just need to know whether the module has a definition and what that definition is. |
That's good to know. I'm thinking if ClangImporter should import each module independently. Because when it is one big AST on clang side, it is tricky to maintain duplicate definitions and types. We are planning to perform in clang more decl and type merging because without them we are hitting redefinition errors and ambiguous lookup errors. And I'm afraid that merging isn't particularly useful for Swift but can cause more problems. So it is important to have some mechanism for Swift that deals with modules independently. And we'll need to check with LLDB folks to make sure any solution we come up with is compatible with expression evaluation. |
Inviting more people as my proposal gets more ambitious and I want folks to catch unintended consequences. So, the problem is that we'd like Swift to import Clang modules more independently. Multiple definitions with the same name in different clang modules isn't a problem for swift because those definitions are kept separate and we are relying on swift name lookup to resolve any ambiguities. Ambiguities on clang side aren't a problem because swift doesn't use clang name lookup at this point. Now we are facing the question of how to achieve the separation between imported clang modules. My idea was for An alternative is to have some flag that prevents clang from merging entities with the same name. So far I've discarded this approach because we still need to detect duplicates in Objective-C code and I don't know how the flag can tell us which duplicates are OK to ignore and which deserve diagnostic. And this approach seems to be fragile and error-prone as we need to maintain real AST and implicit AST-for-Swift. Also I'm not sure we'll be able to use this mechanism with C++ modules. And the question to Adrian (or anybody from LLDB team that Adrian believes can help) - does LLDB use clang's CodeGen for evaluating Swift code? Or does it take imported Swift types and evaluates that relying on Swift's SILGen + subsequent machine code generation? |
The plan now is not to import clang modules separately but to detect and accept definitions that were demoted to declarations. Swift-side change is swiftlang/swift#41144 |
933d047
to
9fa3a0e
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
…tions with the same name." This reverts commit a0423cc and re-applies commit 9454716. After adding `isThisDeclarationADemotedDefinition` API now swift can query if a declaration was a definition but was demoted. This way it can keep accepting `RecordDecl` that were merged across different modules. rdar://86548228
9fa3a0e
to
0aa51e8
Compare
@swift-ci 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've rebased the PR on top of "stable/20211026" instead of "next" as PR testing for "next" is broken.
Also Evan has asked if this revert-of-revert is the same as the original commit and I've added an inline comment for a single line that I've changed in this re-landing.
} | ||
if (OldDef) { | ||
Reader.MergedDeclContexts.insert(std::make_pair(RD, OldDef)); | ||
RD->demoteThisDefinitionToDeclaration(); |
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.
Compared to the original patch I've changed this line from RD->setCompleteDefinition(false);
to RD->demoteThisDefinitionToDeclaration();
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 this looks fine.
I've put up swiftlang/swift-corelibs-foundation#3149 to check that foundation still builds correctly since that was where I detected the issue in the first place.
LGTM once that passes.
Alright, swiftlang/swift-corelibs-foundation#3149 passed. LGTM. |
Thanks for the review! I'll keep an eye on any potential problems in case we need to revert it again. |
This reverts commit a0423cc and
re-applies commit 9454716.
After adding
isThisDeclarationADemotedDefinition
API now swift canquery if a declaration was a definition but was demoted. This way it can
keep accepting
RecordDecl
that were merged across different modules.rdar://86548228