Skip to content

Commit 68cd4f7

Browse files
rnktstellar
authored andcommitted
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)
1 parent 1feb332 commit 68cd4f7

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
437437
// Finish the function to maintain CodeGenFunction invariants.
438438
// FIXME: Don't emit unreachable code.
439439
EmitBlock(createBasicBlock());
440-
FinishFunction();
440+
441+
FinishThunk();
441442
}
442443

443444
void CodeGenFunction::generateThunk(llvm::Function *Fn,
@@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
564565
CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
565566

566567
// Thunks for variadic methods are special because in general variadic
567-
// arguments cannot be perferctly forwarded. In the general case, clang
568+
// arguments cannot be perfectly forwarded. In the general case, clang
568569
// implements such thunks by cloning the original function body. However, for
569570
// thunks with no return adjustment on targets that support musttail, we can
570571
// use musttail to perfectly forward the variadic arguments.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=i686-windows-msvc -emit-llvm -o - | FileCheck %s
2+
3+
// When generating thunks using musttail due to inalloca parameters, don't push
4+
// and pop terminate scopes. PR44987
5+
6+
struct NonTrivial {
7+
NonTrivial();
8+
NonTrivial(const NonTrivial &o);
9+
~NonTrivial();
10+
int x;
11+
};
12+
struct A {
13+
virtual void f(NonTrivial o) noexcept;
14+
};
15+
struct B {
16+
virtual void f(NonTrivial o) noexcept;
17+
};
18+
class C : A, B {
19+
virtual void f(NonTrivial o) noexcept;
20+
};
21+
C c;
22+
23+
// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0)
24+
// CHECK-NOT: invoke
25+
// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0)
26+
// CHECK-NEXT ret void
27+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-passes | FileCheck %s
2+
3+
// When generating the thunk for secondary, do not push terminate scopes for
4+
// either the varargs or non-varargs case. Related to PR44987.
5+
6+
struct A {
7+
virtual void primary_key();
8+
};
9+
struct B {
10+
virtual void secondary();
11+
virtual void secondary_vararg(int, ...);
12+
};
13+
class C : A, B {
14+
virtual void primary_key();
15+
void secondary() noexcept;
16+
void secondary_vararg(int, ...) noexcept;
17+
};
18+
void C::primary_key() {}
19+
20+
// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this)
21+
// CHECK-NOT: invoke
22+
// CHECK: tail call void @_ZN1C9secondaryEv(%class.C* %{{.*}})
23+
// CHECK-NOT: invoke
24+
// CHECK: ret void
25+
26+
// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...)
27+
// CHECK-NOT: invoke
28+
// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #2
29+
// CHECK-NEXT: ret void

0 commit comments

Comments
 (0)