[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 7 01:16:17 PDT 2024
martinboehme wrote:
> Another possibility to consider: when [transforming a member access](https://github.com/llvm/llvm-project/blob/ff210b94d449de8ebe1f32cf0d7763ba63b27b39/clang/lib/Sema/TreeTransform.h#L11950), strip off any implicit member accesses from the base expression before transforming the base. That way, we'll rebuild the implicit member access from scratch, which might be a little more work, but should get details like this one right. (We can then probably also remove the logic to deal with an absent `DeclName` in `RebuildMemberExpr` since that shouldn't happen any more.)
This sounds enticing, but after experimenting with this a bit, I’ve concluded that it’s unfortunately not so simple to get this working (unless there’s something I’m overlooking).
Looking at the relevant part of the AST:
```cxx
`-MemberExpr <col:10, col:14> 'int' xvalue .i 0xbdcb3c0
`-MemberExpr <col:10, col:14> 'S::(anonymous struct at line:2:3)' xvalue .S::(anonymous struct at line:2:3) 0xbdcb488
`-MaterializeTemporaryExpr <col:10, col:12> 'S' xvalue
`-CXXTemporaryObjectExpr <col:10, col:12> 'S' 'void () noexcept' zeroing
```
What I think you’re suggesting is that while processing the base for the outer `MemberExpr` (the one for `.i`), we strip the inner `MemberExpr` (the one for the anonymous field). The idea would be that the `MemberExpr` for the anonymous field should get recreated within `Sema::BuildMemberReferenceExpr()` when it’s called with the field declaration for `i`.
This _would_ work if we handed an `IndirectFieldDecl` to `BuildMemberReferenceExpr()`, but the problem is that we have no easy way of getting to the `IndirectFieldDecl`. The `getMemberDecl()` for the outer `MemberExpr` is a plain `FieldDecl`; the `getFoundDecl()` is, too.
The `getFoundDecl()` for the _inner_ `MemberExpr` does refer to the `IndirectFieldDecl` we want. So we could try to retain only this `MemberExpr` and strip the others – but then we run into the issue that there may not even _be_ an inner `MemberExpr` if the anonymous union is declared inside a function rather than inside a class ([example](https://godbolt.org/z/s1qqj5rY3)).
My feeling is that rather than trying to deal with all of the various cases involved in stripping, then recreating the implicit `MemberExpr`s, we retain them and merely recreate the `MaterializeTemporaryExpr` if needed.
https://github.com/llvm/llvm-project/pull/90842
More information about the cfe-commits
mailing list