Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use FinishThunk to finish musttail thunks
FinishThunk, and the invariant of setting and then unsetting CurCodeDecl, was added in 7f416cc (2015). The invariant didn't exist when I added this musttail codepath in ab2090d (2014). Recently in 28328c3, 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 (cherry picked from commit ce5173c)
- Loading branch information
Showing
3 changed files
with
59 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0) | ||
// CHECK-NOT: invoke | ||
// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0) | ||
// CHECK-NEXT ret void | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |