Browse Source

Fixed enum comparison to int when there's an int conversion operator

Brian Fiete 7 months ago
parent
commit
dfbb09a8ac

+ 10 - 4
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -923,16 +923,22 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo
 		addNonStatic = true;
 
 	auto activeTypeDef = mModule->GetActiveTypeDef();
+	
+#define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic))
+
+	mModule->PopulateType(typeInst, BfPopulateType_Data);
 
 	if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum()) && (allowImplicitThis))
 	{
 		AddEntry(AutoCompleteEntry("value", "_"), filter);
 	}
 
-#define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic))
-
-	mModule->PopulateType(typeInst, BfPopulateType_Data);
-
+	if ((typeInst->IsEnum()) && (typeInst->IsTypedPrimitive()))
+	{	
+		if (typeInst->IsTypedPrimitive())
+			AddEntry(AutoCompleteEntry("valuetype", "UnderlyingType"), filter);		
+	}
+	 
 	BfShow checkShow = (startType == typeInst) ? BfShow_Hide : BfShow_HideIndirect;
 
 	BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;

+ 27 - 7
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -24208,6 +24208,7 @@ void BfExprEvaluator::AddStrings(const BfTypedValue& leftValue, const BfTypedVal
 void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue)
 {
 	bool noClassify = (flags & BfBinOpFlag_NoClassify) != 0;
+	bool forceRightType = (flags & BfBinOpFlag_ForceRightType) != 0;
 	bool forceLeftType = (flags & BfBinOpFlag_ForceLeftType) != 0;
 	bool deferRight = (flags & BfBinOpFlag_DeferRight) != 0;
 
@@ -24271,7 +24272,11 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 	}
 
 	auto resultType = leftValue.mType;
-	if (!forceLeftType)
+	if (forceRightType)
+	{
+		resultType = rightValue.mType;		
+	}
+	else if (!forceLeftType)
 	{
 		bool handled = false;
 
@@ -24974,7 +24979,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 			AddStrings(leftValue, rightValue, opToken);
 			return;
 		}
-
+		
 		//TODO: Allow all pointer comparisons, but only allow SUBTRACTION between equal pointer types
 		if ((binaryOp == BfBinaryOp_Subtract) || (binaryOp == BfBinaryOp_OverflowSubtract))
 		{
@@ -25162,11 +25167,26 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
 			}
 
 			if (needsOtherCast)
-			{
-				// The only purpose of this cast is to potentially throw a casting error
-				BfIRValue otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
-				if (!otherCastResult)
-					return;
+			{				
+				BfCastFlags castFlags = (BfCastFlags)((explicitCast ? BfCastFlags_Explicit : BfCastFlags_None) | BfCastFlags_SilentFail);
+				BfIRValue otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
+				if (!otherCastResult)					
+				{
+					// We picked the wrong type, try the other one...
+					if (mModule->CanCast(*resultTypedValue, otherType))
+					{
+						BfBinOpFlags newFlags = flags;
+						if (otherTypedValue == &leftValue)
+							newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_ForceRightType & ~BfBinOpFlag_DeferRight);
+						else
+							newFlags = (BfBinOpFlags)(flags | BfBinOpFlag_ForceRightType & ~BfBinOpFlag_ForceLeftType & ~BfBinOpFlag_DeferRight);
+						return PerformBinaryOperation(leftExpression, rightExpression, binaryOp, opToken, newFlags, leftValue, rightValue);
+					}
+
+					// Do again but with an error
+					castFlags = (BfCastFlags)(castFlags & ~BfCastFlags_SilentFail);
+					otherCastResult = mModule->CastToValue(otherTypeSrc, *otherTypedValue, resultType, castFlags);
+				}
 			}
 		}
 

+ 4 - 3
IDEHelper/Compiler/BfExprEvaluator.h

@@ -395,9 +395,10 @@ enum BfBinOpFlags
 	BfBinOpFlag_None = 0,
 	BfBinOpFlag_NoClassify = 1,
 	BfBinOpFlag_ForceLeftType = 2,
-	BfBinOpFlag_IgnoreOperatorWithWrongResult = 4,
-	BfBinOpFlag_IsConstraintCheck = 8,
-	BfBinOpFlag_DeferRight = 0x10
+	BfBinOpFlag_ForceRightType = 4,
+	BfBinOpFlag_IgnoreOperatorWithWrongResult = 8,
+	BfBinOpFlag_IsConstraintCheck = 0x10,
+	BfBinOpFlag_DeferRight = 0x20
 };
 
 class BfExprEvaluator : public BfStructuralVisitor

+ 0 - 8
IDEHelper/Compiler/CeMachine.cpp

@@ -6886,14 +6886,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 				SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurModule->mCurTypeInstance, mCallerTypeInstance);
 				SetAndRestoreValue<bool> emitIgnoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, ignoreWrites.mPrevVal);
 
-// 				int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
-// 				String emitStr;
-// 				if (!GetStringFromAddr(strInstAddr, emitStr))
-// 				{
-// 					_Fail("Invalid String");
-// 					return false;
-// 				}
-
 				addr_ce strViewPtr = *(addr_ce*)((uint8*)stackPtr);
 				String emitStr;
 				if (!GetStringFromStringView(strViewPtr, emitStr))