mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
Implemented a read check between ui/play/data fields with a meaningful error
This commit is contained in:
parent
a7a4406bb1
commit
a2f3d8511d
2 changed files with 16 additions and 7 deletions
|
@ -6718,8 +6718,6 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
||||||
// [ZZ] plain data "inherits" scope of whatever it was defined in.
|
// [ZZ] plain data "inherits" scope of whatever it was defined in.
|
||||||
if (bWritable) // don't do complex checks on early fail
|
if (bWritable) // don't do complex checks on early fail
|
||||||
{
|
{
|
||||||
if (ctx.Function && FString(ctx.Function->SymbolName) == FString("DrawPowerup"))
|
|
||||||
Printf("field type = %d\n", BarrierSide);
|
|
||||||
int outerflags = 0;
|
int outerflags = 0;
|
||||||
if (ctx.Function)
|
if (ctx.Function)
|
||||||
outerflags = ctx.Function->Variants[0].Flags;
|
outerflags = ctx.Function->Variants[0].Flags;
|
||||||
|
@ -6748,7 +6746,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))
|
if (!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))
|
||||||
|| !static_cast<PPointer *>(classx->ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(AActor)))
|
|| !static_cast<PPointer *>(classx->ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(AActor)))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
|
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type");
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -6759,7 +6757,18 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// [ZZ] support magic
|
// [ZZ] support magic
|
||||||
BarrierSide = FScopeBarrier::SideFromFlags(membervar->Flags);
|
int outerflags = 0;
|
||||||
|
if (ctx.Function)
|
||||||
|
outerflags = ctx.Function->Variants[0].Flags;
|
||||||
|
FScopeBarrier scopeBarrier(outerflags, membervar->Flags, membervar->SymbolName.GetChars());
|
||||||
|
if (!scopeBarrier.readable)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "%s", scopeBarrier.readerror.GetChars());
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BarrierSide = scopeBarrier.sidelast;
|
||||||
if (classx->ExprType == EFX_StructMember || classx->ExprType == EFX_ClassMember)
|
if (classx->ExprType == EFX_StructMember || classx->ExprType == EFX_ClassMember)
|
||||||
{
|
{
|
||||||
FxStructMember* pmember = (FxStructMember*)classx;
|
FxStructMember* pmember = (FxStructMember*)classx;
|
||||||
|
@ -6772,7 +6781,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
||||||
if (ptrtype == nullptr || !ptrtype->PointedType->IsKindOf(RUNTIME_CLASS(PStruct)))
|
if (ptrtype == nullptr || !ptrtype->PointedType->IsKindOf(RUNTIME_CLASS(PStruct)))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Member variable requires a struct or class object.");
|
ScriptPosition.Message(MSG_ERROR, "Member variable requires a struct or class object");
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -6826,7 +6835,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
if (!(classx->RequestAddress(ctx, &AddressWritable)))
|
if (!(classx->RequestAddress(ctx, &AddressWritable)))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "unable to dereference left side of %s", membervar->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_ERROR, "Unable to dereference left side of %s", membervar->SymbolName.GetChars());
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ struct FScopeBarrier
|
||||||
if ((sideto == Side_UI) != (sidefrom == Side_UI)) // only ui -> ui is readable
|
if ((sideto == Side_UI) != (sidefrom == Side_UI)) // only ui -> ui is readable
|
||||||
{
|
{
|
||||||
readable = false;
|
readable = false;
|
||||||
readerror.Format("Can't read %s field %s from %s context", StringFromSide(sideto), StringFromSide(sidefrom));
|
readerror.Format("Can't read %s field %s from %s context", StringFromSide(sideto), name, StringFromSide(sidefrom));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readable)
|
if (!readable)
|
||||||
|
|
Loading…
Reference in a new issue