[PATCH] D55371: Fix thunks returning memptrs via sret by emitting also scalar return values directly in sret slot (PR39901)

Hans Wennborg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 6 07:31:41 PST 2018


hans created this revision.
hans added reviewers: eli.friedman, rnk, rjmccall.

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 (Eli), we put aggregate return values directly in the sret slot, but this doesn't apply to member pointers which are considered scalar.

Maybe I'm missing something subtle, but why not always use the sret slot directly for indirect return values? This patch does that, fixing the thunks. 
Please take a look.


https://reviews.llvm.org/D55371

Files:
  lib/CodeGen/CGVTables.cpp
  lib/CodeGen/CodeGenFunction.cpp
  test/CodeGenCXX/thunk-returning-memptr.cpp


Index: test/CodeGenCXX/thunk-returning-memptr.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/thunk-returning-memptr.cpp
@@ -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
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1073,9 +1073,8 @@
     // 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())
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -350,8 +350,7 @@
                                   : 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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55371.176971.patch
Type: text/x-patch
Size: 2299 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181206/f56d0bb3/attachment.bin>


More information about the llvm-commits mailing list