]> granicus.if.org Git - clang/commitdiff
[MS ABI] Allow memfn pointers with unconvertible types to be formed
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 11 Jun 2015 00:20:57 +0000 (00:20 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 11 Jun 2015 00:20:57 +0000 (00:20 +0000)
Remove the restriction which forbade forming pointers to member
functions which had parameter types or return types which were not
convertible.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239499 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp

index de30883c545f2853528d540f385e1dc894602215..bb95a123c5515aed66bd36d3578f27ceffb1e9cf 100644 (file)
@@ -2423,12 +2423,7 @@ MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD,
     FirstField = CGM.GetAddrOfFunction(MD, Ty);
     FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
   } else {
-    if (!CGM.getTypes().isFuncTypeConvertible(
-            MD->getType()->castAs<FunctionType>())) {
-      CGM.ErrorUnsupported(MD, "pointer to virtual member function with "
-                               "incomplete return or parameter type");
-      FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
-    } else if (FPT->getCallConv() == CC_X86FastCall) {
+    if (FPT->getCallConv() == CC_X86FastCall) {
       CGM.ErrorUnsupported(MD, "pointer to fastcall virtual member function");
       FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
     } else {
index f6f75835c658e6840e240f6eb0e13d7b8dd8ef9a..eb5f90dc86be9d664328f5d3e988993fc8ad9a9c 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
 
 struct S {
   int x, y, z;
@@ -13,12 +13,15 @@ struct U {
   U(const U &);
 };
 
+struct B;
+
 struct C {
   virtual void foo();
   virtual int bar(int, double);
   virtual S baz(int);
   virtual S qux(U);
   virtual void thud(...);
+  virtual void (B::*plugh())();
 };
 
 namespace {
@@ -47,6 +50,8 @@ void f() {
   void (C::*ptr6)(...);
   ptr6 = &C::thud;
 
+  auto ptr7 = &C::plugh;
+
 
 // CHECK32-LABEL: define void @"\01?f@@YAXXZ"()
 // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr
@@ -167,4 +172,18 @@ void f() {
 // CHECK64: ret void
 // CHECK64: }
 
+// CHECK32: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BBE@AE"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %vtable, i64 5
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK32: ret void
+// CHECK32: }
+
+// CHECK64: define linkonce_odr void @"\01??_9C@@$BCI@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %vtable, i64 5
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
+// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
+// CHECK64: ret void
+// CHECK64: }
+
 // CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}