Skip to content

Commit

Permalink
[Clang][Codegen] Do not annotate thunk's this/return types with align…
Browse files Browse the repository at this point in the history
…/deref/nonnull attrs

As it was discovered in post-commit feedback
for 0aa0458,
we handle thunks incorrectly, and end up annotating
their this/return with attributes that are valid
for their callees, not for thunks themselves.

While it would be good to fix this properly,
and keep annotating them on thunks,
i've tried doing that in https://reviews.llvm.org/D100388
with little success, and the patch is stuck for a month now.

So for now, as a stopgap measure, subj.
  • Loading branch information
LebedevRI committed May 13, 2021
1 parent 70aa462 commit a624cec
Show file tree
Hide file tree
Showing 20 changed files with 67 additions and 56 deletions.
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGBlocks.cpp
Expand Up @@ -1902,7 +1902,7 @@ static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,
} else {
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
}
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Expand Up @@ -1692,7 +1692,7 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
llvm::Function *Fn = llvm::Function::Create(
FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
Fn->setDoesNotThrow();

Expand Down
45 changes: 27 additions & 18 deletions clang/lib/CodeGen/CGCall.cpp
Expand Up @@ -1982,9 +1982,12 @@ static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
/// attributes that restrict how the frontend generates code must be
/// added here rather than getDefaultFunctionAttributes.
///
void CodeGenModule::ConstructAttributeList(
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
void CodeGenModule::ConstructAttributeList(StringRef Name,
const CGFunctionInfo &FI,
CGCalleeInfo CalleeInfo,
llvm::AttributeList &AttrList,
unsigned &CallingConv,
bool AttrOnCallSite, bool IsThunk) {
llvm::AttrBuilder FuncAttrs;
llvm::AttrBuilder RetAttrs;

Expand Down Expand Up @@ -2275,18 +2278,21 @@ void CodeGenModule::ConstructAttributeList(
llvm_unreachable("Invalid ABI kind for return argument");
}

if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
QualType PTy = RefTy->getPointeeType();
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
RetAttrs.addDereferenceableAttr(
getMinimumObjectSize(PTy).getQuantity());
if (getContext().getTargetAddressSpace(PTy) == 0 &&
!CodeGenOpts.NullPointerIsValid)
RetAttrs.addAttribute(llvm::Attribute::NonNull);
if (PTy->isObjectType()) {
llvm::Align Alignment =
getNaturalPointeeTypeAlignment(RetTy).getAsAlign();
RetAttrs.addAlignmentAttr(Alignment);
if (!IsThunk) {
// FIXME: fix this properly, https://reviews.llvm.org/D100388
if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
QualType PTy = RefTy->getPointeeType();
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
RetAttrs.addDereferenceableAttr(
getMinimumObjectSize(PTy).getQuantity());
if (getContext().getTargetAddressSpace(PTy) == 0 &&
!CodeGenOpts.NullPointerIsValid)
RetAttrs.addAttribute(llvm::Attribute::NonNull);
if (PTy->isObjectType()) {
llvm::Align Alignment =
getNaturalPointeeTypeAlignment(RetTy).getAsAlign();
RetAttrs.addAlignmentAttr(Alignment);
}
}
}

Expand All @@ -2313,9 +2319,11 @@ void CodeGenModule::ConstructAttributeList(
llvm::AttributeSet::get(getLLVMContext(), Attrs);
}

// Apply `nonnull` and `dereferencable(N)` to the `this` argument.
// Apply `nonnull` and `dereferencable(N)` to the `this` argument,
// unless this is a thunk function.
// FIXME: fix this properly, https://reviews.llvm.org/D100388
if (FI.isInstanceMethod() && !IRFunctionArgs.hasInallocaArg() &&
!FI.arg_begin()->type->isVoidPointerType()) {
!FI.arg_begin()->type->isVoidPointerType() && !IsThunk) {
auto IRArgs = IRFunctionArgs.getIRArgs(0);

assert(IRArgs.second == 1 && "Expected only a single `this` pointer.");
Expand Down Expand Up @@ -5140,7 +5148,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::AttributeList Attrs;
CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
Callee.getAbstractInfo(), Attrs, CallingConv,
/*AttrOnCallSite=*/true);
/*AttrOnCallSite=*/true,
/*IsThunk=*/false);

if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl))
if (FD->hasAttr<StrictFPAttr>())
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Expand Up @@ -3395,7 +3395,7 @@ void CodeGenFunction::EmitCfiCheckFail() {
llvm::FunctionType::get(VoidTy, {VoidPtrTy, VoidPtrTy}, false),
llvm::GlobalValue::WeakODRLinkage, "__cfi_check_fail", &CGM.getModule());

CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
F->setVisibility(llvm::GlobalValue::HiddenVisibility);

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGNonTrivialStruct.cpp
Expand Up @@ -470,7 +470,7 @@ template <class Derived> struct GenFuncBase {
llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
F->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
IdentifierInfo *II = &Ctx.Idents.get(FuncName);
FunctionDecl *FD = FunctionDecl::Create(
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGObjC.cpp
Expand Up @@ -760,7 +760,7 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
if (OMD->isDirectMethod()) {
Fn->setVisibility(llvm::Function::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(OMD, FI, Fn);
CGM.SetLLVMFunctionAttributes(OMD, FI, Fn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(OMD, Fn);
} else {
CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGVTables.cpp
Expand Up @@ -427,7 +427,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
unsigned CallingConv;
llvm::AttributeList Attrs;
CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
Attrs, CallingConv, /*AttrOnCallSite=*/true);
Attrs, CallingConv, /*AttrOnCallSite=*/true,
/*IsThunk=*/false);
Call->setAttributes(Attrs);
Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));

Expand Down Expand Up @@ -531,7 +532,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
OldThunkFn->setName(StringRef());
ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
Name.str(), &CGM.getModule());
CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);

// If needed, replace the old thunk with a bitcast.
if (!OldThunkFn->use_empty()) {
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/CodeGen/CodeGenModule.cpp
Expand Up @@ -1466,10 +1466,11 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) {

void CodeGenModule::SetLLVMFunctionAttributes(GlobalDecl GD,
const CGFunctionInfo &Info,
llvm::Function *F) {
llvm::Function *F, bool IsThunk) {
unsigned CallingConv;
llvm::AttributeList PAL;
ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv, false);
ConstructAttributeList(F->getName(), Info, GD, PAL, CallingConv,
/*AttrOnCallSite=*/false, IsThunk);
F->setAttributes(PAL);
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
Expand Down Expand Up @@ -2008,7 +2009,7 @@ void CodeGenModule::SetInternalFunctionAttributes(GlobalDecl GD,
llvm::Function *F,
const CGFunctionInfo &FI) {
const Decl *D = GD.getDecl();
SetLLVMFunctionAttributes(GD, FI, F);
SetLLVMFunctionAttributes(GD, FI, F, /*IsThunk=*/false);
SetLLVMFunctionAttributesForDefinition(D, F);

F->setLinkage(llvm::Function::InternalLinkage);
Expand Down Expand Up @@ -2062,7 +2063,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
const auto *FD = cast<FunctionDecl>(GD.getDecl());

if (!IsIncompleteFunction)
SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F);
SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F,
IsThunk);

// Add the Returned attribute for "this", except for iOS 5 and earlier
// where substantial code, including the libstdc++ dylib, was compiled with
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CodeGenModule.h
Expand Up @@ -1164,7 +1164,7 @@ class CodeGenModule : public CodeGenTypeCache {

/// Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info,
llvm::Function *F);
llvm::Function *F, bool IsThunk);

/// Set the LLVM function attributes which only apply to a function
/// definition.
Expand Down Expand Up @@ -1200,7 +1200,7 @@ class CodeGenModule : public CodeGenTypeCache {
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info,
CGCalleeInfo CalleeInfo,
llvm::AttributeList &Attrs, unsigned &CallingConv,
bool AttrOnCallSite);
bool AttrOnCallSite, bool IsThunk);

/// Adds attributes to F according to our CodeGenOptions and LangOptions, as
/// though we had emitted it ourselves. We remove any attributes on F that
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Expand Up @@ -2811,7 +2811,7 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));

CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper, /*IsThunk=*/false);

// Always resolve references to the wrapper at link time.
if (!Wrapper->hasLocalLinkage())
Expand Down Expand Up @@ -2944,8 +2944,8 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
llvm::GlobalVariable::ExternalWeakLinkage,
InitFnName.str(), &CGM.getModule());
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI,
cast<llvm::Function>(Init));
CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, cast<llvm::Function>(Init), /*IsThunk=*/false);
}

if (Init) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/MicrosoftCXXABI.cpp
Expand Up @@ -2046,7 +2046,7 @@ MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
if (MD->isExternallyVisible())
ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));

CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);

// Add the "thunk" attribute so that LLVM knows that the return type is
Expand Down
16 changes: 8 additions & 8 deletions clang/test/CodeGenCXX/constructor-destructor-return-this.cpp
Expand Up @@ -70,33 +70,33 @@ C::~C() { }
// CHECKGEN-LABEL: define{{.*}} void @_ZN1CC1EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKGEN-LABEL: define{{.*}} void @_ZN1CD2Ev(%class.C* {{[^,]*}} %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZN1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKGEN-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)

// CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
// CHECKARM-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
// CHECKARM-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKARM-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKARM-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKARM-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKARM-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)

// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} %this)
// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKIOS5-LABEL: define{{.*}} %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKIOS5-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKIOS5-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKIOS5-LABEL: define{{.*}} void @_ZThn8_N1CD0Ev(%class.C* %this)

// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CC2EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CC1EPiPc(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CD2Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZN1CD1Ev(%class.C* {{[^,]*}} returned {{[^,]*}} %this)
// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZThn16_N1CD1Ev(%class.C* {{[^,]*}} %this)
// CHECKFUCHSIA-LABEL: define{{.*}} %class.C* @_ZThn16_N1CD1Ev(%class.C* %this)
// CHECKFUCHSIA-LABEL: define{{.*}} void @_ZN1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKFUCHSIA-LABEL: define{{.*}} void @_ZThn16_N1CD0Ev(%class.C* {{[^,]*}} %this)
// CHECKFUCHSIA-LABEL: define{{.*}} void @_ZThn16_N1CD0Ev(%class.C* %this)

// CHECKMS-LABEL: define dso_local x86_thiscallcc %class.C* @"??0C@@QAE@PAHPAD@Z"(%class.C* {{[^,]*}} returned {{[^,]*}} %this, i32* %i, i8* %c)
// CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1C@@UAE@XZ"(%class.C* {{[^,]*}} %this)
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
Expand Up @@ -22,7 +22,7 @@ C::C() {} // force emission
// CHECK32-NEXT: ret void

// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z"
// CHECK64: (%"struct.byval_thunk::C"* {{[^,]*}} %this, %"struct.byval_thunk::Agg"* %x)
// CHECK64: (%"struct.byval_thunk::C"* %this, %"struct.byval_thunk::Agg"* %x)
// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@byval_thunk@@UEAAXUAgg@2@@Z"
// CHECK64: (%"struct.byval_thunk::C"* {{[^,]*}} %{{.*}}, %"struct.byval_thunk::Agg"* %x)
Expand Down Expand Up @@ -54,7 +54,7 @@ C::C() {} // force emission
// CHECK32-NEXT: ret void

// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z"
// CHECK64: (%"struct.stdcall_thunk::C"* {{[^,]*}} %this, %"struct.stdcall_thunk::Agg"* %x)
// CHECK64: (%"struct.stdcall_thunk::C"* %this, %"struct.stdcall_thunk::Agg"* %x)
// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@stdcall_thunk@@UEAAXUAgg@2@@Z"
// CHECK64: (%"struct.stdcall_thunk::C"* {{[^,]*}} %{{.*}}, %"struct.stdcall_thunk::Agg"* %x)
Expand Down Expand Up @@ -86,7 +86,7 @@ C::C() {} // force emission
// CHECK32-NEXT: ret %"struct.sret_thunk::Agg"* %[[rv]]

// CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z"
// CHECK64: (%"struct.sret_thunk::C"* {{[^,]*}} %this, %"struct.sret_thunk::Agg"* noalias sret(%"struct.sret_thunk::Agg") align 4 %agg.result, %"struct.sret_thunk::Agg"* %x)
// CHECK64: (%"struct.sret_thunk::C"* %this, %"struct.sret_thunk::Agg"* noalias sret(%"struct.sret_thunk::Agg") align 4 %agg.result, %"struct.sret_thunk::Agg"* %x)
// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8
// CHECK64: call void @"?foo@C@sret_thunk@@UEAA?AUAgg@2@U32@@Z"
// CHECK64: (%"struct.sret_thunk::C"* {{[^,]*}} %{{.*}}, %"struct.sret_thunk::Agg"* sret(%"struct.sret_thunk::Agg") align 4 %agg.result, %"struct.sret_thunk::Agg"* %x)
Expand Down
3 changes: 1 addition & 2 deletions clang/test/CodeGenCXX/microsoft-abi-structors.cpp
Expand Up @@ -173,13 +173,12 @@ void foo() {
C c;
}
// DTORS2-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z"
// DTORS2: (%"struct.dtor_in_second_nvbase::C"* {{[^,]*}} %this, i32 %should_call_delete)
// DTORS2: (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete)
// Do an adjustment from B* to C*.
// DTORS2: getelementptr i8, i8* %{{.*}}, i32 -4
// DTORS2: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::C"*
// DTORS2: %[[CALL:.*]] = tail call x86_thiscallcc i8* @"??_GC@dtor_in_second_nvbase@@UAEPAXI@Z"
// DTORS2: ret i8* %[[CALL]]

}

namespace test2 {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
Expand Up @@ -61,7 +61,7 @@ struct C : A, B {

C::C() {} // Emits vftable and forces thunk generation.

// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC@@W3AEPAXI@Z"(%struct.C* {{[^,]*}} %this, i32 %should_call_delete) {{.*}} comdat
// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc i8* @"??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete) {{.*}} comdat
// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4
// FIXME: should actually call _EC, not _GC.
// CODEGEN: call x86_thiscallcc i8* @"??_GC@@UAEPAXI@Z"
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/thunk-returning-memptr.cpp
Expand Up @@ -23,5 +23,5 @@ C::C() {}
// 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({ i32, i32 }) align 4 %agg.result, %struct.C* {{[^,]*}} %this)
// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv({ i32, i32 }* noalias sret({ i32, i32 }) align 4 %agg.result, %struct.C* %this)
// CHECK: tail call void @_ZN1C1fEv({ i32, i32 }* sret({ i32, i32 }) align 4 %agg.result
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/thunk-wrong-return-type.cpp
Expand Up @@ -23,4 +23,4 @@ struct Y : U, X {
Y y;

// FIXME: The return type should be align 1 dereferenceable(1) %struct.A.8*
// CHECK: define linkonce_odr nonnull align 32 dereferenceable(40) %struct.B.1* @_ZTchn8_v0_n24_N1Y1fEv(%struct.Y.5* nonnull dereferenceable(16) %this) unnamed_addr #1 comdat align 2 {
// CHECK: define linkonce_odr %struct.B.1* @_ZTchn8_v0_n24_N1Y1fEv(%struct.Y.5* %this) unnamed_addr #1 comdat align 2 {
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/thunk-wrong-this.cpp
Expand Up @@ -20,6 +20,6 @@ void Obj::Foo2() {}
// CHECK: define dso_local void @_ZN3Obj4Foo2Ev(%class.Obj.0* nonnull dereferenceable(16) %this) unnamed_addr #0 align 2 {

// FIXME: the argument should be %class.Base2.2* nonnull dereferenceable(8) %this
// CHECK: define dso_local void @_ZThn8_N3Obj4Foo2Ev(%class.Obj.0* nonnull dereferenceable(16) %this) unnamed_addr #1 align 2 {
// CHECK: define dso_local void @_ZThn8_N3Obj4Foo2Ev(%class.Obj.0* %this) unnamed_addr #1 align 2 {

// CHECK: tail call void @_ZN3Obj4Foo2Ev(%class.Obj.0* nonnull dereferenceable(16) %2)
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/thunks-ehspec.cpp
Expand Up @@ -17,13 +17,13 @@ class C : A, B {
};
void C::primary_key() {}

// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* {{[^,]*}} %this) {{.*}} #2
// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this) {{.*}} #2
// 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, ...) {{.*}} #2
// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...) {{.*}} #2
// CHECK-NOT: invoke
// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* {{[^,]*}} %{{.*}}, i32 %{{.*}}, ...) #3
// CHECK-NEXT: ret void

0 comments on commit a624cec

Please sign in to comment.