Skip to content

Commit 55fb6ba

Browse files
author
Andres Madrid Ucha
committed
Clang: Fix mismatch in elementtype
When processing thunk functions and elementtypes with inheritance, there were logic errors in the direct base checking that could lead to incorrect function types being retained. The issue occurred in the following case: 1. Initial comparison: CurrentThisStructTy (ios_base) == NewThisTy (ios_base) - Both types are the same, so NewIsDirectBase is incorrectly set to true - ThunkFn type: void (%class._ZSt8ios_base*) - ThunkFnTy: (%class._ZSt8ios_base*) - Since types match, no update occurs 2. Second comparison: CurrentThisStructTy != NewThisTy - ThunkFn then gets updated to void (%class._ZSt9basic_iosIcSt11char_traitsIcEE*) - This is correct behavior 3. Third comparison: Same types again (ios_base == ios_base) - NewIsDirectBase is again set to true, which will then affect updating the ThunkFn - Current ThunkFn: void (%class._ZSt9basic_iosIcSt11char_traitsIcEE*) but the one we want to update to is void (%class._ZSt8ios_base*) - Because NewIsDirectBase is true, the update is skipped eventhough ThunkFn != ThunkFnTy. This leaves ThunkFn with the wrong type
1 parent 8907c03 commit 55fb6ba

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -586,31 +586,37 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
586586
// CHEERP: If there are virtual bases it is possible that the type of `this` mismatches
587587
// between the existing and new think, but one is directbase of the other.
588588
// We keep the thunk with the most basic `this` type
589+
590+
if (!ThunkFn->hasParamAttribute(thisIndex, llvm::Attribute::ElementType))
591+
ThunkFn->addParamAttr(thisIndex, llvm::Attribute::get(CGM.getLLVMContext(), llvm::Attribute::ElementType, CurrentThisTy));
592+
589593
bool NewIsDirectBase = false;
590594
bool CurrentIsDirectBase = false;
591595
if (!CGM.getTarget().isByteAddressable()) {
592-
// Geth the `this` type. It can be the first or second parameter (if there is a
596+
// Get the `this` type. It can be the first or second parameter (if there is a
593597
// struct return pointer)
594598
llvm::StructType* CurrentThisStructTy = cast<llvm::StructType>(CurrentThisTy);
595599
llvm::StructType* NewThisTy = cast<llvm::StructType>(ThunkFn->getParamAttribute(thisIndex, llvm::Attribute::ElementType).getValueAsType());
596-
597-
// Check if one of the types is directbase of the other (check all the directbase hierarchy)
598-
for (llvm::StructType* I = NewThisTy; I != nullptr; I = I->getDirectBase()) {
599-
if (I == CurrentThisTy) {
600-
NewIsDirectBase = true;
601-
break;
600+
// If the attribute type is the same as current, or doesn't exist, skip the directbase check
601+
if (NewThisTy && NewThisTy != CurrentThisTy) {
602+
// Check if one of the types is directbase of the other (check all the directbase hierarchy)
603+
for (llvm::StructType* I = NewThisTy; I != nullptr; I = I->getDirectBase()) {
604+
if (I == CurrentThisTy) {
605+
NewIsDirectBase = true;
606+
break;
607+
}
602608
}
603-
}
604-
for (llvm::StructType* I = CurrentThisStructTy; I != nullptr; I = I->getDirectBase()) {
605-
if (I == NewThisTy) {
606-
CurrentIsDirectBase = true;
607-
break;
609+
for (llvm::StructType* I = CurrentThisStructTy; I != nullptr; I = I->getDirectBase()) {
610+
if (I == NewThisTy) {
611+
CurrentIsDirectBase = true;
612+
break;
613+
}
608614
}
609615
}
610616
}
617+
611618
if (ThunkFn->getFunctionType() != ThunkFnTy && !NewIsDirectBase) {
612619
llvm::GlobalValue *OldThunkFn = ThunkFn;
613-
614620
// If the types mismatch then we have to rewrite the definition.
615621
assert((OldThunkFn->isDeclaration() || CurrentIsDirectBase) &&
616622
"Shouldn't replace non-declaration");
@@ -634,6 +640,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
634640
OldThunkFn->eraseFromParent();
635641
}
636642

643+
637644
bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
638645
bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
639646

0 commit comments

Comments
 (0)