1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Suppress 'unreachable code' for 'System.Compiler' comparison branches

This commit is contained in:
Brian Fiete 2022-03-19 09:16:51 -07:00
parent 7cb92e4007
commit 87d403f72e
4 changed files with 52 additions and 2 deletions

View file

@ -113,6 +113,11 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
VisitChildNoRef(expr);
mResult = GetResult();
auto compilerVal = mModule->GetCompilerFieldValue(mResult);
if (compilerVal)
mResult = compilerVal;
if ((mResult) && (wantType != NULL))
{
auto typeInst = mResult.mType->ToTypeInstance();

View file

@ -12483,7 +12483,20 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo
{
BfTypedValue result = GetCompilerFieldValue(globalVar->mName);
if (result)
{
// We want to avoid 'unreachable code' issues from values that
// are technically constant but change depending on compilation context
if (mCurMethodState != NULL)
{
auto checkScope = mCurMethodState->mCurScope;
while (checkScope != NULL)
{
checkScope->mSupressNextUnreachable = true;
checkScope = checkScope->mPrevScope;
}
}
return result;
}
return GetDefaultTypedValue(typedValue.mType);
}
}
@ -14577,6 +14590,32 @@ BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str)
return BfTypedValue();
}
BfTypedValue BfModule::GetCompilerFieldValue(BfTypedValue typedValue)
{
if (!typedValue.IsAddr())
return BfTypedValue();
if (typedValue.mValue.IsConst())
{
auto constantValue = mBfIRBuilder->GetConstant(typedValue.mValue);
if (constantValue != NULL)
{
if (constantValue->mConstType == BfConstType_GlobalVar)
{
auto globalVar = (BfGlobalVar*)constantValue;
if (globalVar->mName[0] == '#')
{
BfTypedValue result = GetCompilerFieldValue(globalVar->mName);
return result;
}
}
}
}
return BfTypedValue();
}
BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
{
BfIRValue globalValue;

View file

@ -435,6 +435,7 @@ public:
bool mIsDeferredBlock;
bool mAllowVariableDeclarations;
bool mInInitBlock;
bool mSupressNextUnreachable;
BfMixinState* mMixinState;
BfBlock* mAstBlock;
BfAstNode* mCloseNode;
@ -470,6 +471,7 @@ public:
mHadOuterDynStack = false;
mHadScopeValueRetain = false;
mIsDeferredBlock = false;
mSupressNextUnreachable = false;
mAllowTargeting = true;
mAllowVariableDeclarations = true;
mInInitBlock = false;
@ -1038,7 +1040,7 @@ public:
bool mMayNeedThisAccessCheck;
bool mLeftBlockUncond; // Definitely left block. mHadReturn also sets mLeftBlock
bool mLeftBlockCond; // May have left block.
bool mInPostReturn; // Unreachable code
bool mInPostReturn; // Unreachable code
bool mCrossingMixin; // ie: emitting dtors in response to a return in a mixin
bool mNoBind;
bool mInConditionalBlock; // IE: RHS of ((A) && (B)), indicates an allocation in 'B' won't be dominated by a dtor, for example
@ -1691,6 +1693,7 @@ public:
BfIRValue GetInterfaceSlotNum(BfTypeInstance* ifaceType);
void HadSlotCountDependency();
BfTypedValue GetCompilerFieldValue(const StringImpl& str);
BfTypedValue GetCompilerFieldValue(const BfTypedValue typedVal);
BfTypedValue ReferenceStaticField(BfFieldInstance* fieldInstance);
int GetFieldDataIdx(BfTypeInstance* typeInst, int fieldIdx, const char* fieldName = NULL);
BfTypedValue GetThis(bool markUsing = true);

View file

@ -3453,7 +3453,8 @@ void BfModule::VisitCodeBlock(BfBlock* block)
if ((!hadUnreachableCode) && (!mCurMethodState->mInPostReturn))
{
Warn(BfWarning_CS0162_UnreachableCode, "Unreachable code", child);
if ((mCurMethodState->mCurScope == NULL) || (!mCurMethodState->mCurScope->mSupressNextUnreachable))
Warn(BfWarning_CS0162_UnreachableCode, "Unreachable code", child);
hadUnreachableCode = true;
prevInsertBlock = mBfIRBuilder->GetInsertBlock();
@ -3462,6 +3463,8 @@ void BfModule::VisitCodeBlock(BfBlock* block)
mBfIRBuilder->mIgnoreWrites = true;
}
}
if ((mCurMethodState != NULL) && (mCurMethodState->mCurScope != NULL))
mCurMethodState->mCurScope->mSupressNextUnreachable = false;
if (itr.IsLast())
{