[PATCH] D110280: [modules] Fix IRGen assertion on accessing ObjC ivar inside a method.
Volodymyr Sapsai via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 28 14:46:15 PDT 2021
vsapsai added a comment.
In D110280#3016911 <https://reviews.llvm.org/D110280#3016911>, @rjmccall wrote:
> Hmm. It sounds like we misbehave if we're working with a non-canonical ivar. While it does seem preferable in general for lookups done after merging modules to return the canonical ivar, I'm not sure we can rely on the AST only having references to that ivar, since e.g. there might be references to non-canonical ivars in static/inline functions in the modules that declare them.
I've experimented with RecordDecl and always_inline functions. Just "inline" is inlined in LLVM but not in Clang, and in IR we have a function declaration and its call, so I don't know where to look for potential IRGen problems for MemberExpr. Anyway, with always_inline function we can have MemberExpr with MemberDecl from a "wrong" module. `FieldDecl` parent is from the "right" module because we've merged decl contexts, so `CodeGenTypes::getCGRecordLayout` receives correct RecordDecl. Later, when we want to get offset for `FieldDecl` from "wrong" module, we are saved by `getCanonicalDecl` (in getLLVMFieldNo <https://github.com/llvm/llvm-project/blob/1ecb1bc3e214c8da53a7fda14f428786441109d7/clang/lib/CodeGen/CGRecordLayout.h#L198> and getBitFieldInfo <https://github.com/llvm/llvm-project/blob/1ecb1bc3e214c8da53a7fda14f428786441109d7/clang/lib/CodeGen/CGRecordLayout.h#L217>, for instance) that returns FieldDecl from the "right" module.
I wasn't able to reproduce the exact scenario as in this PR because need to access an ivar from a method and I don't think you can inline that. As for test-functions.m, the test wasn't failing earlier because of a different name lookup code path and I've added it for completeness. I'll add always_inline function accessing ivars to the test, it doesn't hurt.
In D110280#3016911 <https://reviews.llvm.org/D110280#3016911>, @rjmccall wrote:
> So while this seems like a good change in the abstract — although maybe we should just be doing the lookup in the canonical definition in the first place? — it also might not be enough, and the record-layout code might just need to properly handle non-canonical ivars.
Unfortunately, we were doing lookup in the canonical definition but `ASTReader::FindExternalVisibleDeclsByName` found decls from both modules because we've merged decl contexts and lookup tables from both modules were available in `ASTReader.Lookups`. I was considering other options for calling `ObjCIvarDecl::getCanonicalDecl` and based on the stack trace
ASTReader::FindExternalVisibleDeclsByName
DeclContext::lookup
ObjCContainerDecl::getIvarDecl
ObjCInterfaceDecl::lookupInstanceVariable
Sema::LookupIvarInObjCMethod
decided `ObjCContainerDecl::getIvarDecl` would be the best option as this is the earliest opportunity where we have to use a single ObjCIvarDecl instead of multiple options.
As for teaching record-layout code to properly handle non-canonical ivars, I don't know how involved it is going to be. In https://reviews.llvm.org/D106994 Richard also suggested adding support for "compatible types". Cannot really tell the long-term impact of different approaches but based on my limited experience, I still [naively] believe that carefully™ using correct decls is a viable solution.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110280/new/
https://reviews.llvm.org/D110280
More information about the cfe-commits
mailing list