Handled the case where fixup happened recursively when structs contained pointers in a loop larger than one struct. See description for example
Example: ```typedef struct bar bar; struct foo { bar* Bar; }; struct bar { foo* Foo; };``` Cases like this (and cases with more structs in between, which would have caused the same problem) were causing infinite Fixup recursion, so we just ignore fixup needs on all pointers, instead defaulting to just knowing the size of all pointers regardless of type.
This commit is contained in:
parent
9a228d22ba
commit
22c6fe15b6
|
@ -296,14 +296,27 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
|||
{
|
||||
type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex);
|
||||
|
||||
// NOTE(Peter): This signals a nested pointer to an address of the
|
||||
// same type as the one we are parsing now. In that case, the size
|
||||
// also hasn't been determined yet, but we know the size of the member
|
||||
// is just a pointer (32 or 64 bits).
|
||||
// For example, this would go into an infinite recursion without the case
|
||||
// of StructIndex != Member->TypeIndex:
|
||||
// NOTE(Peter): There are a lot of cases where struct members which are pointers
|
||||
// to other structs cause interesting behavior here.
|
||||
// For example:
|
||||
// struct foo { foo* Next; }
|
||||
if (MemberTypeDef->Size == 0 && StructIndex != Member->TypeIndex)
|
||||
// could cause infinite loops if we try and fixup all structs with a size of 0
|
||||
// which would happen in this case, because we wouldn't have parsed foo's size
|
||||
// yet, but would begin fixing up foo because of the type of Next
|
||||
// Another example:
|
||||
// typedef struct bar bar;
|
||||
// struct foo { bar* Bar; }
|
||||
// struct bar { foo* Foo; }
|
||||
// causes the exact same problem, but we cant detect it by just excluding
|
||||
// fixing up StructIndex recursively.
|
||||
//
|
||||
// TL;DR
|
||||
// The solution I've chosen to go with is just exclude all pointer members from
|
||||
// causing recursive fixups. Those types should be fixed up at some point in the
|
||||
// process, and we already know how big a pointer is in memory, no matter the type
|
||||
if (!Member->Pointer)
|
||||
{
|
||||
if (MemberTypeDef->Size == 0)
|
||||
{
|
||||
if (MemberTypeDef->Type == TypeDef_Struct)
|
||||
{
|
||||
|
@ -324,6 +337,7 @@ FixUpStructSize (s32 StructIndex, type_table TypeTable)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 MemberSize = CalculateStructMemberSize(*Member, *MemberTypeDef);
|
||||
SizeAcc += MemberSize;
|
||||
|
|
Loading…
Reference in New Issue