When mangling member-expressions, mangle only access to first named member,
ignoring unnamed ones in anonymous unions. This fixes crash reported in bug
report 15542, and results in behaviour consistent with GCC.
Details
Diff Detail
Event Timeline
If I reduce to a valid testcase (dropping one layer of the union), then EDG mangles your x.implicit_this(y) callee as:
_ZNK5test61XIiE13implicit_thisINS_1YEEEDTclfp_L_ZNS1_4__C11mEEEET_
whereas GCC and Clang with this patch mangle it as
_ZNK5test61XIiE13implicit_thisINS_1YEEEDTclfp_dtdefpT1mEET_
The difference is the argument to f; EDG uses
L_ZNS1_4__C11mEE
which is <external-name> test6::X<int>::__C1::m, which doesn't seem very good. I think GCC's mangling is the best option here, but please also suggest this on the cxx-abi-dev mailing list.
lib/AST/ItaniumMangle.cpp | ||
---|---|---|
2538 | Please use if (isa<IndirectFieldDecl>(ME->getMemberDecl())) ... to more directly express the intent here. | |
test/CodeGenCXX/mangle-exprs.cpp | ||
225–226 | This is, strictly speaking, ill-formed; you cannot define a type within an anonymous union. Please also add a test case with only one layer of anonymous union so that we test the non-extension case. Please also add a test with an anonymous struct (maybe to this multi-layer case). | |
234–238 | These are both ill-formed. You can't use this-> (or (*this).) in a trailing return type because the class type is not yet complete (but it appears we don't diagnose it in this case). Please use a type other than X in this check. |
I have updated tests to include an anonymous union, an anonymous struct and
combinations of those two. In addition, dependency on non-diagnosed incomplete
type in member-expression has been removed.
End condition is now made more explicit using IndirectFieldDecl, but this
requires additional check ensuring that we are in fact dealing with an
anonymous union / struct (so that we don't break non-anonymous case). Did you
have something simpler in mind here?
Indeed, something like "if (!member) return mangleExpression(base)", would be
really nice, but the problem is that we need a member name from outermost
MemberExpr generated from IndirectFieldDecl, and isArrow from innermost
MemberExpr generated from IndirectFieldDecl.
I updated the code to skip over all bases whose types are anonymous structs or
unions, though I will mention that first version that relied on empty
identifiers would also work.
Please use
... to more directly express the intent here.