summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-04-18 23:21:32 +0000
committerReid Kleckner <rnk@google.com>2018-04-18 23:21:32 +0000
commit54a33d7a27516e71b31dc2d0934a40893c53d917 (patch)
treed656615e6f51b17fa1d6f4547fdeda32d9eb0fa4
parent47196a25bbec1d56961a1caf3e68410ee6aa93b5 (diff)
downloadbcm5719-llvm-54a33d7a27516e71b31dc2d0934a40893c53d917.tar.gz
bcm5719-llvm-54a33d7a27516e71b31dc2d0934a40893c53d917.zip
[MS] Fix unprototyped thunk emission for incomplete return types
Fixes PR37161 llvm-svn: 330303
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp14
-rw-r--r--clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp17
2 files changed, 26 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index d063f036d75..7ac15ba6153 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -233,11 +233,15 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
QualType ThisType = MD->getThisType(getContext());
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
- QualType ResultType = CGM.getCXXABI().HasThisReturn(GD)
- ? ThisType
- : CGM.getCXXABI().hasMostDerivedReturn(GD)
- ? CGM.getContext().VoidPtrTy
- : FPT->getReturnType();
+ QualType ResultType;
+ if (IsUnprototyped)
+ ResultType = CGM.getContext().VoidTy;
+ else if (CGM.getCXXABI().HasThisReturn(GD))
+ ResultType = ThisType;
+ else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
+ ResultType = CGM.getContext().VoidPtrTy;
+ else
+ ResultType = FPT->getReturnType();
FunctionArgList FunctionArgs;
// Create the implicit 'this' parameter declaration.
diff --git a/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp b/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp
index b2ca5cb0d13..0a232b98518 100644
--- a/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp
+++ b/clang/test/CodeGenCXX/ms-thunks-unprototyped.cpp
@@ -24,11 +24,28 @@ struct B : virtual A {
struct C : B { int c; };
C c;
+// Do the same thing, but with an incomplete return type.
+struct B1 { virtual DoNotInstantiate<void> f() = 0; };
+struct B2 { virtual DoNotInstantiate<void> f() = 0; };
+struct S : B1, B2 { DoNotInstantiate<void> f() override; };
+S s;
+
+// CHECK: @"??_7S@@6BB2@@@" = linkonce_odr unnamed_addr constant
+// CHECK-SAME: void (%struct.S*, ...)* @"?f@S@@W7EAA?AU?$DoNotInstantiate@X@@XZ"
+
// CHECK: @"??_7C@@6B@" = linkonce_odr unnamed_addr constant
// CHECK-SAME: void (%struct.B*, ...)* @"?foo@B@@W7EAAXUIncomplete@@@Z"
// CHECK-SAME: void (%struct.B*, ...)* @"?bar@B@@W7EAAXU?$DoNotInstantiate@H@@@Z"
// CHECK-SAME: i32 (i8*, i32)* @"?baz@B@@W7EAAHU?$InstantiateLater@H@@@Z"
+
+// CHECK-LABEL: define linkonce_odr dso_local void @"?f@S@@W7EAA?AU?$DoNotInstantiate@X@@XZ"(%struct.S* %this, ...)
+// CHECK: %[[THIS_ADJ_i8:[^ ]*]] = getelementptr i8, i8* {{.*}}, i32 -8
+// CHECK: %[[THIS_ADJ:[^ ]*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.S*
+// CHECK: musttail call void (%struct.S*, ...) {{.*}}@"?f@S@@UEAA?AU?$DoNotInstantiate@X@@XZ"
+// CHECK-SAME: (%struct.S* %[[THIS_ADJ]], ...)
+// CHECK: ret void
+
// The thunks should have a -8 adjustment.
// CHECK-LABEL: define linkonce_odr dso_local void @"?foo@B@@W7EAAXUIncomplete@@@Z"(%struct.B* %this, ...)
OpenPOWER on IntegriCloud