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:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário