[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.

llvm-svn: 275154
This commit is contained in:
David Majnemer 2016-07-12 04:42:50 +00:00
parent ec1b80fd11
commit 526793d14c
4 changed files with 31 additions and 11 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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);
};