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) if (this == dec)
return true; 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) if (mType != dec->mType)
return false; return false;
if (mSize != dec->mSize) if (mSize != dec->mSize)
@ -367,8 +374,8 @@ bool Declaration::IsSubType(const Declaration* dec) const
return true; return true;
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || DT_TYPE_UNION) else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || DT_TYPE_UNION)
return false; return false;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) else if (mType == DT_TYPE_ARRAY)
return mBase->IsSubType(dec->mBase); return mSize <= dec->mSize && mBase->IsSubType(dec->mBase);
else if (mType == DT_TYPE_FUNCTION) else if (mType == DT_TYPE_FUNCTION)
{ {
if (!dec->mBase->IsSubType(mBase)) 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); TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, 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 = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
vr = Dereference(proc, fblock, vr);
int ttemp; int ttemp;
InterType ttype, stypel, styper; InterType ttype, stypel, styper;
@ -2201,37 +2198,63 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
Declaration* dtype; Declaration* dtype;
if (stypel == IT_POINTER || styper == IT_POINTER) if (stypel == IT_POINTER || styper == IT_POINTER)
{ {
if (!vl.mType->IsSame(vr.mType)) if (vl.mType->mType == DT_TYPE_ARRAY)
vl = Dereference(proc, tblock, vl, 1);
else
vl = Dereference(proc, tblock, vl);
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"); mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
dtype = vl.mType;
}
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
ntype->mBase = dtype->mBase;
dtype = ntype;
ttype = IT_POINTER; ttype = IT_POINTER;
dtype = vl.mType;
}
else if (stypel == styper)
{
ttype = stypel;
dtype = vl.mType;
}
else if (stypel > styper)
{
ttype = stypel;
dtype = vl.mType;
vr = CoerceType(proc, fblock, vr, dtype);
} }
else else
{ {
ttype = styper; vl = Dereference(proc, tblock, vl);
dtype = vr.mType; vr = Dereference(proc, fblock, vr);
vl = CoerceType(proc, tblock, vl, dtype); if (stypel == styper)
{
ttype = stypel;
dtype = vl.mType;
}
else if (stypel > styper)
{
ttype = stypel;
dtype = vl.mType;
vr = CoerceType(proc, fblock, vr, dtype);
}
else
{
ttype = styper;
dtype = vr.mType;
vl = CoerceType(proc, tblock, vl, dtype);
}
} }
ttemp = proc->AddTemporary(ttype); ttemp = proc->AddTemporary(ttype);
InterInstruction * rins = new InterInstruction(); InterInstruction * rins = new InterInstruction();
rins->mCode = IC_LOAD_TEMPORARY; rins->mCode = IC_LOAD_TEMPORARY;
rins->mSrc[0].mType = InterTypeOf(vr.mType); rins->mSrc[0].mType = ttype;
rins->mSrc[0].mTemp = vr.mTemp; rins->mSrc[0].mTemp = vr.mTemp;
rins->mDst.mType = ttype; rins->mDst.mType = ttype;
rins->mDst.mTemp = ttemp; rins->mDst.mTemp = ttemp;
@ -2239,7 +2262,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * lins = new InterInstruction(); InterInstruction * lins = new InterInstruction();
lins->mCode = IC_LOAD_TEMPORARY; lins->mCode = IC_LOAD_TEMPORARY;
lins->mSrc[0].mType = InterTypeOf(vl.mType); lins->mSrc[0].mType = ttype;
lins->mSrc[0].mTemp = vl.mTemp; lins->mSrc[0].mTemp = vl.mTemp;
lins->mDst.mType = ttype; lins->mDst.mType = ttype;
lins->mDst.mTemp = ttemp; lins->mDst.mTemp = ttemp;

View File

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