Merge pull request #85560 from slavapestov/fix-ridiculous-irgen-thing

IRGen: Remove unsafe usage of static variable
This commit is contained in:
Slava Pestov
2025-11-20 02:54:38 -05:00
committed by GitHub
5 changed files with 33 additions and 30 deletions

View File

@@ -465,6 +465,10 @@ class LinkEntity {
// These are both type kinds and protocol-conformance kinds.
// TYPE KINDS: BEGIN {{
/// A SIL differentiability witness. The pointer is a
/// SILDifferentiabilityWitness*.
DifferentiabilityWitness,
/// A lazy protocol witness accessor function. The pointer is a
/// canonical TypeBase*, and the secondary pointer is a
/// ProtocolConformance*.
@@ -475,10 +479,6 @@ class LinkEntity {
/// ProtocolConformance*.
ProtocolWitnessTableLazyCacheVariable,
/// A SIL differentiability witness. The pointer is a
/// SILDifferentiabilityWitness*.
DifferentiabilityWitness,
// Everything following this is a type kind.
/// A value witness for a type.

View File

@@ -4046,38 +4046,41 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
auto var = createVariable(*this, link, definitionType,
entity.getAlignment(*this), DbgTy);
// @escaping () -> ()
// NOTE: we explicitly desugar the `Void` type for the return as the test
// suite makes assumptions that it can emit the value witness table without a
// standard library for the target. `Context.getVoidType()` will attempt to
// lookup the `Decl` before returning the canonical type. To workaround this
// dependency, we simply desugar the `Void` return type to `()`.
static CanType kAnyFunctionType =
FunctionType::get({}, Context.TheEmptyTupleType,
ASTExtInfo{})->getCanonicalType();
auto isZeroParamFunctionType = [this](Type t) -> bool {
if (auto *funcTy = t->getAs<FunctionType>()) {
return (funcTy->getParams().size() == 0 &&
funcTy->getResult()->isEqual(Context.TheEmptyTupleType));
}
return false;
};
// Adjust the linkage for the well-known VWTs that are strongly defined
// in the runtime.
//
// We special case the "AnyFunctionType" here as this type is referened
// We special case the "AnyFunctionType" here as this type is referenced
// inside the standard library with the definition being in the runtime
// preventing the normal detection from identifying that this is module
// local.
//
// If we are statically linking the standard library, we need to internalise
// the symbols.
if (getSwiftModule()->isStdlibModule() ||
(Context.getStdlibModule() &&
Context.getStdlibModule()->isStaticLibrary()))
if (entity.isTypeKind() &&
(IsWellKnownBuiltinOrStructralType(entity.getType()) ||
entity.getType() == kAnyFunctionType))
if (auto *GV = dyn_cast<llvm::GlobalValue>(var))
if (GV->hasDLLImportStorageClass())
ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage,
llvm::GlobalValue::DefaultVisibility,
llvm::GlobalValue::DefaultStorageClass})
.to(GV);
if (auto *GV = dyn_cast<llvm::GlobalValue>(var)) {
if (GV->hasDLLImportStorageClass()) {
if (getSwiftModule()->isStdlibModule() ||
(Context.getStdlibModule() &&
Context.getStdlibModule()->isStaticLibrary())) {
if (entity.isTypeKind() &&
(isWellKnownBuiltinOrStructuralType(entity.getType()) ||
isZeroParamFunctionType(entity.getType()))) {
ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage,
llvm::GlobalValue::DefaultVisibility,
llvm::GlobalValue::DefaultStorageClass})
.to(GV);
}
}
}
}
// Install the concrete definition if we have one.
if (definition && definition.hasInit()) {

View File

@@ -1416,13 +1416,13 @@ llvm::Module *IRGenModule::getModule() const {
return ClangCodeGen->GetModule();
}
bool IRGenModule::IsWellKnownBuiltinOrStructralType(CanType T) const {
bool IRGenModule::isWellKnownBuiltinOrStructuralType(CanType T) const {
if (T == Context.TheEmptyTupleType || T == Context.TheNativeObjectType ||
T == Context.TheBridgeObjectType || T == Context.TheRawPointerType ||
T == Context.getAnyObjectType())
return true;
if (auto IntTy = dyn_cast_or_null<BuiltinIntegerType>(T)) {
if (auto IntTy = dyn_cast<BuiltinIntegerType>(T)) {
auto Width = IntTy->getWidth();
if (Width.isPointerWidth())
return true;

View File

@@ -1203,7 +1203,7 @@ public:
ClassMetadataStrategy getClassMetadataStrategy(const ClassDecl *theClass);
bool IsWellKnownBuiltinOrStructralType(CanType type) const;
bool isWellKnownBuiltinOrStructuralType(CanType type) const;
private:
TypeConverter &Types;

View File

@@ -3681,7 +3681,7 @@ namespace {
//
// TODO: If a nominal type is in the same source file as we're currently
// emitting, we would be able to see its value witness table.
if (IGF.IGM.IsWellKnownBuiltinOrStructralType(t))
if (IGF.IGM.isWellKnownBuiltinOrStructuralType(t))
return emitFromValueWitnessTable(t);
// If the type is a singleton aggregate, the field's layout is equivalent