r348569 - Fix thunks returning memptrs via sret by emitting also scalar return values directly in sret slot (PR39901)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 7 00:17:26 PST 2018


Author: hans
Date: Fri Dec  7 00:17:26 2018
New Revision: 348569

URL: http://llvm.org/viewvc/llvm-project?rev=348569&view=rev
Log:
Fix thunks returning memptrs via sret by emitting also scalar return values directly in sret slot (PR39901)

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

Added:
    cfe/trunk/test/CodeGenCXX/thunk-returning-memptr.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=348569&r1=348568&r2=348569&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Fri Dec  7 00:17:26 2018
@@ -350,8 +350,7 @@ void CodeGenFunction::EmitCallAndReturnF
                                   : FPT->getReturnType();
   ReturnValueSlot Slot;
   if (!ResultType->isVoidType() &&
-      CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
-      !hasScalarEvaluationKind(CurFnInfo->getReturnType()))
+      CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect)
     Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
 
   // Now emit our call.

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=348569&r1=348568&r2=348569&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Dec  7 00:17:26 2018
@@ -1073,9 +1073,8 @@ void CodeGenFunction::StartFunction(Glob
     // Count the implicit return.
     if (!endsWithReturn(D))
       ++NumReturnExprs;
-  } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
-             !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
-    // Indirect aggregate return; emit returned value directly into sret slot.
+  } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) {
+    // Indirect return; emit returned value directly into sret slot.
     // This reduces code size, and affects correctness in C++.
     auto AI = CurFn->arg_begin();
     if (CurFnInfo->getReturnInfo().isSRetAfterThis())

Added: cfe/trunk/test/CodeGenCXX/thunk-returning-memptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunk-returning-memptr.cpp?rev=348569&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thunk-returning-memptr.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/thunk-returning-memptr.cpp Fri Dec  7 00:17:26 2018
@@ -0,0 +1,27 @@
+// 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




More information about the cfe-commits mailing list