From 6adb42e1ac111305fcba657e6c7fe02fcc9f83e2 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 20 Nov 2014 01:35:11 +0000 Subject: [PATCH] =?utf8?q?When=20mangling=20member-expressions,=20skip=20i?= =?utf8?q?mplicit=20accesses=20of=20anonymous=20union=20objects.=20This=20?= =?utf8?q?is=20consistent=20with=20GCC's=20behavior.=20Patch=20by=20Tomasz?= =?utf8?q?=20Mi=C4=85sko!?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit llvm-svn: 222402 --- clang/lib/AST/ItaniumMangle.cpp | 12 ++++++ clang/test/CodeGenCXX/mangle-exprs.cpp | 76 ++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index e6409ce..9e9c171 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/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/clang/test/CodeGenCXX/mangle-exprs.cpp b/clang/test/CodeGenCXX/mangle-exprs.cpp index 089203e..ee7f244 100644 --- a/clang/test/CodeGenCXX/mangle-exprs.cpp +++ b/clang/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 +} + -- 2.7.4