1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Disallowed cast from func constraint to void* or delegate to object

This commit is contained in:
Brian Fiete 2021-12-15 08:42:11 -05:00
parent 7b58863563
commit bb6c59e39e

View file

@ -11513,29 +11513,37 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
{ {
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance(); auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
if ((constraintTypeInst != NULL) && (constraintTypeInst->IsDelegateOrFunction()))
{ {
// Enum->int // Could be a methodref - can't cast to anything else
if ((explicitCast) && (toType->IsInteger()))
return typedVal.mValue;
} }
BfTypedValue fromTypedValue;
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
fromTypedValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint, false, BfDefaultValueKind_Undef);
else else
fromTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), genericParamInst->mTypeConstraint, genericParamInst->mTypeConstraint->IsValueType());
auto result = CastToValue(srcNode, fromTypedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
if (result)
{ {
if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate())) if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
{ {
// Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc // Enum->int
Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode); if ((explicitCast) && (toType->IsInteger()))
return BfIRValue(); return typedVal.mValue;
}
BfTypedValue fromTypedValue;
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
fromTypedValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint, false, BfDefaultValueKind_Undef);
else
fromTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), genericParamInst->mTypeConstraint, genericParamInst->mTypeConstraint->IsValueType());
auto result = CastToValue(srcNode, fromTypedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
if (result)
{
if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate()))
{
// Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc
Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
return BfIRValue();
}
return result;
} }
return result;
} }
} }