From: Richard Smith Date: Thu, 20 Nov 2014 01:35:11 +0000 (+0000) Subject: When mangling member-expressions, skip implicit accesses of anonymous union X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e056d2629ca57f4e4e761e114d2daa593b9fdd41;p=clang When mangling member-expressions, skip implicit accesses of anonymous union objects. This is consistent with GCC's behavior. Patch by Tomasz Miąsko! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222402 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index e6409ce4d8..9e9c1718d1 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -2532,6 +2532,18 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base, // ::= dt // ::= pt if (base) { + + // Ignore member expressions involving anonymous unions. + while (const auto *RT = base->getType()->getAs()) { + if (!RT->getDecl()->isAnonymousStructOrUnion()) + break; + const auto *ME = dyn_cast(base); + if (!ME) + break; + base = ME->getBase(); + isArrow = ME->isArrow(); + } + if (base->isImplicitCXXThis()) { // Note: GCC mangles member expressions to the implicit 'this' as // *this., whereas we represent them as this->. The Itanium C++ ABI diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index 089203e144..ee7f24466b 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -217,3 +217,79 @@ namespace test5 { template void a(decltype(noexcept(int()))); // CHECK: void @_ZN5test51aIiEEvDTnxcvT__EE( } + +namespace test6 { + struct X { + int i; + }; + + struct Y { + union { + int i; + }; + }; + + struct Z { + union { + X ua; + Y ub; + }; + + struct { + X s; + }; + + union { + union { + struct { + struct { + X uuss; + }; + }; + }; + }; + }; + + Z z, *zp; + + template + void f1(decltype(T(z.ua.i))) {} + template void f1(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f1IiEEvDTcvT_dtdtL_ZNS_1zEE2ua1iE + + template + void f2(decltype(T(z.ub.i))) {} + template void f2(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f2IiEEvDTcvT_dtdtL_ZNS_1zEE2ub1iE + + template + void f3(decltype(T(z.s.i))) {} + template void f3(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f3IiEEvDTcvT_dtdtL_ZNS_1zEE1s1iE + + template + void f4(decltype(T(z.uuss.i))) {} + template void f4(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f4IiEEvDTcvT_dtdtL_ZNS_1zEE4uuss1iE + + template + void f5(decltype(T(zp->ua.i))) {} + template void f5(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f5IiEEvDTcvT_dtptL_ZNS_2zpEE2ua1iE + + template + void f6(decltype(T(zp->ub.i))) {} + template void f6(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f6IiEEvDTcvT_dtptL_ZNS_2zpEE2ub1iE + + template + void f7(decltype(T(zp->s.i))) {} + template void f7(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f7IiEEvDTcvT_dtptL_ZNS_2zpEE1s1iE + + template + void f8(decltype(T(zp->uuss.i))) {} + template void f8(int); + // CHECK-LABEL: define weak_odr void @_ZN5test62f8IiEEvDTcvT_dtptL_ZNS_2zpEE4uuss1iE +} +