r295010 - [MS ABI] Correctly mangling vbase destructors

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 13 16:54:11 PST 2017


Author: majnemer
Date: Mon Feb 13 18:54:11 2017
New Revision: 295010

URL: http://llvm.org/viewvc/llvm-project?rev=295010&view=rev
Log:
[MS ABI] Correctly mangling vbase destructors

They are a little bit of a special case in the mangling. They are always
mangled without taking into account their virtual-ness of the
destructor. They are also mangled to return void, unlike the actual
destructor.

This fixes PR31931.

Differential Revision: https://reviews.llvm.org/D29912

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
    cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp
    cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
    cfe/trunk/test/CodeGenCXX/regcall.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Mon Feb 13 18:54:11 2017
@@ -1890,14 +1890,18 @@ void MicrosoftCXXNameMangler::mangleFunc
   // <return-type> ::= <type>
   //               ::= @ # structors (they have no declared return type)
   if (IsStructor) {
-    if (isa<CXXDestructorDecl>(D) && isStructorDecl(D) &&
-        StructorType == Dtor_Deleting) {
-      // The scalar deleting destructor takes an extra int argument.
-      // However, the FunctionType generated has 0 arguments.
-      // FIXME: This is a temporary hack.
-      // Maybe should fix the FunctionType creation instead?
-      Out << (PointersAre64Bit ? "PEAXI at Z" : "PAXI at Z");
-      return;
+    if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
+      // The scalar deleting destructor takes an extra int argument which is not
+      // reflected in the AST.
+      if (StructorType == Dtor_Deleting) {
+        Out << (PointersAre64Bit ? "PEAXI at Z" : "PAXI at Z");
+        return;
+      }
+      // The vbase destructor returns void which is not reflected in the AST.
+      if (StructorType == Dtor_Complete) {
+        Out << "XXZ";
+        return;
+      }
     }
     if (IsCtorClosure) {
       // Default constructor closure and copy constructor closure both return
@@ -2005,13 +2009,20 @@ void MicrosoftCXXNameMangler::mangleFunc
   // <global-function> ::= Y # global near
   //                   ::= Z # global far
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+    bool IsVirtual = MD->isVirtual();
+    // When mangling vbase destructor variants, ignore whether or not the
+    // underlying destructor was defined to be virtual.
+    if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
+        StructorType == Dtor_Complete) {
+      IsVirtual = false;
+    }
     switch (MD->getAccess()) {
       case AS_none:
         llvm_unreachable("Unsupported access specifier");
       case AS_private:
         if (MD->isStatic())
           Out << 'C';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'E';
         else
           Out << 'A';
@@ -2019,7 +2030,7 @@ void MicrosoftCXXNameMangler::mangleFunc
       case AS_protected:
         if (MD->isStatic())
           Out << 'K';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'M';
         else
           Out << 'I';
@@ -2027,7 +2038,7 @@ void MicrosoftCXXNameMangler::mangleFunc
       case AS_public:
         if (MD->isStatic())
           Out << 'S';
-        else if (MD->isVirtual())
+        else if (IsVirtual)
           Out << 'U';
         else
           Out << 'Q';

Modified: cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp Mon Feb 13 18:54:11 2017
@@ -5,10 +5,10 @@ struct __declspec(dllexport) T { virtual
 struct __declspec(dllexport) U : S, T { virtual ~U(); };
 
 // CHECK-LABEL: define {{.*}} @"\01??_GS@@UAEPAXI at Z"
-// CHECK: call x86_thiscallcc void @"\01??_DS@@UAE at XZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}}
+// CHECK: call x86_thiscallcc void @"\01??_DS@@QAEXXZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}}
 
 // CHECK-LABEL: define {{.*}} @"\01??_GT@@UAEPAXI at Z"
-// CHECK: call x86_thiscallcc void @"\01??_DT@@UAE at XZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}}
+// CHECK: call x86_thiscallcc void @"\01??_DT@@QAEXXZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}}
 
 // CHECK-LABEL: define {{.*}} @"\01??_GU@@UAEPAXI at Z"
-// CHECK: call x86_thiscallcc void @"\01??_DU@@UAE at XZ"(%struct.U* %this1){{.*}}!dbg !{{[0-9]+}}
+// CHECK: call x86_thiscallcc void @"\01??_DU@@QAEXXZ"(%struct.U* %this1){{.*}}!dbg !{{[0-9]+}}

Modified: cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp Mon Feb 13 18:54:11 2017
@@ -55,12 +55,12 @@ void test_cleanup() {
 // CHECK:           to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]]
 
 // CHECK: [[LEAVE_FUNC]]
-// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAE at XZ"(
+// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"(
 // CHECK:   ret void
 
 // CHECK: [[CLEANUP]]
 // CHECK:   %[[CLEANUPPAD:.*]] = cleanuppad within none []
-// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAE at XZ"(
+// CHECK:   call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"(
 // CHECK:   cleanupret from %[[CLEANUPPAD]] unwind to caller
 
 

Modified: cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp Mon Feb 13 18:54:11 2017
@@ -137,7 +137,7 @@ namespace inalloca_nonvirt {
   // WIN32: call {{.*}} @"\01??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
   // WIN32: call void @llvm.stackrestore(
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -150,7 +150,7 @@ namespace inalloca_nonvirt {
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
   // WIN64: call {{.*}} @"\01??0A at inalloca_nonvirt@@QEAA at UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 
   struct C : B { using B::B; };
   C c(1, 2, 3, 4);
@@ -173,7 +173,7 @@ namespace inalloca_nonvirt {
   // WIN32: call {{.*}} @"\01??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]])
   // WIN32: call void @llvm.stackrestore(
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -186,7 +186,7 @@ namespace inalloca_nonvirt {
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
   // WIN64: call {{.*}} @"\01??0A at inalloca_nonvirt@@QEAA at UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 }
 
 namespace inalloca_virt {
@@ -224,7 +224,7 @@ namespace inalloca_virt {
   // destroy the parameters, but that's not actually possible.
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -239,7 +239,7 @@ namespace inalloca_virt {
   // WIN64: br
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 
   struct C : B { using B::B; };
   C c(1, 2, 3, 4);
@@ -281,7 +281,7 @@ namespace inalloca_virt {
   //
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
   // WIN32: call {{.*}} @"\01??0Z@@QAE at XZ"(
-  // WIN32: call {{.*}} @"\01??_DQ@@QAE at XZ"(
+  // WIN32: call {{.*}} @"\01??_DQ@@QAEXXZ"(
 
   // On Win64, the Q arguments would be destroyed in the callee. We don't yet
   // support that in the non-inlined case, so we force inlining.
@@ -301,7 +301,7 @@ namespace inalloca_virt {
   // WIN64: br
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
   // WIN64: call {{.*}} @"\01??0Z@@QEAA at XZ"(
-  // WIN64: call void @"\01??_DQ@@QEAA at XZ"({{.*}}* %[[TMP]])
+  // WIN64: call void @"\01??_DQ@@QEAAXXZ"({{.*}}* %[[TMP]])
 }
 
 namespace inline_nonvirt {

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp Mon Feb 13 18:54:11 2017
@@ -138,6 +138,6 @@ S3 *f(S2 &s) {
 // CHECK:    [[CALL:%.*]] = invoke i8* @__RTDynamicCast
 
 // CHECK:    [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
-// CHECK:    call x86_thiscallcc void @"\01??_DCleanup at PR25606@@QAE at XZ"(
+// CHECK:    call x86_thiscallcc void @"\01??_DCleanup at PR25606@@QAEXXZ"(
 // CHECK:    ret %"struct.PR25606::S3"* [[BC]]
 }

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Mon Feb 13 18:54:11 2017
@@ -207,7 +207,7 @@ F::~F() {
 void foo() {
   F f;
 }
-// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF at test2@@UAE at XZ"({{.*}} {{.*}} comdat
+// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF at test2@@QAEXXZ"({{.*}} {{.*}} comdat
 //      Do an adjustment from C* to F*.
 // DTORS3:   getelementptr i8, i8* %{{.*}}, i32 20
 // DTORS3:   bitcast i8* %{{.*}} to %"struct.test2::F"*
@@ -361,12 +361,12 @@ struct D : B, C { ~D(); };
 void call_vbase_complete(D *d) {
   d->~D();
 // CHECK: define void @"\01?call_vbase_complete at dtors@@YAXPAUD at 1@@Z"
-// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAE at XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: ret
 }
 
 // The complete dtor should call the base dtors for D and the vbase A (once).
-// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD at dtors@@QAE at XZ"({{.*}}) {{.*}} comdat
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD at dtors@@QAEXXZ"({{.*}}) {{.*}} comdat
 // CHECK-NOT: call
 // CHECK: call x86_thiscallcc void @"\01??1D at dtors@@QAE at XZ"
 // CHECK-NOT: call
@@ -377,7 +377,7 @@ void call_vbase_complete(D *d) {
 void destroy_d_complete() {
   D d;
 // CHECK: define void @"\01?destroy_d_complete at dtors@@YAXXZ"
-// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAE at XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: ret
 }
 
@@ -387,7 +387,7 @@ void destroy_d_complete() {
 void call_nv_deleting_dtor(D *d) {
   delete d;
 // CHECK: define void @"\01?call_nv_deleting_dtor at dtors@@YAXPAUD at 1@@Z"
-// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAE at XZ"(%"struct.dtors::D"* %{{[^,]+}})
+// CHECK: call x86_thiscallcc void @"\01??_DD at dtors@@QAEXXZ"(%"struct.dtors::D"* %{{[^,]+}})
 // CHECK: call void @"\01??3 at YAXPAX@Z"
 // CHECK: ret
 }

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp Mon Feb 13 18:54:11 2017
@@ -12,7 +12,7 @@
 // CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat
 // CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat
 // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE at ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE at ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
-// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE at XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
+// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH at TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"\01??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"\01??$?_OH at TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Mon Feb 13 18:54:11 2017
@@ -84,7 +84,7 @@ B::~B() {
 
   // CHECK: ret
 
-  // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE at XZ"(%struct.B*
+  // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B*
   // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}}
   // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
   // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8
@@ -102,7 +102,7 @@ B::~B() {
   // CHECK2:   %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B*
   // CHECK2:   store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4
   // CHECK2:   %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]]
-  // CHECK2:   call x86_thiscallcc void @"\01??_DB@@UAE at XZ"(%struct.B* %[[THIS]])
+  // CHECK2:   call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]])
   // ...
   // CHECK2: ret
 }
@@ -208,7 +208,7 @@ void call_complete_dtor() {
   B b;
   // CHECK: call x86_thiscallcc %struct.B* @"\01??0B@@QAE at XZ"(%struct.B* %[[B:.*]], i32 1)
   // CHECK-NOT: getelementptr
-  // CHECK: call x86_thiscallcc void @"\01??_DB@@UAE at XZ"(%struct.B* %[[B]])
+  // CHECK: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[B]])
   // CHECK: ret
 }
 

Modified: cfe/trunk/test/CodeGenCXX/regcall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/regcall.cpp?rev=295010&r1=295009&r2=295010&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/regcall.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/regcall.cpp Mon Feb 13 18:54:11 2017
@@ -47,8 +47,8 @@ public:
   // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev
   // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev
   // Windows ignores calling convention on constructor/destructors.
-  // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAA at XZ"
-  // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAE at XZ"
+  // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAAXXZ"
+  // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAEXXZ"
   
   test_class& __regcall operator+=(const test_class&){
     return *this;




More information about the cfe-commits mailing list