From beb066fd5df283ee0848e3aceca6d0eae2739cb5 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 12 Jul 2016 04:42:50 +0000 Subject: [PATCH] [MS ABI] Support throwing/catching __unaligned types We need to mark the appropriate bits in ThrowInfo and HandlerType so that the personality routine can correctly handle qualification conversions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@275154 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Mangle.h | 3 ++- lib/AST/MicrosoftMangle.cpp | 9 ++++++--- lib/CodeGen/MicrosoftCXXABI.cpp | 22 +++++++++++++++------- test/CodeGenCXX/microsoft-abi-throw.cpp | 8 ++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index d489746b40..6e3ef9da0c 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -208,7 +208,8 @@ public: raw_ostream &Out) = 0; virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, - uint32_t NumEntries, raw_ostream &Out) = 0; + bool IsUnaligned, uint32_t NumEntries, + raw_ostream &Out) = 0; virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out) = 0; diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 04d8d77710..351997e02a 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -153,7 +153,8 @@ public: const CXXRecordDecl *DstRD, raw_ostream &Out) override; void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, - uint32_t NumEntries, raw_ostream &Out) override; + bool IsUnaligned, uint32_t NumEntries, + raw_ostream &Out) override; void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out) override; void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, @@ -2654,9 +2655,9 @@ void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap( Mangler.mangleName(DstRD); } -void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, - bool IsConst, +void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, + bool IsUnaligned, uint32_t NumEntries, raw_ostream &Out) { msvc_hashing_ostream MHO(Out); @@ -2666,6 +2667,8 @@ void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, Mangler.getStream() << 'C'; if (IsVolatile) Mangler.getStream() << 'V'; + if (IsUnaligned) + Mangler.getStream() << 'U'; Mangler.getStream() << NumEntries; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); } diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 93a6f000e3..41cd53c221 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -3639,7 +3639,8 @@ MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) { } static QualType decomposeTypeForEH(ASTContext &Context, QualType T, - bool &IsConst, bool &IsVolatile) { + bool &IsConst, bool &IsVolatile, + bool &IsUnaligned) { T = Context.getExceptionObjectType(T); // C++14 [except.handle]p3: @@ -3649,10 +3650,12 @@ static QualType decomposeTypeForEH(ASTContext &Context, QualType T, // - a qualification conversion IsConst = false; IsVolatile = false; + IsUnaligned = false; QualType PointeeType = T->getPointeeType(); if (!PointeeType.isNull()) { IsConst = PointeeType.isConstQualified(); IsVolatile = PointeeType.isVolatileQualified(); + IsUnaligned = PointeeType.getQualifiers().hasUnaligned(); } // Member pointer types like "const int A::*" are represented by having RTTI @@ -3675,8 +3678,9 @@ MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type, // TypeDescriptors for exceptions never have qualified pointer types, // qualifiers are stored seperately in order to support qualification // conversions. - bool IsConst, IsVolatile; - Type = decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile); + bool IsConst, IsVolatile, IsUnaligned; + Type = + decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile, IsUnaligned); bool IsReference = CatchHandlerType->isReferenceType(); @@ -3685,6 +3689,8 @@ MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type, Flags |= 1; if (IsVolatile) Flags |= 2; + if (IsUnaligned) + Flags |= 4; if (IsReference) Flags |= 8; @@ -4095,8 +4101,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) { } llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { - bool IsConst, IsVolatile; - T = decomposeTypeForEH(getContext(), T, IsConst, IsVolatile); + bool IsConst, IsVolatile, IsUnaligned; + T = decomposeTypeForEH(getContext(), T, IsConst, IsVolatile, IsUnaligned); // The CatchableTypeArray enumerates the various (CV-unqualified) types that // the exception object may be caught as. @@ -4112,8 +4118,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { SmallString<256> MangledName; { llvm::raw_svector_ostream Out(MangledName); - getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, NumEntries, - Out); + getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned, + NumEntries, Out); } // Reuse a previously generated ThrowInfo if we have generated an appropriate @@ -4129,6 +4135,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { Flags |= 1; if (IsVolatile) Flags |= 2; + if (IsUnaligned) + Flags |= 4; // The cleanup-function (a destructor) must be called when the exception // object's lifetime ends. diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp index f013c8aeb1..7c2e2a8f90 100644 --- a/test/CodeGenCXX/microsoft-abi-throw.cpp +++ b/test/CodeGenCXX/microsoft-abi-throw.cpp @@ -20,6 +20,8 @@ // CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat // CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat // CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat +// CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat +// CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat struct N { ~N(); }; @@ -44,6 +46,12 @@ void g(const int *const *y) { throw y; } +void h(__unaligned int * __unaligned *y) { + // CHECK-LABEL: @"\01?h@@YAXPFAPFAH@Z" + // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIU2PAPFAH) + throw y; +} + struct Default { Default(Default &, int = 42); }; -- 2.40.0