Fix conditional operator with pointes and arrays
This commit is contained in:
parent
3c891fb61e
commit
fc0f8e2442
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue