summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-12-03 01:21:41 +0000
committerNico Weber <nicolasweber@gmx.de>2014-12-03 01:21:41 +0000
commitaad4af6d50a138350d401a8871ba82ecf44e9c47 (patch)
tree44ac7492bc1b2bc7dd5dd6ec091858335e4ef69e /clang/lib/CodeGen/CGClass.cpp
parente8efd99b24a9d5ef6dc011854380dbc73cb0de8c (diff)
downloadbcm5719-llvm-aad4af6d50a138350d401a8871ba82ecf44e9c47.tar.gz
bcm5719-llvm-aad4af6d50a138350d401a8871ba82ecf44e9c47.zip
Fix incorrect codegen for devirtualized calls to virtual overloaded operators.
Consider this program: struct A { virtual void operator-() { printf("base\n"); } }; struct B final : public A { virtual void operator-() override { printf("derived\n"); } }; int main() { B* b = new B; -static_cast<A&>(*b); } Before this patch, clang saw the virtual call to A::operator-(), figured out that it can be devirtualized, and then just called A::operator-() directly, without going through the vtable. Instead, it should've looked up which operator-() the call devirtualizes to and should've called that. For regular virtual member calls, clang gets all this right already. So instead of giving EmitCXXOperatorMemberCallee() all the logic that EmitCXXMemberCallExpr() already has, cut the latter function into two pieces, call the second piece EmitCXXMemberOrOperatorMemberCallExpr(), and use it also to generate code for calls to virtual member operators. This way, virtual overloaded operators automatically don't get devirtualized if they have covariant returns (like it was done for regular calls in r218602), etc. This also happens to fix (or at least improve) codegen for explicit constructor calls (`A a; a.A::A()`) in MS mode with -fsanitize-address-field-padding=1. (This adjustment for virtual operator calls seems still wrong with the MS ABI.) llvm-svn: 223185
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp14
1 files changed, 0 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 8138c6fc8d2..3957eb76527 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2163,20 +2163,6 @@ CodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base,
return false;
}
-llvm::Value *
-CodeGenFunction::EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,
- const CXXMethodDecl *MD,
- llvm::Value *This) {
- llvm::FunctionType *fnType =
- CGM.getTypes().GetFunctionType(
- CGM.getTypes().arrangeCXXMethodDeclaration(MD));
-
- if (MD->isVirtual() && !CanDevirtualizeMemberFunctionCall(E->getArg(0), MD))
- return CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, fnType);
-
- return CGM.GetAddrOfFunction(MD, fnType);
-}
-
void CodeGenFunction::EmitForwardingCallToLambda(
const CXXMethodDecl *callOperator,
CallArgList &callArgs) {
OpenPOWER on IntegriCloud