diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 0e382806..84427248 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -4979,6 +4979,9 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe if (fieldDef->mIsVolatile) mIsVolatileReference = true; + if (fieldInstance->mCustomAttributes != NULL) + mModule->CheckErrorAttributes(fieldInstance->mOwner, NULL, fieldInstance, fieldInstance->mCustomAttributes, targetSrc); + if (isFailurePass) { if (mModule->GetCeDbgState() == NULL) @@ -6169,7 +6172,7 @@ void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstN { BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes(); if (customAttributes != NULL) - mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc); + mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, NULL, customAttributes, targetSrc); } BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags, BfType* origTargetType) @@ -6486,11 +6489,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } else if (mModule->mIsComptimeModule) { - if (methodInstance->mIsUnspecialized) - { - doConstReturn = true; - } - else + //TODO: This meant that unspecialized types were not even allowed to have Init methods that called into themselves +// if (methodInstance->mIsUnspecialized) +// { +// doConstReturn = true; +// } +// else { mModule->mCompiler->mCeMachine->QueueMethod(methodInstance, func); } @@ -15352,7 +15356,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (unresolvedTypeRef == NULL) unresolvedTypeRef = mModule->ResolveTypeRef(arrayTypeRef->mElementType); if (unresolvedTypeRef == NULL) - unresolvedTypeRef = mModule->mContext->mBfObjectType; + unresolvedTypeRef = mModule->GetPrimitiveType(BfTypeCode_Var); int dimensions = 1; @@ -15436,7 +15440,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs if (dimensions > 4) dimensions = 4; - if (!isRawArrayAlloc) + if ((!isRawArrayAlloc) && (!unresolvedTypeRef->IsVar())) arrayType = mModule->CreateArrayType(unresolvedTypeRef, dimensions); } @@ -22393,6 +22397,12 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, auto ptrType = mModule->CreatePointerType(mResult.mType); if (mResult.mType->IsValuelessType()) { + if (!mModule->IsInSpecializedSection()) + { + mModule->Warn(0, StrFormat("Operator '&' results in a sentinel address for zero-sized type '%s'", + mModule->TypeToString(mResult.mType).c_str()), opToken); + } + // Sentinel value auto val = mModule->mBfIRBuilder->CreateIntToPtr(mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), mModule->mBfIRBuilder->MapType(ptrType)); mResult = BfTypedValue(val, ptrType); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 42410b0a..69453b92 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -478,7 +478,8 @@ public: void EmitAppendAlign(int align, int sizeMultiple = 0) { - BF_ASSERT(align > 0); + if (align <= 1) + return; if (mIsFirstConstPass) mModule->mCurMethodInstance->mAppendAllocAlign = BF_MAX((int)mModule->mCurMethodInstance->mAppendAllocAlign, align); @@ -3387,7 +3388,7 @@ BfError* BfModule::Warn(int warningNum, const StringImpl& warning, BfAstNode* re return bfError; } -void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc) +void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc) { if (customAttributes == NULL) return; @@ -3414,7 +3415,9 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()) && (targetSrc != NULL)) { String err; - if (methodInstance != NULL) + if (fieldInstance != NULL) + err = StrFormat("'%s' is obsolete", FieldToString(fieldInstance).c_str()); + else if (methodInstance != NULL) err = StrFormat("'%s' is obsolete", MethodToString(methodInstance).c_str()); else err = StrFormat("'%s' is obsolete", TypeToString(typeInstance, BfTypeNameFlag_UseUnspecializedGenericParamNames).c_str()); @@ -3453,7 +3456,9 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty())) { String err; - if (methodInstance != NULL) + if (fieldInstance != NULL) + err += StrFormat("Method error: '", FieldToString(fieldInstance).c_str()); + else if (methodInstance != NULL) err += StrFormat("Method error: '", MethodToString(methodInstance).c_str()); else err += StrFormat("Type error: '", TypeToString(typeInstance, BfTypeNameFlag_UseUnspecializedGenericParamNames).c_str()); @@ -3469,7 +3474,9 @@ void BfModule::CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstan if ((customAttribute != NULL) && (!customAttribute->mCtorArgs.IsEmpty()) && (targetSrc != NULL)) { String err; - if (methodInstance != NULL) + if (fieldInstance != NULL) + err += StrFormat("Field warning: '", FieldToString(fieldInstance).c_str()); + else if (methodInstance != NULL) err += StrFormat("Method warning: '", MethodToString(methodInstance).c_str()); else err += StrFormat("Type warning: '", TypeToString(typeInstance, BfTypeNameFlag_UseUnspecializedGenericParamNames).c_str()); @@ -10022,6 +10029,9 @@ void BfModule::ValidateAllocation(BfType* type, BfAstNode* refNode) void BfModule::EmitAppendAlign(int align, int sizeMultiple) { + if (align <= 1) + return; + if (sizeMultiple == 0) sizeMultiple = align; if ((mCurMethodState->mCurAppendAlign != 0) && (mCurMethodState->mCurAppendAlign % align != 0)) @@ -11177,6 +11187,18 @@ bool BfModule::HasMixin(BfTypeInstance* typeInstance, const StringImpl& methodNa return BfModuleMethodInstance(); } +String BfModule::FieldToString(BfFieldInstance* fieldInstance) +{ + auto result = TypeToString(fieldInstance->mOwner); + result += "."; + auto fieldDef = fieldInstance->GetFieldDef(); + if (fieldDef != NULL) + result += fieldDef->mName; + else + result += "???"; + return result; +} + StringT<128> BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags, BfTypeVector* typeGenericArgs, BfTypeVector* methodGenericArgs) { auto methodDef = methodInst->mMethodDef; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 3c288f38..5234ce41 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1619,7 +1619,7 @@ public: BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL); BfError* FailAfter(const StringImpl& error, BfAstNode* refNode); BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false, bool showInSpecialized = false); - void CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc); + void CheckErrorAttributes(BfTypeInstance* typeInstance, BfMethodInstance* methodInstance, BfFieldInstance* fieldInstance, BfCustomAttributes* customAttributes, BfAstNode* targetSrc); void CheckRangeError(BfType* type, BfAstNode* refNode); bool CheckCircularDataError(bool failTypes = true); BfFileInstance* GetFileFromNode(BfAstNode* astNode); @@ -1653,6 +1653,7 @@ public: StringT<128> TypeToString(BfType* resolvedType, Array* genericMethodParamNameOverrides = NULL); StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array* genericMethodParamNameOverrides = NULL); void DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None, Array* genericMethodParamNameOverrides = NULL); + String FieldToString(BfFieldInstance* fieldInstance); StringT<128> MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags = BfMethodNameFlag_ResolveGenericParamNames, BfTypeVector* typeGenericArgs = NULL, BfTypeVector* methodGenericArgs = NULL); void pt(BfType* type); void pm(BfMethodInstance* type); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 39facad4..87811127 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -9803,7 +9803,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined) PopulateType(resolvedTypeRef); if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary())) - CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef); + CheckErrorAttributes(typeInstance, NULL, NULL, typeInstance->mCustomAttributes, typeRef); resolvedTypeRef = resolvedTypeRef->GetUnderlyingType(); if (resolvedTypeRef != NULL) typeInstance = resolvedTypeRef->ToTypeInstance(); @@ -9817,7 +9817,7 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy if ((!typeRef->IsTemporary()) && ((resolveFlags & BfResolveTypeRefFlag_FromIndirectSource) == 0)) { if (typeInstance->mCustomAttributes != NULL) - CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef); + CheckErrorAttributes(typeInstance, NULL, NULL, typeInstance->mCustomAttributes, typeRef); else if ((typeInstance->mTypeDef->mTypeDeclaration != NULL) && (typeInstance->mTypeDef->mTypeDeclaration->mAttributes != NULL)) { auto typeRefVerifyRequest = mContext->mTypeRefVerifyWorkList.Alloc(); @@ -15827,4 +15827,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF BFMODULE_FATAL(this, "Not implemented"); str += "???"; return; -} \ No newline at end of file +} + +