Implemented a read check between ui/play/data fields with a meaningful error

This commit is contained in:
ZZYZX 2017-02-17 22:46:18 +02:00
parent a7a4406bb1
commit a2f3d8511d
2 changed files with 16 additions and 7 deletions

View file

@ -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;
} }

View file

@ -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)