Added proper handling for default parameter values of virtual overrides

Due to how the VM handles default parameters, these must always be identical to the parent to prevent undefined behavior.
So now, if such parameters are encountered, the compiler will either abort (for script version >= 3.3) or print a warning (for older versions.)
Any defaults being specified for older versions will be ignored, though, and the defaults of the parent function be copied to the override.
This commit is contained in:
Christoph Oelckers 2018-03-12 10:19:16 +01:00
parent c01554c6c8
commit def5e1d61b

View file

@ -2494,6 +2494,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
bool hasoptionals = false;
if (p != nullptr)
{
bool overridemsg = false;
do
{
int elementcount = 1;
@ -2528,6 +2529,22 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
{
flags |= VARF_Optional;
hasoptionals = true;
if ((varflags & VARF_Override) && !overridemsg)
{
// This is illegal, but in older compilers wasn't checked, so there it has to be demoted to a warning.
// Virtual calls always need to get their defaults from the base virtual method.
if (mVersion >= MakeVersion(3, 3))
{
Error(p, "Default values for parameter of virtual override not allowed");
}
else
{
Warn(p, "Default values for parameter of virtual override will be ignored!");
}
overridemsg = true;
}
FxExpression *x = new FxTypeCast(ConvertNode(p->Default), type, false);
FCompileContext ctx(OutNamespace, c->Type(), false);
@ -2721,6 +2738,13 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
clstype->Virtuals[vindex] = sym->Variants[0].Implementation;
sym->Variants[0].Implementation->VirtualIndex = vindex;
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
// Defaults must be identical to parent class
if (parentfunc->Variants[0].Implementation->DefaultArgs.Size() > 0)
{
Printf("Copying defaults from %s to %s\n", parentfunc->Variants[0].Implementation->PrintableName.GetChars(), sym->Variants[0].Implementation->PrintableName.GetChars());
sym->Variants[0].Implementation->DefaultArgs = parentfunc->Variants[0].Implementation->DefaultArgs;
}
}
}
else