diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index c13ef408..ba84fd16 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -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(); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index ef617ede..8970f7ee 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -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; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index bea38ef4..bb4294dc 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -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); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 395bebfb..d67e2874 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -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()) {