Fix conditional operator with pointes and arrays

This commit is contained in:
drmortalwombat 2021-10-14 13:15:10 +02:00
parent 3c891fb61e
commit fc0f8e2442
3 changed files with 56 additions and 26 deletions

View File

@ -350,6 +350,13 @@ bool Declaration::IsSubType(const Declaration* dec) const
{
if (this == dec)
return true;
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
{
if (dec->mType == DT_TYPE_POINTER)
return mBase->IsSubType(dec->mBase);
}
if (mType != dec->mType)
return false;
if (mSize != dec->mSize)
@ -367,8 +374,8 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true;
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || DT_TYPE_UNION)
return false;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSubType(dec->mBase);
else if (mType == DT_TYPE_ARRAY)
return mSize <= dec->mSize && mBase->IsSubType(dec->mBase);
else if (mType == DT_TYPE_FUNCTION)
{
if (!dec->mBase->IsSubType(mBase))

View File

@ -2187,10 +2187,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper);
vl = Dereference(proc, tblock, vl);
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
vr = Dereference(proc, fblock, vr);
int ttemp;
InterType ttype, stypel, styper;
@ -2201,13 +2198,38 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
Declaration* dtype;
if (stypel == IT_POINTER || styper == IT_POINTER)
{
if (!vl.mType->IsSame(vr.mType))
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
if (vl.mType->mType == DT_TYPE_ARRAY)
vl = Dereference(proc, tblock, vl, 1);
else
vl = Dereference(proc, tblock, vl);
ttype = IT_POINTER;
if (vr.mType->mType == DT_TYPE_ARRAY)
vr = Dereference(proc, fblock, vr, 1);
else
vr = Dereference(proc, fblock, vr);
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
dtype = vr.mType;
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
dtype = vl.mType;
else
{
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
dtype = vl.mType;
}
else if (stypel == styper)
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
ntype->mBase = dtype->mBase;
dtype = ntype;
ttype = IT_POINTER;
}
else
{
vl = Dereference(proc, tblock, vl);
vr = Dereference(proc, fblock, vr);
if (stypel == styper)
{
ttype = stypel;
dtype = vl.mType;
@ -2226,12 +2248,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vl = CoerceType(proc, tblock, vl, dtype);
}
}
ttemp = proc->AddTemporary(ttype);
InterInstruction * rins = new InterInstruction();
rins->mCode = IC_LOAD_TEMPORARY;
rins->mSrc[0].mType = InterTypeOf(vr.mType);
rins->mSrc[0].mType = ttype;
rins->mSrc[0].mTemp = vr.mTemp;
rins->mDst.mType = ttype;
rins->mDst.mTemp = ttemp;
@ -2239,7 +2262,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * lins = new InterInstruction();
lins->mCode = IC_LOAD_TEMPORARY;
lins->mSrc[0].mType = InterTypeOf(vl.mType);
lins->mSrc[0].mType = ttype;
lins->mSrc[0].mTemp = vl.mTemp;
lins->mDst.mType = ttype;
lins->mDst.mTemp = ttemp;

View File

@ -1519,7 +1519,7 @@ Expression* Parser::ParseLogicOrExpression(void)
Expression* Parser::ParseConditionalExpression(void)
{
Expression* exp = ParseLogicAndExpression();
Expression* exp = ParseLogicOrExpression();
if (mScanner->mToken == TK_QUESTIONMARK)
{
@ -1563,7 +1563,7 @@ Expression* Parser::ParseParenthesisExpression(void)
Expression* Parser::ParseAssignmentExpression(void)
{
Expression* exp = ParseLogicOrExpression();
Expression* exp = ParseConditionalExpression();
while (mScanner->mToken >= TK_ASSIGN && mScanner->mToken <= TK_ASSIGN_OR)
{