]> granicus.if.org Git - clang/commitdiff
MS ABI: Correctly generate throw-info for pointer to const qual types
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 6 Mar 2015 23:45:20 +0000 (23:45 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 6 Mar 2015 23:45:20 +0000 (23:45 +0000)
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
lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/microsoft-abi-throw.cpp

index 4e3d50b408ec91904c7528fbf475fa924cc99429..9cb7d22e92fd73e31ca9595a8937e1078a91ccb1 100644 (file)
@@ -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<MemberPointerType>())
+    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.
index 0cedf349b958e2697cea403d3033975e8de5c778..b69ddf7aebec2cd1480b6bc1ddb5d948226eca49 100644 (file)
@@ -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);
       }
     }
   }
index f0151c5d39bf3bb47fb55b6ae0affa74490c1e89..ec63d01da7b0c8cfec58b61ece032acc4f1dbf12 100644 (file)
@@ -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;
 }