aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGExprCXX.cpp31
-rw-r--r--test/CodeGenCXX/apple-kext-indirect-call.C3
2 files changed, 17 insertions, 17 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 08ff17e1fd..5521c0f8ce 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -55,9 +55,14 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
/// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given
/// expr can be devirtualized.
-static bool canDevirtualizeMemberFunctionCalls(const Expr *Base,
+static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context,
+ const Expr *Base,
const CXXMethodDecl *MD) {
+ // Cannot divirtualize in kext mode.
+ if (Context.getLangOptions().AppleKext)
+ return false;
+
// If the member function has the "final" attribute, we know that it can't be
// overridden and can therefore devirtualize it.
if (MD->hasAttr<FinalAttr>())
@@ -173,12 +178,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
// We also don't emit a virtual call if the base expression has a record type
// because then we know what the type is.
bool UseVirtualCall;
- if (!getContext().getLangOptions().AppleKext)
- UseVirtualCall = MD->isVirtual() && !ME->hasQualifier()
- && !canDevirtualizeMemberFunctionCalls(ME->getBase(), MD);
- else
- UseVirtualCall = MD->isVirtual();
-
+ UseVirtualCall = MD->isVirtual() && !ME->hasQualifier()
+ && !canDevirtualizeMemberFunctionCalls(getContext(),
+ ME->getBase(), MD);
llvm::Value *Callee;
if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
if (UseVirtualCall) {
@@ -190,14 +192,13 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
dyn_cast<CXXConstructorDecl>(MD)) {
Callee = CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty);
} else if (UseVirtualCall) {
- if (getContext().getLangOptions().AppleKext &&
- ME->hasQualifier()) {
- Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), This, Ty);
- }
- else
Callee = BuildVirtualCall(MD, This, Ty);
} else {
- Callee = CGM.GetAddrOfFunction(MD, Ty);
+ if (getContext().getLangOptions().AppleKext &&
+ ME->hasQualifier())
+ Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), This, Ty);
+ else
+ Callee = CGM.GetAddrOfFunction(MD, Ty);
}
return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
@@ -277,8 +278,8 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
FPT->isVariadic());
llvm::Value *Callee;
if (MD->isVirtual() &&
- (getContext().getLangOptions().AppleKext ||
- !canDevirtualizeMemberFunctionCalls(E->getArg(0), MD)))
+ !canDevirtualizeMemberFunctionCalls(getContext(),
+ E->getArg(0), MD))
Callee = BuildVirtualCall(MD, This, Ty);
else
Callee = CGM.GetAddrOfFunction(MD, Ty);
diff --git a/test/CodeGenCXX/apple-kext-indirect-call.C b/test/CodeGenCXX/apple-kext-indirect-call.C
index 401e743305..2dbb0b8395 100644
--- a/test/CodeGenCXX/apple-kext-indirect-call.C
+++ b/test/CodeGenCXX/apple-kext-indirect-call.C
@@ -1,8 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s
struct Base {
- virtual void abc1(void) const;
- virtual void abc2(void) const;
virtual void abc(void) const;
};
@@ -12,4 +10,5 @@ void FUNC(Base* p) {
p->Base::abc();
}
+// CHECK: getelementptr inbounds (void (%struct.Base*)** bitcast ([3 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2)
// CHECK-NOT: call void @_ZNK4Base3abcEv