diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-06-11 00:20:57 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-06-11 00:20:57 +0000 |
| commit | 01b9bb42d43a041bbe75c56d3dd70c15e3cdc3a6 (patch) | |
| tree | 2ec522d2663bec308c7ff82d546fddb5762de707 /clang | |
| parent | 6bd006f31a7f18a32e45ea436fb08f64bdf669b1 (diff) | |
| download | bcm5719-llvm-01b9bb42d43a041bbe75c56d3dd70c15e3cdc3a6.tar.gz bcm5719-llvm-01b9bb42d43a041bbe75c56d3dd70c15e3cdc3a6.zip | |
[MS ABI] Allow memfn pointers with unconvertible types to be formed
Remove the restriction which forbade forming pointers to member
functions which had parameter types or return types which were not
convertible.
llvm-svn: 239499
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 7 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp | 23 |
2 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index de30883c545..bb95a123c55 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -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 { diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp index f6f75835c65..eb5f90dc86b 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp @@ -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"{{.*}}} |

