don't allow backing types of string/array/map/etc to be referenced as actual types

This commit is contained in:
Ricardo Luís Vaz Silva 2025-03-02 15:19:43 -03:00
commit a0592816cd
7 changed files with 72 additions and 48 deletions

View file

@ -109,6 +109,8 @@ public:
EScopeFlags ScopeFlags = (EScopeFlags)0;
bool SizeKnown = true;
bool TypeInternal = false;
PType * LocalType = nullptr;
PType * SetLocalType(PType * LocalType) { this->LocalType = LocalType; return this; }

View file

@ -432,6 +432,7 @@ struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; }
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; }
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; }
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; }
struct_flags(X) ::= struct_flags(A) INTERNAL. { X.Flags = A.Flags | ZCC_Internal; }
struct_flags(X) ::= struct_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Version = C.String->GetChars(); }
opt_struct_body(X) ::= . { X = NULL; }

View file

@ -729,6 +729,8 @@ void ZCCCompiler::CreateStructTypes()
syms = &OutNamespace->Symbols;
}
if (s->NodeName() == NAME__ && fileSystem.GetFileContainer(Lump) == 0)
{
// This is just a container for syntactic purposes.
@ -743,11 +745,17 @@ void ZCCCompiler::CreateStructTypes()
{
s->strct->Type = NewStruct(s->NodeName(), outer, false, AST.FileNo);
}
if (s->strct->Flags & ZCC_Version)
{
s->strct->Type->mVersion = s->strct->Version;
}
if (s->strct->Flags & ZCC_Internal)
{
s->strct->Type->TypeInternal = true;
}
auto &sf = s->Type()->ScopeFlags;
if (mVersion >= MakeVersion(2, 4, 0))
{
@ -809,6 +817,12 @@ void ZCCCompiler::CreateClassTypes()
PClass *parent;
auto ParentName = c->cls->ParentName;
if (c->cls->Flags & ZCC_Internal)
{
Error(c->cls, "'Internal' not allowed for classes");
}
// The parent exists, we may create a type for this class
if (ParentName != nullptr && ParentName->SiblingNext == ParentName)
{
parent = PClass::FindClass(ParentName->Id);
@ -845,7 +859,6 @@ void ZCCCompiler::CreateClassTypes()
Error(c->cls, "Class '%s' cannot extend sealed class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars());
}
// The parent exists, we may create a type for this class
if (c->cls->Flags & ZCC_Native)
{
// If this is a native class, its own type must also already exist and not be a runtime class.
@ -1868,7 +1881,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
{
Error(field, "%s: @ not allowed for user scripts", name.GetChars());
}
retval = ResolveUserType(btype, btype->UserType, outertype? &outertype->Symbols : nullptr, true);
retval = ResolveUserType(outertype, btype, btype->UserType, outertype? &outertype->Symbols : nullptr, true);
break;
case ZCC_UserType:
@ -1898,7 +1911,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
default:
retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
retval = ResolveUserType(outertype, btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
break;
}
break;
@ -2153,7 +2166,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
* @param nativetype Distinguishes between searching for a native type or a user type.
* @returns the PType found for this user type
*/
PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *symt, bool nativetype)
PType *ZCCCompiler::ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *symt, bool nativetype)
{
// Check the symbol table for the identifier.
PSymbol *sym = nullptr;
@ -2170,10 +2183,18 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSy
return TypeError;
}
//only allow references to internal types inside internal types
if (ptype->TypeInternal && !outertype->TypeInternal)
{
Error(type, "Type %s not accessible", FName(type->UserType->Id).GetChars());
return TypeError;
}
if (id->SiblingNext != type->UserType)
{
assert(id->SiblingNext->NodeType == AST_Identifier);
ptype = ResolveUserType(
outertype,
type,
static_cast<ZCC_Identifier *>(id->SiblingNext),
&ptype->Symbols,

View file

@ -134,7 +134,7 @@ protected:
FString FlagsToString(uint32_t flags);
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize);
PType *ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *sym, bool nativetype);
PType *ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *sym, bool nativetype);
static FString UserTypeName(ZCC_BasicType *type);
TArray<ZCC_StructWork *> OrderStructs();
void AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *struct_def);