Add warning for static buffer overflow
This commit is contained in:
parent
755c9234e1
commit
611f672b81
|
@ -40,6 +40,7 @@ enum ErrorID
|
|||
EWARN_NUMERIC_0_USED_AS_NULLPTR,
|
||||
EWARN_FLOAT_TO_INT,
|
||||
EWARN_UNDEFINED_POINTER_ARITHMETIC,
|
||||
EWARN_INVALID_VALUE_RANGE,
|
||||
|
||||
EERR_GENERIC = 3000,
|
||||
EERR_FILE_NOT_FOUND,
|
||||
|
|
|
@ -118,6 +118,11 @@ void IntegerValueRange::LimitMaxWeak(int64 value)
|
|||
}
|
||||
}
|
||||
|
||||
bool IntegerValueRange::IsInvalid(void) const
|
||||
{
|
||||
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue > mMaxValue;
|
||||
}
|
||||
|
||||
bool IntegerValueRange::IsConstant(void) const
|
||||
{
|
||||
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue;
|
||||
|
@ -8077,6 +8082,12 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
|
||||
vr.mMaxValue <<= ins->mSrc[0].mIntConst;
|
||||
vr.mMinValue <<= ins->mSrc[0].mIntConst;
|
||||
|
||||
if (ins->mDst.mType == IT_INT8 && vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMaxValue > 255)
|
||||
{
|
||||
vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].IsUByte() && ins->mSrc[0].mRange.mMaxValue < 16)
|
||||
{
|
||||
|
@ -10519,7 +10530,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
|||
nins->mSrc[0] = ains->mSrc[1];
|
||||
nins->mDst.mTemp = spareTemps++;
|
||||
nins->mDst.mType = IT_INT16;
|
||||
nins->mDst.mRange = pins->mDst.mRange;
|
||||
nins->mDst.mRange = ains->mSrc[1].mRange;
|
||||
mInstructions.Insert(i, nins);
|
||||
|
||||
ins->mSrc[0] = nins->mDst;
|
||||
|
@ -19140,6 +19151,31 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals,
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::WarnInvalidValueRanges(void)
|
||||
{
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins = mInstructions[i];
|
||||
|
||||
for (int j = 0; j < ins->mNumOperands; j++)
|
||||
{
|
||||
if (ins->mSrc[j].mTemp >= 0 && ins->mSrc[j].mRange.IsInvalid())
|
||||
{
|
||||
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_INVALID_VALUE_RANGE, "Invalid value range");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->WarnInvalidValueRanges();
|
||||
if (mFalseJump) mFalseJump->WarnInvalidValueRanges();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
|
||||
{
|
||||
if (!mVisited)
|
||||
|
@ -19883,6 +19919,16 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void)
|
|||
mEntryBlock->WarnUsedUndefinedVariables();
|
||||
}
|
||||
|
||||
void InterCodeProcedure::WarnInvalidValueRanges(void)
|
||||
{
|
||||
ResetEntryBlocks();
|
||||
ResetVisited();
|
||||
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->WarnInvalidValueRanges();
|
||||
}
|
||||
|
||||
|
||||
void InterCodeProcedure::TempForwarding(bool reverse, bool checkloops)
|
||||
{
|
||||
|
@ -20503,7 +20549,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "addGameObjectCannon");
|
||||
CheckFunc = !strcmp(mIdent->mString, "opp::ostream::operator<<");
|
||||
CheckCase = false;
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
@ -21409,6 +21455,8 @@ void InterCodeProcedure::Close(void)
|
|||
BuildTraces(false, false, true);
|
||||
DisassembleDebug("Final Merged basic blocks");
|
||||
|
||||
WarnInvalidValueRanges();
|
||||
|
||||
BuildDataFlowSets();
|
||||
|
||||
MapCallerSavedTemps();
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
void SetLimit(int64 minValue, int64 maxValue);
|
||||
|
||||
bool IsConstant(void) const;
|
||||
bool IsInvalid(void) const;
|
||||
|
||||
void LimitMin(int64 value);
|
||||
void LimitMax(int64 value);
|
||||
|
@ -619,6 +620,7 @@ public:
|
|||
bool SameExitCode(const InterCodeBasicBlock* block) const;
|
||||
|
||||
void WarnUsedUndefinedVariables(void);
|
||||
void WarnInvalidValueRanges(void);
|
||||
void CheckValueReturn(void);
|
||||
void CheckNullptrDereference(void);
|
||||
|
||||
|
@ -732,6 +734,7 @@ protected:
|
|||
void MergeBasicBlocks(void);
|
||||
void CheckUsedDefinedTemps(void);
|
||||
void WarnUsedUndefinedVariables(void);
|
||||
void WarnInvalidValueRanges(void);
|
||||
void PropagateMemoryAliasingInfo(void);
|
||||
void MoveConditionsOutOfLoop(void);
|
||||
|
||||
|
|
|
@ -9245,6 +9245,14 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
|
||||
int sreg0 = ins->mSrc[sop0].mTemp < 0 ? -1 : BC_REG_TMP + proc->mTempOffset[ins->mSrc[sop0].mTemp];
|
||||
|
||||
if (ins->mSrc[sop1].mTemp >= 0 && ins->mSrc[sop0].mTemp >= 0 && sins1 && sins1 == sins0)
|
||||
{
|
||||
LoadValueToReg(proc, sins1, BC_REG_ACCU, nullptr, nullptr);
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitx")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_ZP_32_X, BC_REG_ACCU));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ins->mSrc[sop1].mTemp < 0)
|
||||
{
|
||||
union { float f; unsigned int v; } cc;
|
||||
|
@ -9326,16 +9334,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitx")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_ZP_32_X, sreg0));
|
||||
#if 0
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 2));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 3));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -49481,25 +49480,42 @@ NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* i
|
|||
return mRuntime[i];
|
||||
}
|
||||
|
||||
static inline bool isfparam(const NativeCodeInstruction & cins, const NativeCodeInstruction & ins)
|
||||
{
|
||||
if (cins.mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
if (ins.mAddress >= BC_REG_WORK && ins.mAddress < BC_REG_WORK + 8)
|
||||
return true;
|
||||
if (ins.mAddress >= BC_REG_ACCU && ins.mAddress < BC_REG_ACCU + 4)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ins.mAddress >= BC_REG_FPARAMS && ins.mAddress < BC_REG_FPARAMS_END)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NativeCodeGenerator::RegisterFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||
{
|
||||
LinkerObject* lo = block->mIns[at].mLinkerObject;
|
||||
if (lo->mIdent && !(block->mIns[at].mFlags & NCIF_USE_ZP_32_X))
|
||||
if (lo->mIdent)// && !(block->mIns[at].mFlags & NCIF_USE_ZP_32_X))
|
||||
{
|
||||
uint64 fpmask = 0;
|
||||
|
||||
int i = at;
|
||||
while (i >= 2 &&
|
||||
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
||||
block->mIns[i - 1].mAddress >= BC_REG_FPARAMS && block->mIns[i - 1].mAddress < BC_REG_FPARAMS_END &&
|
||||
isfparam(block->mIns[at], block->mIns[i - 1]) &&
|
||||
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
||||
{
|
||||
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
||||
{
|
||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_FPARAMS)))
|
||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_WORK)))
|
||||
break;
|
||||
}
|
||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_FPARAMS);
|
||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_WORK);
|
||||
|
||||
i -= 2;
|
||||
}
|
||||
|
@ -49508,16 +49524,18 @@ void NativeCodeGenerator::RegisterFunctionCall(NativeCodeBasicBlock* block, int
|
|||
{
|
||||
FunctionCall* ncp = new FunctionCall();
|
||||
ncp->mLinkerObject = lo;
|
||||
ncp->mOffset = block->mIns[at].mAddress;
|
||||
|
||||
ncp->mProxyObject = nullptr;
|
||||
ncp->mCount = 1;
|
||||
while (i < at)
|
||||
{
|
||||
ncp->mIns[block->mIns[i + 1].mAddress - BC_REG_FPARAMS] = block->mIns[i];
|
||||
ncp->mIns[block->mIns[i + 1].mAddress - BC_REG_WORK] = block->mIns[i];
|
||||
i += 2;
|
||||
}
|
||||
|
||||
FunctionCall* cp = mFunctionCalls;
|
||||
while (cp && cp->mLinkerObject != ncp->mLinkerObject)
|
||||
while (cp && (cp->mLinkerObject != ncp->mLinkerObject || cp->mOffset != ncp->mOffset))
|
||||
cp = cp->mNext;
|
||||
if (!cp)
|
||||
{
|
||||
|
@ -49556,15 +49574,15 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
|||
int i = at;
|
||||
while (i >= 2 &&
|
||||
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
||||
block->mIns[i - 1].mAddress >= BC_REG_FPARAMS && block->mIns[i - 1].mAddress < BC_REG_FPARAMS_END &&
|
||||
isfparam(block->mIns[at], block->mIns[i - 1]) &&
|
||||
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
||||
{
|
||||
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
||||
{
|
||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_FPARAMS)))
|
||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_WORK)))
|
||||
break;
|
||||
}
|
||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_FPARAMS);
|
||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_WORK);
|
||||
|
||||
i -= 2;
|
||||
}
|
||||
|
@ -49573,15 +49591,16 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
|||
{
|
||||
FunctionCall ncp;
|
||||
ncp.mLinkerObject = lo;
|
||||
ncp.mOffset = block->mIns[at].mAddress;
|
||||
int j = i;
|
||||
while (i < at)
|
||||
{
|
||||
ncp.mIns[block->mIns[i + 1].mAddress - BC_REG_FPARAMS] = block->mIns[i];
|
||||
ncp.mIns[block->mIns[i + 1].mAddress - BC_REG_WORK] = block->mIns[i];
|
||||
i += 2;
|
||||
}
|
||||
|
||||
FunctionCall* cp = mFunctionCalls;
|
||||
while (cp && cp->mLinkerObject != ncp.mLinkerObject)
|
||||
while (cp && (cp->mLinkerObject != ncp.mLinkerObject || cp->mOffset != ncp.mOffset))
|
||||
cp = cp->mNext;
|
||||
if (cp)
|
||||
{
|
||||
|
@ -49607,7 +49626,7 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
|||
{
|
||||
while (j < at)
|
||||
{
|
||||
if (bcp->mIns[block->mIns[j + 1].mAddress - BC_REG_FPARAMS].mType != ASMIT_INV)
|
||||
if (bcp->mIns[block->mIns[j + 1].mAddress - BC_REG_WORK].mType != ASMIT_INV)
|
||||
{
|
||||
block->mIns[j + 0].mType = ASMIT_NOP; block->mIns[j + 0].mMode = ASMIM_IMPLIED;
|
||||
block->mIns[j + 1].mType = ASMIT_NOP; block->mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||
|
@ -49615,6 +49634,7 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
|||
j += 2;
|
||||
}
|
||||
block->mIns[j].mLinkerObject = bcp->mProxyObject;
|
||||
block->mIns[j].mAddress = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -49675,13 +49695,13 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
|||
|
||||
ocalls.Remove(besti);
|
||||
|
||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
||||
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||
{
|
||||
if (fi->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
||||
if (fi->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||
{
|
||||
if (!fi->mIns[i - BC_REG_FPARAMS].IsSame(fj->mIns[i - BC_REG_FPARAMS]))
|
||||
if (!fi->mIns[i - BC_REG_WORK].IsSame(fj->mIns[i - BC_REG_WORK]))
|
||||
{
|
||||
fi->mIns[i - BC_REG_FPARAMS].mType = ASMIT_INV;
|
||||
fi->mIns[i - BC_REG_WORK].mType = ASMIT_INV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49709,9 +49729,9 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
|||
ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType);
|
||||
|
||||
ExpandingArray<uint8> code;
|
||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
||||
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(ncp->mIns[i - BC_REG_FPARAMS]);
|
||||
NativeCodeInstruction& ins(ncp->mIns[i - BC_REG_WORK]);
|
||||
if (ins.mType == ASMIT_LDA)
|
||||
{
|
||||
switch (ins.mMode)
|
||||
|
@ -49792,7 +49812,7 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
|||
rl.mObject = ncp->mProxyObject;
|
||||
rl.mOffset = code.Size();
|
||||
rl.mRefObject = ncp->mLinkerObject;
|
||||
rl.mRefOffset = 0;
|
||||
rl.mRefOffset = ncp->mOffset;
|
||||
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
|
||||
ncp->mProxyObject->AddReference(rl);
|
||||
code.Push(0);
|
||||
|
@ -49818,8 +49838,8 @@ void NativeCodeGenerator::RegisterRuntime(const Ident* ident, LinkerObject* obje
|
|||
|
||||
bool NativeCodeGenerator::FunctionCall::IsSame(const FunctionCall* fc) const
|
||||
{
|
||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
||||
if (!mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
||||
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||
if (!mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -49828,11 +49848,11 @@ int NativeCodeGenerator::FunctionCall::Matches(const FunctionCall* fc) const
|
|||
{
|
||||
int match = 0;
|
||||
|
||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
||||
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||
{
|
||||
if (fc->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
||||
if (fc->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||
{
|
||||
if (!mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
||||
if (!mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||
return -1;
|
||||
match++;
|
||||
}
|
||||
|
@ -49845,11 +49865,11 @@ int NativeCodeGenerator::FunctionCall::PotentialMatches(const FunctionCall* fc)
|
|||
{
|
||||
int match = 0;
|
||||
|
||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
||||
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||
{
|
||||
if (fc->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
||||
if (fc->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||
{
|
||||
if (mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
||||
if (mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||
match++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -840,7 +840,7 @@ public:
|
|||
LinkerObject * mLinkerObject, * mProxyObject;
|
||||
NativeCodeInstruction mIns[64];
|
||||
FunctionCall * mNext, * mSame;
|
||||
int mCount;
|
||||
int mCount, mOffset;
|
||||
|
||||
bool IsSame(const FunctionCall* fc) const;
|
||||
int Matches(const FunctionCall* fc) const;
|
||||
|
|
|
@ -212,6 +212,8 @@ int main2(int argc, const char** argv)
|
|||
compiler->mCompilerOptions |= COPT_OPTIMIZE_CONST_PARAMS;
|
||||
else if (arg[2] == 'g')
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
|
||||
else if (arg[2] == 'm')
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
||||
}
|
||||
else if (arg[1] == 'e')
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue