]> granicus.if.org Git - clang/commit
Fix incorrect codegen for devirtualized calls to virtual overloaded operators.
authorNico Weber <nicolasweber@gmx.de>
Wed, 3 Dec 2014 01:21:41 +0000 (01:21 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 3 Dec 2014 01:21:41 +0000 (01:21 +0000)
commit2ed848d612648bfba2e4130561b7ea574cd7cd3a
tree7d114387f9e3181fdc25a11b57ca8b7c527ecc7f
parent25a330f77d69fd8e49d4f953899eb779abd1d58f
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.)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223185 91177308-0d34-0410-b5e6-96231b3b80d8
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp