- fixed: only explicit class type casts must obey strict namespace rules, i.e. only '(class<type>)(variable_to_cast)'

The general rule is as follows: A class name as a string will always be looked up fully, even if the class name gets shadows by another variable because strings are not identifiers.
It is only class names as identifiers that must obey the rule that if it is not known yet or hidden by something else that it may not be found to ensure that the older variable does not take over the name if it gets reused.
This commit is contained in:
Christoph Oelckers 2017-01-24 10:04:46 +01:00
parent 17ed23bfcc
commit c12dfd7e4d
3 changed files with 12 additions and 8 deletions

View file

@ -1613,7 +1613,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
}
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
{
FxExpression *x = new FxClassTypeCast(static_cast<PClassPointer*>(ValueType), basex);
FxExpression *x = new FxClassTypeCast(static_cast<PClassPointer*>(ValueType), basex, Explicit);
x = x->Resolve(ctx);
basex = nullptr;
delete this;
@ -4412,7 +4412,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
if (left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
{
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left);
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left, false);
ClassCheck = true;
}
else
@ -4420,7 +4420,7 @@ FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject)), false);
ClassCheck = false;
}
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right);
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right, false);
RESOLVE(left, ctx);
RESOLVE(right, ctx);
@ -9922,12 +9922,13 @@ VMFunction *FxReturnStatement::GetDirectFunction()
//
//==========================================================================
FxClassTypeCast::FxClassTypeCast(PClassPointer *dtype, FxExpression *x)
FxClassTypeCast::FxClassTypeCast(PClassPointer *dtype, FxExpression *x, bool explicitily)
: FxExpression(EFX_ClassTypeCast, x->ScriptPosition)
{
ValueType = dtype;
desttype = dtype->ClassRestriction;
basex=x;
Explicit = explicitily;
}
//==========================================================================
@ -9991,7 +9992,9 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
if (clsname != NAME_None)
{
cls = FindClassType(clsname, ctx);
if (Explicit) cls = FindClassType(clsname, ctx);
else cls = PClass::FindClass(clsname);
if (cls == nullptr)
{
/* lax */
@ -10141,7 +10144,7 @@ FxExpression *FxClassPtrCast::Resolve(FCompileContext &ctx)
}
else if (basex->ValueType == TypeString || basex->ValueType == TypeName)
{
FxExpression *x = new FxClassTypeCast(to, basex);
FxExpression *x = new FxClassTypeCast(to, basex, true);
basex = nullptr;
delete this;
return x->Resolve(ctx);

View file

@ -1913,10 +1913,11 @@ class FxClassTypeCast : public FxExpression
{
PClass *desttype;
FxExpression *basex;
bool Explicit;
public:
FxClassTypeCast(PClassPointer *dtype, FxExpression *x);
FxClassTypeCast(PClassPointer *dtype, FxExpression *x, bool explicitly);
~FxClassTypeCast();
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);

View file

@ -197,7 +197,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type)
sc.SetEscape(true);
sc.MustGetString();
sc.SetEscape(false);
x = new FxClassTypeCast(static_cast<PClassPointer *>(type), new FxConstant(FName(sc.String), sc));
x = new FxClassTypeCast(static_cast<PClassPointer *>(type), new FxConstant(FName(sc.String), sc), false);
}
else
{