[clang] ce5173c - Use FinishThunk to finish musttail thunks

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 20 09:07:27 PDT 2020


Author: Reid Kleckner
Date: 2020-03-20T09:02:21-07:00
New Revision: ce5173c0e174870934d1b3a026f631d996136191

URL: https://github.com/llvm/llvm-project/commit/ce5173c0e174870934d1b3a026f631d996136191
DIFF: https://github.com/llvm/llvm-project/commit/ce5173c0e174870934d1b3a026f631d996136191.diff

LOG: Use FinishThunk to finish musttail thunks

FinishThunk, and the invariant of setting and then unsetting
CurCodeDecl, was added in 7f416cc42638 (2015). The invariant didn't
exist when I added this musttail codepath in ab2090d10765 (2014).
Recently in 28328c3771, I started using this codepath on non-Windows
platforms, and users reported problems during release testing (PR44987).

The issue was already present for users of EH on i686-windows-msvc, so I
added a test for that case as well.

Reviewed By: hans

Differential Revision: https://reviews.llvm.org/D76444

Added: 
    clang/test/CodeGenCXX/ms-thunks-ehspec.cpp
    clang/test/CodeGenCXX/thunks-ehspec.cpp

Modified: 
    clang/lib/CodeGen/CGVTables.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 403b9e25f7a3..412fc693c5b2 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
   // Finish the function to maintain CodeGenFunction invariants.
   // FIXME: Don't emit unreachable code.
   EmitBlock(createBasicBlock());
-  FinishFunction();
+
+  FinishThunk();
 }
 
 void CodeGenFunction::generateThunk(llvm::Function *Fn,
@@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
   CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
 
   // Thunks for variadic methods are special because in general variadic
-  // arguments cannot be perferctly forwarded. In the general case, clang
+  // arguments cannot be perfectly forwarded. In the general case, clang
   // implements such thunks by cloning the original function body. However, for
   // thunks with no return adjustment on targets that support musttail, we can
   // use musttail to perfectly forward the variadic arguments.

diff  --git a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp
new file mode 100644
index 000000000000..f72100d5078b
--- /dev/null
+++ b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=i686-windows-msvc -emit-llvm -o - | FileCheck %s
+
+// When generating thunks using musttail due to inalloca parameters, don't push
+// and pop terminate scopes. PR44987
+
+struct NonTrivial {
+  NonTrivial();
+  NonTrivial(const NonTrivial &o);
+  ~NonTrivial();
+  int x;
+};
+struct A {
+  virtual void f(NonTrivial o) noexcept;
+};
+struct B {
+  virtual void f(NonTrivial o) noexcept;
+};
+class C : A, B {
+  virtual void f(NonTrivial o) noexcept;
+};
+C c;
+
+// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0)
+// CHECK-NOT: invoke
+// CHECK: musttail call x86_thiscallcc void @"?f at C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0)
+// CHECK-NEXT  ret void
+

diff  --git a/clang/test/CodeGenCXX/thunks-ehspec.cpp b/clang/test/CodeGenCXX/thunks-ehspec.cpp
new file mode 100644
index 000000000000..30276948d3fc
--- /dev/null
+++ b/clang/test/CodeGenCXX/thunks-ehspec.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s
+
+// When generating the thunk for secondary, do not push terminate scopes for
+// either the varargs or non-varargs case. Related to PR44987.
+
+struct A {
+  virtual void primary_key();
+};
+struct B {
+  virtual void secondary();
+  virtual void secondary_vararg(int, ...);
+};
+class C : A, B {
+  virtual void primary_key();
+  void secondary() noexcept;
+  void secondary_vararg(int, ...) noexcept;
+};
+void C::primary_key() {}
+
+// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this)
+// CHECK-NOT: invoke
+// CHECK: tail call void @_ZN1C9secondaryEv(%class.C* %{{.*}})
+// CHECK-NOT: invoke
+// CHECK: ret void
+
+// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...)
+// CHECK-NOT: invoke
+// CHECK:  musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #2
+// CHECK-NEXT:  ret void


        


More information about the cfe-commits mailing list