Procházet zdrojové kódy

Fixed stack overflow with inner type as base type

Brian Fiete před 5 roky
rodič
revize
797aa7cedc

+ 25 - 7
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -2227,6 +2227,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	SizedArray<BfInterfaceDecl, 8> interfaces;
 	HashSet<BfTypeInstance*> ifaceSet;
 
+	typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags | BfTypeRebuildFlag_ResolvingBase);
+
 	if (resolvedTypeRef == mContext->mBfObjectType)
 	{
 		baseType = NULL;
@@ -2326,7 +2328,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 					if (checkType->IsPrimitiveType())
 						Fail(StrFormat("Enum '%s' cannot be specified as '%s' because it has a payload",
 							TypeToString(typeInstance).c_str(), TypeToString(checkType).c_str()),
-							checkTypeRef);
+							checkTypeRef, true);
 					else
 						Fail("Enums cannot derive from other types", checkTypeRef);
 					continue;
@@ -2376,11 +2378,25 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 						baseTypeRef = checkTypeRef;
 						if (checkTypeInst != NULL)
 						{
-							baseType = checkTypeInst;
-							/*if ((resolvedTypeRef->IsBoxed()) && (baseType->IsValueType()))
+							auto checkOuter = checkTypeInst;
+							while (checkOuter != NULL)
 							{
-								baseType = CreateBoxedType(baseType);
-							}*/
+								if (checkOuter == typeInstance)
+								{
+									Fail(StrFormat("Type '%s' cannot be declare inner type '%s' as a base type",
+										TypeToString(typeInstance).c_str(),
+										TypeToString(checkTypeInst).c_str()), checkTypeRef, true);
+									checkTypeInst = NULL; 
+									break;
+								}
+								checkOuter = GetOuterType(checkOuter);
+							}
+						}
+
+
+						if (checkTypeInst != NULL)
+						{
+							baseType = checkTypeInst;
 						}
 					}
 				}
@@ -2434,11 +2450,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	}
 
 	if (!typeInstance->IsBoxed())
-	{		
+	{
 		BfType* outerType = GetOuterType(typeInstance);
 		if (outerType != NULL)
 		{
-			PopulateType(outerType, BfPopulateType_BaseType);
+			PopulateType(outerType, BfPopulateType_Identity);
 			AddDependency(outerType, typeInstance, BfDependencyMap::DependencyFlag_OuterType);
 		}
 	}
@@ -2509,6 +2525,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 		}
 	}
 
+	typeInstance->mRebuildFlags = (BfTypeRebuildFlags)(typeInstance->mRebuildFlags & ~BfTypeRebuildFlag_ResolvingBase);
+
 	if (populateType <= BfPopulateType_BaseType)
 		return;
 

+ 2 - 1
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -397,7 +397,8 @@ enum BfTypeRebuildFlags
 	BfTypeRebuildFlag_SpecializedByAutocompleteMethod = 0x200,
 	BfTypeRebuildFlag_UnderlyingTypeDeferred = 0x400,
 	BfTypeRebuildFlag_TypeDataSaved = 0x800,
-	BfTypeRebuildFlag_InTempPool = 0x1000
+	BfTypeRebuildFlag_InTempPool = 0x1000,
+	BfTypeRebuildFlag_ResolvingBase = 0x2000
 };
 
 class BfTypeDIReplaceCallback;