Add check for __interrupt attribute on function pointers call from interrupt code

This commit is contained in:
drmortalwombat 2022-02-15 09:49:46 +01:00
parent fdb112a037
commit 1221649a3d
17 changed files with 143 additions and 21 deletions

View File

@ -129,6 +129,9 @@ rem @echo off
@call :test ptrinittest.c
@if %errorlevel% neq 0 goto :error
@call :test ptrarraycmptest.c
@if %errorlevel% neq 0 goto :error
@exit /b 0
:error

View File

@ -0,0 +1,39 @@
#include <assert.h>
struct X
{
int a;
};
X x[5] = {
{1}, {2}, {3}, {4}, {5}
};
X * y;
int main(void)
{
y = x;
assert(y == x);
y = x + 1;
assert(y == x + 1);
y = &(x[2]);
assert(y == x + 2);
y = x + 3;
assert(y == &(x[3]));
y = x ;
assert(y == (struct X*)x);
y = x;
assert(x == y);
y = x + 1;
assert(x + 1 == y);
y = &(x[2]);
assert(x + 2 == y);
y = x + 3;
assert(&(x[3]) == y);
y = x ;
assert((struct X*)x == y);
return 0;
}

View File

@ -273,7 +273,7 @@ bool Compiler::GenerateCode(void)
}
#endif
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
for (int i = mInterCodeModule->mProcedures.Size() - 1; i >=0; i--)
{
InterCodeProcedure* proc = mInterCodeModule->mProcedures[i];

View File

@ -557,6 +557,9 @@ bool Declaration::IsSubType(const Declaration* dec) const
if (dl || dr)
return false;
if ((mFlags & DTF_INTERRUPT) && !(dec->mFlags & DTF_INTERRUPT))
return false;
if ((mFlags & DTF_VARIADIC) != (dec->mFlags & DTF_VARIADIC))
return false;
@ -682,7 +685,7 @@ bool Declaration::CanAssign(const Declaration* fromType) const
}
else if (mBase->mType == DT_TYPE_FUNCTION && fromType->mType == DT_TYPE_FUNCTION)
{
return mBase->IsSame(fromType);
return mBase->IsSubType(fromType);
}
else if (mBase->mType == DT_TYPE_VOID && fromType->mType == DT_TYPE_ASSEMBLER)
{

View File

@ -76,6 +76,7 @@ static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);
static const uint64 DTF_FUNC_RECURSIVE = (1ULL << 34);
static const uint64 DTF_FUNC_ANALYZING = (1ULL << 35);
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37);
static const uint64 DTF_VAR_ALIASING = (1ULL << 37);

View File

@ -18,6 +18,7 @@ enum ErrorID
EWARN_UNKNOWN_PRAGMA,
EWARN_INDEX_OUT_OF_BOUNDS,
EWARN_SYNTAX,
EWARN_NOT_INTERRUPT_SAFE,
EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND,

View File

@ -159,6 +159,8 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
mFunctions.Push(dec);
dec->mFlags |= DTF_ANALYZED;
dec->mFlags |= DTF_FUNC_INTRSAVE;
if ((dec->mFlags & DTF_INTRINSIC) && !dec->mValue)
dec->mFlags |= DTF_FUNC_CONSTEXPR;
else if (dec->mFlags & DTF_DEFINED)
@ -325,6 +327,13 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_CALL:
ldec = Analyze(exp->mLeft, procDec);
RegisterCall(procDec, ldec);
if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT)))
{
procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
if (procDec->mFlags & DTF_INTERRUPT)
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent->mString);
}
if (exp->mRight)
RegisterProc(Analyze(exp->mRight, procDec));
break;
@ -423,6 +432,20 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
return TheVoidTypeDeclaration;
}
uint64 GlobalAnalyzer::GetProcFlags(Declaration* to) const
{
if (to->mType == DT_CONST_FUNCTION)
return to->mFlags;
else if (to->mType == DT_TYPE_FUNCTION)
return to->mFlags;
else if (to->mType == DT_TYPE_POINTER && to->mBase->mType == DT_TYPE_FUNCTION)
return GetProcFlags(to->mBase);
else if (to->mType == DT_VARIABLE || to->mType == DT_ARGUMENT)
return GetProcFlags(to->mBase);
else
return 0;
}
void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
{
if (from)

View File

@ -27,6 +27,7 @@ protected:
Declaration* Analyze(Expression* exp, Declaration* procDec);
uint64 GetProcFlags(Declaration* to) const;
void RegisterCall(Declaration* from, Declaration* to);
void RegisterProc(Declaration* to);
};

View File

@ -2627,6 +2627,16 @@ bool InterInstruction::ConstantFolding(void)
mNumOperands = 0;
return true;
}
else if (mSrc[0].mTemp == mSrc[1].mTemp)
{
mCode = IC_CONSTANT;
mConst.mIntConst = ::ConstantFolding(mOperator, mSrc[0].mType, 0, 0);
mConst.mType = IT_BOOL;
mSrc[0].mTemp == -1;
mSrc[1].mTemp == -1;
mNumOperands = 0;
return true;
}
break;
case IC_BINARY_OPERATOR:
if (mSrc[0].mTemp < 0 && mSrc[1].mTemp < 0)
@ -8581,6 +8591,9 @@ void InterCodeProcedure::Close(void)
ResetVisited();
mEntryBlock->CollectOuterFrame(0, size, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode);
if (mModule->mCompilerOptions & COPT_NATIVE)
mCallsByteCode = false;
mCommonFrameSize = size;
}
else
@ -9074,6 +9087,7 @@ void InterCodeProcedure::RemoveNonRelevantStatics(void)
{
ResetVisited();
mEntryBlock->RemoveNonRelevantStatics();
RemoveUnusedInstructions();
}
void InterCodeProcedure::MapVariables(void)
@ -9390,7 +9404,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{
#if 0
#if 1
#ifdef _WIN32
FILE* file;
static bool initial = true;

View File

@ -1717,9 +1717,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_RELATIONAL:
{
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
vl = Dereference(proc, block, vl);
vl = Dereference(proc, block, vl, vl.mType->mType == DT_TYPE_ARRAY ? 1 : 0);
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper);
vr = Dereference(proc, block, vr);
vr = Dereference(proc, block, vr, vr.mType->mType == DT_TYPE_ARRAY ? 1 : 0);
InterInstruction * ins = new InterInstruction();

View File

@ -48,6 +48,11 @@ struct ZeroPageSet
mBits[n >> 5] |= 1 << (n & 31);
}
void operator -= (int n)
{
mBits[n >> 5] &= ~(1 << (n & 31));
}
bool operator[] (int n) const
{
return (mBits[n >> 5] & (1 << (n & 31))) != 0;

View File

@ -8214,7 +8214,7 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc
}
}
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction* ins)
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure * nproc, const InterInstruction* ins)
{
if (ins->mCode == IC_ASSEMBLER)
{
@ -8232,10 +8232,22 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterIn
ins->mSrc[0].mLinkerObject->mNumTemporaries = ins->mNumOperands - 1;
}
assert(ins->mSrc[0].mLinkerObject);
if (ins->mSrc[0].mTemp < 0)
{
assert(ins->mSrc[0].mLinkerObject);
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bcexec")));
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_FEXEC));
}
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject));
if (ins->mDst.mTemp >= 0)
{
if (ins->mDst.mType == IT_FLOAT)
@ -8658,7 +8670,7 @@ void NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
case ASMIM_ABSOLUTE:
if (mIns[i].mType == ASMIT_JSR)
{
if (mIns[i].mFlags & NCIF_RUNTIME)
if ((mIns[i].mFlags & NCIF_RUNTIME) && !(mIns[i].mFlags & NCIF_FEXEC))
{
for (int j = 0; j < 4; j++)
{
@ -16028,6 +16040,20 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_PHA));
}
bool usesStack = false;
if (zpLocal[BC_REG_STACK])
{
usesStack = true;
zpLocal -= BC_REG_STACK;
zpLocal -= BC_REG_STACK + 1;
}
if (usesStack)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
for (int i = 2; i < 256; i++)
{
if (zpLocal[i])
@ -16045,6 +16071,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, i));
}
}
if (usesStack)
{
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
if (proc->mHardwareInterrupt)
{
@ -16803,7 +16833,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
break;
case IC_CALL_NATIVE:
case IC_ASSEMBLER:
block->CallAssembler(iproc, ins);
block->CallAssembler(iproc, this, ins);
break;
case IC_PUSH_FRAME:
{

View File

@ -181,7 +181,7 @@ public:
NativeCodeBasicBlock * CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc);
NativeCodeBasicBlock * StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc);
void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins);
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);

View File

@ -962,7 +962,7 @@ Declaration* Parser::ParseDeclaration(bool variable)
}
}
Declaration* bdec = ParseBaseTypeDeclaration(0);
Declaration* bdec = ParseBaseTypeDeclaration(typeFlags);
Declaration* rdec = nullptr, * ldec = nullptr;
@ -988,6 +988,8 @@ Declaration* Parser::ParseDeclaration(bool variable)
}
}
if (npdec->mBase->mType == DT_TYPE_FUNCTION)
npdec->mBase->mFlags |= storageFlags & (DTF_INTERRUPT | DTF_NATIVE | TK_FASTCALL);
if (definingType)
{

View File

@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
#else
strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.4.89");
strcpy(strProductVersion, "1.4.90");
#ifdef __APPLE__
uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,89,0
PRODUCTVERSION 1,4,89,0
FILEVERSION 1,4,90,0
PRODUCTVERSION 1,4,90,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.4.89.0"
VALUE "FileVersion", "1.4.90.0"
VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.4.89.0"
VALUE "ProductVersion", "1.4.90.0"
END
END
BLOCK "VarFileInfo"

View File

@ -3752,15 +3752,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{96DACD5F-2EC0-4296-9AFE-FB3F0A377D2A}"
"PackageCode" = "8:{49C9E61D-9B14-437A-A945-39BFE6ED8516}"
"ProductCode" = "8:{713950ED-E82C-46AE-AEE1-B7696F19319F}"
"PackageCode" = "8:{9CE6068F-14BD-457A-B770-D8A1BA054207}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.4.89"
"ProductVersion" = "8:1.4.90"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"