Fix literal string to int/double conversion under hhir

The simplifier would convert strictly-integer strings to their
integer equivalent, and all other strings to zero. This meant
that eg "1.1" became zero, as did "1x". Normally, such strings
are converted at the ast level, so it was hard to expose the bug,
but eg test/quick/cnvInt.php would fail if you turned off
JitEnableRenameFunctions (and its turned off in repo mode, so the
repo mode test was failing).

The same issue was present in ConvStrToDbl, but there was a bug in
StringData::isNumeric causing it to return true for a weakly-numeric string,
where its contract is to return false (and it did return false for an
equivalent, non-static string). Once I fixed that bug, I had to fix the
bug in ConvStrToDbl.
Esse commit está contido em:
Mark Williams
2013-04-23 08:20:16 -07:00
commit de Sara Golemon
commit 0526e973c5
6 arquivos alterados com 43 adições e 7 exclusões
+1 -1
Ver Arquivo
@@ -792,7 +792,7 @@ DataType StringData::isNumericWithVal(int64_t &lval, double &dval,
}
bool StringData::isNumeric() const {
if (isStatic()) return (m_hash >= 0);
if (m_hash < 0) return false;
int64_t lval; double dval;
DataType ret = isNumericWithVal(lval, dval, 0);
switch (ret) {
+16 -6
Ver Arquivo
@@ -1144,10 +1144,15 @@ SSATmp* Simplifier::simplifyConvStrToDbl(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
const StringData *str = src->getValStr();
if (str->isNumeric()) {
return genDefDbl(str->toDouble());
int64_t lval;
double dval;
DataType ret = str->isNumericWithVal(lval, dval, 1);
if (ret == KindOfInt64) {
dval = (double)lval;
} else if (ret != KindOfDouble) {
dval = 0.0;
}
return genDefDbl(0.0);
return genDefDbl(dval);
}
return nullptr;
}
@@ -1183,10 +1188,15 @@ SSATmp* Simplifier::simplifyConvStrToInt(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
const StringData *str = src->getValStr();
if (str->isInteger()) {
return genDefInt(str->toInt64());
int64_t lval;
double dval;
DataType ret = str->isNumericWithVal(lval, dval, 1);
if (ret == KindOfDouble) {
lval = (int64_t)dval;
} else if (ret != KindOfInt64) {
lval = 0;
}
return genDefInt(0);
return genDefInt(lval);
}
return nullptr;
}
+11
Ver Arquivo
@@ -53,3 +53,14 @@ function bar($i) {
}
bar(1);
function baz($i) {
if ($i >= 1) {
$s1 = '5.3xxx';
$s2 = '7yyy';
}
var_dump((double)$s1);
var_dump((double)$s2);
}
baz(1);
+2
Ver Arquivo
@@ -19,3 +19,5 @@ HipHop Notice: Object of class C could not be converted to int in %s on line 50
float(1)
float(0)
float(1)
float(5.3)
float(7)
+11
Ver Arquivo
@@ -53,3 +53,14 @@ function bar($i) {
}
bar(1);
function baz($i) {
if ($i >= 1) {
$s1 = '5.3xxx';
$s2 = '7yyy';
}
var_dump((int)$s1);
var_dump((int)$s2);
}
baz(1);
+2
Ver Arquivo
@@ -19,3 +19,5 @@ HipHop Notice: Object of class C could not be converted to int in %s on line 50
int(1)
int(0)
int(1)
int(5)
int(7)