瀏覽代碼

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

Brian Fiete 3 年之前
父節點
當前提交
87d403f72e

+ 5 - 0
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();

+ 39 - 0
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;

+ 4 - 1
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);

+ 4 - 1
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())
 		{