Fix a couple of cases where we weren't generating the right kind of call

for a call to a virtual function.

llvm-svn: 88891
This commit is contained in:
Eli Friedman 2009-11-16 05:31:29 +00:00
parent 011c4c341b
commit e6ce354795
3 changed files with 39 additions and 8 deletions

View File

@ -282,14 +282,20 @@ 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.
llvm::Value *Callee;
if (MD->isVirtual() && !ME->hasQualifier() &&
!canDevirtualizeMemberFunctionCalls(ME->getBase()))
Callee = BuildVirtualCall(MD, This, Ty);
else if (const CXXDestructorDecl *Destructor
= dyn_cast<CXXDestructorDecl>(MD))
Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
else
if (const CXXDestructorDecl *Destructor
= dyn_cast<CXXDestructorDecl>(MD)) {
if (MD->isVirtual() && !ME->hasQualifier() &&
!canDevirtualizeMemberFunctionCalls(ME->getBase())) {
Callee = BuildVirtualCall(Destructor, Dtor_Complete, This, Ty);
} else {
Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
}
} else if (MD->isVirtual() && !ME->hasQualifier() &&
!canDevirtualizeMemberFunctionCalls(ME->getBase())) {
Callee = BuildVirtualCall(MD, This, Ty);
} else {
Callee = CGM.GetAddrOfFunction(MD, Ty);
}
return EmitCXXMemberCall(MD, Callee, This,
CE->arg_begin(), CE->arg_end());
@ -425,10 +431,15 @@ CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
const llvm::Type *Ty =
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
FPT->isVariadic());
llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
llvm::Value *Callee;
if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0)))
Callee = BuildVirtualCall(MD, This, Ty);
else
Callee = CGM.GetAddrOfFunction(MD, Ty);
return EmitCXXMemberCall(MD, Callee, This,
E->arg_begin() + 1, E->arg_end());
}

View File

@ -0,0 +1,10 @@
// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
struct A {
virtual int operator-() = 0;
};
void f(A *a) {
// CHECK: call i32 %
-*a;
}

View File

@ -0,0 +1,10 @@
// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
struct A {
virtual ~A();
};
void f(A *a) {
// CHECK: call void %
a->~A();
}