From a6e301dd4153ad7bfef61da0304fa57ad92032ab Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 6 Mar 2015 23:45:20 +0000 Subject: [PATCH] MS ABI: Correctly generate throw-info for pointer to const qual types We didn't create type info based on the unqualified pointee type, causing RTTI mismatches. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231533 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MicrosoftCXXABI.cpp | 16 ++++++++++++++-- lib/Sema/SemaExprCXX.cpp | 5 ++--- test/CodeGenCXX/microsoft-abi-throw.cpp | 8 +++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 4e3d50b408..9cb7d22e92 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -3367,7 +3367,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) { // - a standard pointer conversion (4.10) not involving conversions to // pointers to private or protected or ambiguous classes // - // All pointers are convertible to void so ensure that it is in the + // All pointers are convertible to pointer-to-void so ensure that it is in the // CatchableTypeArray. if (IsPointer) CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy)); @@ -3398,6 +3398,8 @@ llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) { } llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { + T = getContext().getExceptionObjectType(T); + // C++14 [except.handle]p3: // A handler is a match for an exception object of type E if [...] // - the handler is of type cv T or const T& where T is a pointer type and @@ -3409,7 +3411,17 @@ llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) { IsConst = PointeeType.isConstQualified(); IsVolatile = PointeeType.isVolatileQualified(); } - T = getContext().getExceptionObjectType(T); + + // Member pointer types like "const int A::*" are represented by having RTTI + // for "int A::*" and separately storing the const qualifier. + if (const auto *MPTy = T->getAs()) + T = getContext().getMemberPointerType(PointeeType.getUnqualifiedType(), + MPTy->getClass()); + + // Pointer types like "const int * const *" are represented by having RTTI + // for "const int **" and separately storing the const qualifier. + if (T->isPointerType()) + T = getContext().getPointerType(PointeeType.getUnqualifiedType()); // The CatchableTypeArray enumerates the various (CV-unqualified) types that // the exception object may be caught as. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 0cedf349b9..b69ddf7aeb 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -787,10 +787,9 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, getUnambiguousPublicSubobjects(RD, UnambiguousPublicSubobjects); for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) { if (CXXConstructorDecl *CD = LookupCopyingConstructor(Subobject, 0)) { - if (CD->isTrivial()) - continue; MarkFunctionReferenced(E->getExprLoc(), CD); - Context.addCopyConstructorForExceptionObject(Subobject, CD); + if (!CD->isTrivial()) + Context.addCopyConstructorForExceptionObject(Subobject, CD); } } } diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp index f0151c5d39..ec63d01da7 100644 --- a/test/CodeGenCXX/microsoft-abi-throw.cpp +++ b/test/CodeGenCXX/microsoft-abi-throw.cpp @@ -26,6 +26,12 @@ void f(const Y &y) { // CHECK-LABEL: @"\01?f@@YAXABUY@@@Z" // CHECK: call x86_thiscallcc %struct.Y* @"\01??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y* // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8* - // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@") #4 + // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@") + throw y; +} + +void g(const int *const *y) { + // CHECK-LABEL: @"\01?g@@YAXPBQBH@Z" + // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIC2PAPBH) throw y; } -- 2.50.1