Commit 89660954 authored by Victor Yacovlev's avatar Victor Yacovlev

Implemented checking integer constants for overflow at compile time

parent 21a21e91
......@@ -1455,14 +1455,23 @@ void SyntaxAnalizerPrivate::parseAssignment(int str)
AST::VariableBaseType b = rightExpr->baseType.kind;
if (a==AST::TypeInteger) {
if (b==AST::TypeReal) {
QString strValue = QString::number(rightExpr->constant.toDouble(), 'f', 100);
while (strValue.endsWith('0') || strValue.endsWith('.')) {
strValue = strValue.left(strValue.length()-1);
bool isRealConstant = false;
static const QString realSpecificSymbols =
QString::fromUtf8("еЕeE.");
if (rightExpr->kind==AST::ExprConst) {
QString strValue;
foreach (const AST::Lexem * lx, right) {
strValue += lx->data;
}
for (int s=0; s<realSpecificSymbols.length(); s++) {
const QChar ss = realSpecificSymbols[s];
if (strValue.contains(ss)) {
isRealConstant = true;
break;
}
}
}
if (rightExpr->kind==AST::ExprConst
&& !strValue.contains(".")
&& !strValue.toLower().contains("e")
)
if (!isRealConstant)
{
// Constant became real because of big integer representation
err = _("Integer constant too big");
......@@ -2515,13 +2524,14 @@ QVariant SyntaxAnalizerPrivate::parseConstant(const std::list<Lexem*> &constant
val += (*it)->data;
}
bool integerOverflow = false;
bool isHex = false;
if (pt==AST::TypeInteger) {
//integerOverflow = !StdLib::IntegerOverflowChecker::checkFromString(val);
// TODO check integer value from string
integerOverflow = !Kumir::Math::isCorrectIntegerConstant(val.toStdWString());
isHex = val.startsWith("$") || val.startsWith("-$") || val.startsWith("0x") || val.startsWith("-0x");
}
if (ct==AST::TypeReal ||
(pt==AST::TypeReal || integerOverflow)
(pt==AST::TypeReal || (integerOverflow && !isHex) )
)
{
ct = AST::TypeReal;
......
......@@ -333,6 +333,43 @@ public:
// TODO: implement for ARM/AVR platform!!!!
}
inline static bool isCorrectIntegerConstant(const String & value) {
size_t start = 0;
if (value.length()<=start) return false;
bool isNegative = value.at(0)==Char('-');
if (isNegative) {
start = 1;
}
if (value.length()<=start) return false;
bool isHex = false;
if (value.length()-start >= 1) {
isHex = value.at(start)==Char('$');
if (isHex) start += 1;
}
if (!isHex && value.length()-start >= 2) {
isHex = value.at(start)==Char('0') && value.at(start+1)==Char('x');
if (isHex) start += 2;
}
if (value.length()<=start) return false;
while (start<value.length() && value.at(start)==Char('0'))
start += 1;
const String digits = value.substr(start);
static const String maxHex = Core::fromAscii("80000000");
static const String maxDecimal = Core::fromAscii("2147483648");
if (isHex) {
if (digits.length()==maxHex.length())
return digits < maxHex;
else
return digits.length()<maxHex.length();
}
else {
if (digits.length()==maxDecimal.length())
return digits < maxDecimal;
else
return digits.length()<maxDecimal.length();
}
}
inline static real abs(real x) { return ::fabs(x); }
inline static int imax(int x, int y) { return x>y? x : y; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment