diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index 26272b9f..b5d18930 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -461,6 +461,18 @@ int BfIRConstHolder::IsZero(BfIRValue value) return -1; } +bool BfIRConstHolder::IsConstValue(BfIRValue value) +{ + auto constant = GetConstant(value); + if (constant == NULL) + return false; + + if (constant->mConstType == BfConstType_GlobalVar) + return false; + + return true; +} + int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) { auto constLHS = GetConstant(lhs); diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 8233175c..bdaf5373 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -948,6 +948,7 @@ public: BfConstant* GetConstant(BfIRValue id); bool TryGetBool(BfIRValue id, bool& boolVal); int IsZero(BfIRValue val); + bool IsConstValue(BfIRValue val); int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true //void WriteConstant(void* data, BeConstant* constVal); @@ -970,7 +971,7 @@ public: BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); bool WriteConstant(BfIRValue val, void* ptr, BfType* type); - BfIRValue ReadConstant(void* ptr, BfType* type); + BfIRValue ReadConstant(void* ptr, BfType* type); }; enum BfIRPopulateType diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 4ef37dfd..77bab66f 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -13510,7 +13510,15 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // .. and we can convert the constraint's toType to OUR toType then we're good auto opToVal = genericParam->mExternType; if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator)) - return mBfIRBuilder->GetFakeVal(); + { + if (mBfIRBuilder->IsConstValue(typedVal.mValue)) + { + // Retain constness + return mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(toType)); + } + else + return mBfIRBuilder->GetFakeVal(); + } } } } @@ -13535,7 +13543,15 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // .. and we can convert the constraint's toType to OUR toType then we're good auto opToVal = genericParam->mExternType; if (CanCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType, BfCastFlags_NoConversionOperator)) - return mBfIRBuilder->GetFakeVal(); + { + if (mBfIRBuilder->IsConstValue(typedVal.mValue)) + { + // Retain constness + return mBfIRBuilder->GetUndefConstValue(mBfIRBuilder->MapType(toType)); + } + else + return mBfIRBuilder->GetFakeVal(); + } } } } diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 0e6195b1..b0e771fd 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -4409,6 +4409,9 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType if (bfType->IsTypedPrimitive()) return CreateConstant(module, ptr, bfType->GetUnderlyingType(), outType); + if (bfType->IsGenericParam()) + return irBuilder->GetUndefConstValue(irBuilder->MapType(bfType)); + if (bfType->IsTypeInstance()) { auto typeInst = bfType->ToTypeInstance();