Thunks that return member pointers via sret are broken due to using temporary storage for the return value on the stack and then passing that pointer to a tail call, violating the rule that a tail call can't access allocas in the caller (see bug). Since r90526, we put aggregate return values directly in the sret slot, but this doesn't apply to member pointers which are considered scalar. Unless I'm missing something subtle, we should be able to always use the sret slot directly for indirect return values. Differential revision: https://reviews.llvm.org/D55371 llvm-svn: 348569
28 lines
651 B
C++
28 lines
651 B
C++
// RUN: %clang_cc1 -triple=i686 -emit-llvm -o - %s | FileCheck %s
|
|
|
|
|
|
struct X;
|
|
typedef void (X::*memptr)();
|
|
|
|
struct A {
|
|
virtual memptr f();
|
|
};
|
|
|
|
struct B {
|
|
virtual memptr f();
|
|
};
|
|
|
|
struct C : A, B {
|
|
C();
|
|
memptr f() override __attribute__((noinline)) { return nullptr; };
|
|
};
|
|
|
|
C::C() {}
|
|
|
|
// Make sure the member pointer is returned from the thunk via the return slot.
|
|
// Because of the tail call, the return value cannot be copied into a local
|
|
// alloca. (PR39901)
|
|
|
|
// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv({ i32, i32 }* noalias sret %agg.result, %struct.C* %this)
|
|
// CHECK: tail call void @_ZN1C1fEv({ i32, i32 }* sret %agg.result
|