From 5533d9a69fb7d628b2573236fb8dba72269fa635 Mon Sep 17 00:00:00 2001 From: Yu-Jung Lo Date: Mon, 16 Sep 2019 16:57:10 -0700 Subject: [PATCH] ClsMeth type comparison improvement Summary: * Raise notice when actually doing a clsmeth to vec/array conversion * Implement ClsMeth comparison at JIT instead of punting to interpreter. Reviewed By: ricklavoie Differential Revision: D17276735 fbshipit-source-id: 854b8bf1dbdbb085086ea60bb6ba633589679317 --- hphp/runtime/base/builtin-functions.cpp | 9 +- hphp/runtime/base/builtin-functions.h | 2 + hphp/runtime/base/tv-comparisons.cpp | 60 ++++----- hphp/runtime/vm/jit/irgen-arith.cpp | 109 ++++++++++++++-- hphp/test/slow/global_func/class_meth/cmp.php | 12 +- .../slow/global_func/class_meth/cmp.php.expectf | 140 +++++++++++++++++---- .../dv_arr_hack_arr/cmp_warn.php.expectf | 126 ++++++------------- 7 files changed, 306 insertions(+), 152 deletions(-) diff --git a/hphp/runtime/base/builtin-functions.cpp b/hphp/runtime/base/builtin-functions.cpp index 98cfe186a33..618bdd26447 100644 --- a/hphp/runtime/base/builtin-functions.cpp +++ b/hphp/runtime/base/builtin-functions.cpp @@ -91,7 +91,10 @@ const StaticString s_cmpWithRecord( "Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare " "records" ); - +const StaticString s_cmpWithClsMeth( + "Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare " + "a clsmeth with a non-clsmeth" +); const StaticString s_cmpWithNonRecord( "Cannot compare records with non-records" ); @@ -820,6 +823,10 @@ void throw_keyset_compare_exception() { SystemLib::throwInvalidOperationExceptionObject(s_cmpWithKeyset); } +void throw_clsmeth_compare_exception() { + SystemLib::throwInvalidOperationExceptionObject(s_cmpWithClsMeth); +} + void throw_param_is_not_container() { static const string msg("Parameter must be an array or collection"); SystemLib::throwInvalidArgumentExceptionObject(msg); diff --git a/hphp/runtime/base/builtin-functions.h b/hphp/runtime/base/builtin-functions.h index 74c870fb7a2..5d152dbd459 100644 --- a/hphp/runtime/base/builtin-functions.h +++ b/hphp/runtime/base/builtin-functions.h @@ -34,6 +34,7 @@ extern const StaticString s_cmpWithCollection; extern const StaticString s_cmpWithVec; extern const StaticString s_cmpWithDict; extern const StaticString s_cmpWithKeyset; +extern const StaticString s_cmpWithClsMeth; extern const StaticString s_cmpWithRecord; /////////////////////////////////////////////////////////////////////////////// @@ -253,6 +254,7 @@ bool is_constructor_name(const char* func); [[noreturn]] void throw_vec_compare_exception(); [[noreturn]] void throw_dict_compare_exception(); [[noreturn]] void throw_keyset_compare_exception(); +[[noreturn]] void throw_clsmeth_compare_exception(); [[noreturn]] void throw_record_compare_exception(); [[noreturn]] void throw_rec_non_rec_compare_exception(); [[noreturn]] void throw_param_is_not_container(); diff --git a/hphp/runtime/base/tv-comparisons.cpp b/hphp/runtime/base/tv-comparisons.cpp index 3b532d693e3..fcbe21ddf66 100644 --- a/hphp/runtime/base/tv-comparisons.cpp +++ b/hphp/runtime/base/tv-comparisons.cpp @@ -58,9 +58,8 @@ typename Op::RetType cellRelOp(Op op, Cell cell, bool val) { } else if (UNLIKELY(isKeysetType(cell.m_type))) { return op.keysetVsNonKeyset(); } else if (UNLIKELY(isClsMethType(cell.m_type))) { - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { if (UNLIKELY(op.noticeOnArrNonArr())) { raiseHackArrCompatArrNonArrCmp(); @@ -139,9 +138,8 @@ typename Op::RetType cellRelOp(Op op, Cell cell, int64_t val) { return strRelOp(op, cell, val, classToStringHelper(cell.m_data.pclass)); case KindOfClsMeth: - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { if (UNLIKELY(op.noticeOnArrNonArr())) { raiseHackArrCompatArrNonArrCmp(); @@ -214,9 +212,8 @@ typename Op::RetType cellRelOp(Op op, Cell cell, double val) { return strRelOp(op, cell, val, classToStringHelper(cell.m_data.pclass)); case KindOfClsMeth: - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { if (UNLIKELY(op.noticeOnArrNonArr())) { raiseHackArrCompatArrNonArrCmp(); @@ -304,9 +301,8 @@ typename Op::RetType cellRelOp(Op op, Cell cell, const StringData* val) { return op(classToStringHelper(cell.m_data.pclass), val); case KindOfClsMeth: - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { if (UNLIKELY(op.noticeOnArrNonArr())) { raiseHackArrCompatArrNonArrCmp(); @@ -326,7 +322,6 @@ typename Op::RetType cellRelOp(Op op, Cell cell, const StringData* val) { template typename Op::RetType cellRelOp(Op op, Cell cell, const ArrayData* ad) { assertx(cellIsPlausible(cell)); - assertx(ad->isPHPArray()); auto const nonArr = [&]{ @@ -397,11 +392,10 @@ typename Op::RetType cellRelOp(Op op, Cell cell, const ArrayData* ad) { return op(false, true); case KindOfClsMeth: - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - hackArr(); - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { + raiseClsMethToVecWarningHelper(); return op(clsMethToVecHelper(cell.m_data.pclsmeth).get(), ad); } @@ -480,9 +474,8 @@ typename Op::RetType cellRelOp(Op op, Cell cell, const ObjectData* od) { return strRelOp(classToStringHelper(cell.m_data.pclass)); case KindOfClsMeth: - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { - return op.vecVsNonVec(); + return op.clsmethVsNonClsMeth(); } else { if (UNLIKELY(op.noticeOnArrNonArr())) { raiseHackArrCompatArrNonArrCmp(); @@ -662,37 +655,44 @@ typename Op::RetType cellRelOp(Op op, Cell cell, ClsMethDataRef clsMeth) { case KindOfString: case KindOfFunc: case KindOfClass: - case KindOfResource: return op(false, true); - case KindOfBoolean: return op(cell.m_data.num, true); + case KindOfResource: + if (RuntimeOption::EvalHackArrDVArrs) return op.clsmethVsNonClsMeth(); + else return op(false, true); + case KindOfBoolean: + if (RuntimeOption::EvalHackArrDVArrs) return op.clsmethVsNonClsMeth(); + else return op(cell.m_data.num, true); case KindOfClsMeth: return op(cell.m_data.pclsmeth, clsMeth); - case KindOfPersistentDict: case KindOfDict: return op.dictVsNonDict(); - case KindOfPersistentKeyset: case KindOfKeyset: return op.keysetVsNonKeyset(); case KindOfPersistentArray: case KindOfArray: { - raiseClsMethToVecWarningHelper(); - if (!RuntimeOption::EvalHackArrDVArrs) { + if (RuntimeOption::EvalHackArrDVArrs) { + return op.clsmethVsNonClsMeth(); + } else { + raiseClsMethToVecWarningHelper(); return op(cell.m_data.parr, clsMethToVecHelper(clsMeth).get()); } - return op.vecVsNonVec(); } case KindOfPersistentVec: case KindOfVec: { - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) { + raiseClsMethToVecWarningHelper(); return op.vec(cell.m_data.parr, clsMethToVecHelper(clsMeth).get()); - } - return op.vecVsNonVec(); + } else return op.vecVsNonVec(); } case KindOfObject: { - auto const od = cell.m_data.pobj; - return od->isCollection() ? op.collectionVsNonObj() : op(true, false); + if (RuntimeOption::EvalHackArrDVArrs) { + return op.clsmethVsNonClsMeth(); + } else { + auto const od = cell.m_data.pobj; + return od->isCollection() ? op.collectionVsNonObj() : op(true, false); + } + } case KindOfRecord: return op.recordVsNonRecord(); @@ -1005,6 +1005,7 @@ struct Eq { bool recordVsNonRecord() const { throw_rec_non_rec_compare_exception(); } + bool clsmethVsNonClsMeth() const { return false; } bool noticeOnArrNonArr() const { return false; } bool noticeOnArrHackArr() const { @@ -1068,6 +1069,9 @@ struct CompareBase { RetType recordVsNonRecord() const { throw_rec_non_rec_compare_exception(); } + RetType clsmethVsNonClsMeth() const { + throw_clsmeth_compare_exception(); + } bool noticeOnArrNonArr() const { return checkHACCompareNonAnyArray(); @@ -1285,8 +1289,8 @@ bool cellSame(Cell c1, Cell c2) { case KindOfPersistentVec: case KindOfVec: if (isClsMethType(c2.m_type)) { - raiseClsMethToVecWarningHelper(); if (!RuntimeOption::EvalHackArrDVArrs) return false; + raiseClsMethToVecWarningHelper(); return PackedArray::VecSame( c1.m_data.parr, clsMethToVecHelper(c2.m_data.pclsmeth).get()); } @@ -1315,8 +1319,8 @@ bool cellSame(Cell c1, Cell c2) { case KindOfPersistentArray: case KindOfArray: if (isClsMethType(c2.m_type)) { - raiseClsMethToVecWarningHelper(); if (RuntimeOption::EvalHackArrDVArrs) return false; + raiseClsMethToVecWarningHelper(); return ArrayData::Same( c1.m_data.parr, clsMethToVecHelper(c2.m_data.pclsmeth).get()); } diff --git a/hphp/runtime/vm/jit/irgen-arith.cpp b/hphp/runtime/vm/jit/irgen-arith.cpp index ac28a148a69..2f3a9d2b91a 100644 --- a/hphp/runtime/vm/jit/irgen-arith.cpp +++ b/hphp/runtime/vm/jit/irgen-arith.cpp @@ -490,6 +490,23 @@ SSATmp* emitMixedKeysetCmp(IRGS& env, Op op) { } } +SSATmp* emitMixedClsMethCmp(IRGS& env, Op op) { + switch (op) { + case Op::Gt: + case Op::Gte: + case Op::Lt: + case Op::Lte: + case Op::Cmp: + gen(env, ThrowInvalidOperation, cns(env, s_cmpWithClsMeth.get())); + return cns(env, false); + case Op::Same: + case Op::Eq: return cns(env, false); + case Op::NSame: + case Op::Neq: return cns(env, true); + default: always_assert(false); + } +} + void implNullCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { assertx(left->type() <= TNull); auto const rightTy = right->type(); @@ -515,6 +532,12 @@ void implNullCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { push(env, emitMixedDictCmp(env, op)); } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); + } else if (rightTy <= TClsMeth) { + if (RuntimeOption::EvalHackArrDVArrs) { + push(env, emitMixedClsMethCmp(env, op)); + } else { + push(env, emitConstCmp(env, op, false, true)); + } } else { // Otherwise, convert both sides to booleans (with null becoming false). push(env, @@ -535,6 +558,12 @@ void implBoolCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { push(env, emitMixedDictCmp(env, op)); } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); + } else if (rightTy <= TClsMeth) { + if (RuntimeOption::EvalHackArrDVArrs) { + push(env, emitMixedClsMethCmp(env, op)); + } else { + push(env, gen(env, toBoolCmpOpcode(op), left, cns(env, true))); + } } else { // Convert whatever is on the right to a boolean and compare. The conversion // may be a no-op if the right operand is already a bool. @@ -607,7 +636,7 @@ void implIntCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { ); } else if (rightTy <= TClsMeth) { if (RuntimeOption::EvalHackArrDVArrs) { - push(env, emitMixedVecCmp(env, op)); + push(env, emitMixedClsMethCmp(env, op)); } else { push(env, emitConstCmp(env, op, false, true)); } @@ -665,7 +694,7 @@ void implDblCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { ); } else if (rightTy <= TClsMeth) { if (RuntimeOption::EvalHackArrDVArrs) { - push(env, emitMixedVecCmp(env, op)); + push(env, emitMixedClsMethCmp(env, op)); } else { push(env, emitConstCmp(env, op, false, true)); } @@ -755,10 +784,10 @@ void implArrCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); } else if (rightTy <= TClsMeth) { - raiseClsMethToVecWarningHelper(env); if (RuntimeOption::EvalHackArrDVArrs) { - push(env, emitMixedVecCmp(env, op)); + push(env, emitMixedClsMethCmp(env, op)); } else { + raiseClsMethToVecWarningHelper(env); auto const arr = convertClsMethToVec(env, right); push(env, gen(env, toArrCmpOpcode(op), left, arr)); decRef(env, arr); @@ -776,9 +805,9 @@ void implVecCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { // Left operand is a vec. if (rightTy <= TVec) { push(env, gen(env, toVecCmpOpcode(op), left, right)); - } else if (rightTy <= TClsMeth ) { - raiseClsMethToVecWarningHelper(env); + } else if (rightTy <= TClsMeth) { if (RuntimeOption::EvalHackArrDVArrs) { + raiseClsMethToVecWarningHelper(env); auto const arr = convertClsMethToVec(env, right); push(env, gen(env, toVecCmpOpcode(op), left, arr)); decRef(env, arr); @@ -921,6 +950,12 @@ void implStrCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { push(env, emitMixedDictCmp(env, op)); } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); + } else if (rightTy <= TClsMeth) { + if (RuntimeOption::EvalHackArrDVArrs) { + push(env, emitMixedClsMethCmp(env, op)); + } else { + push(env, emitConstCmp(env, op, false, true)); + } } else { // Strings are less than anything else (usually arrays). push(env, emitConstCmp(env, op, false, true)); @@ -1011,6 +1046,20 @@ void implObjCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { push(env, emitMixedDictCmp(env, op)); } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); + } else if (rightTy <= TClsMeth) { + if (RuntimeOption::EvalHackArrDVArrs) { + push(env, emitMixedClsMethCmp(env, op)); + } else { + push( + env, + emitCollectionCheck( + env, + op, + left, + [&]{ return emitConstCmp(env, op, true, false); } + ) + ); + } } else { // For anything else, the object is always greater. push(env, emitConstCmp(env, op, true, false)); @@ -1064,6 +1113,12 @@ void implResCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { push(env, emitMixedDictCmp(env, op)); } else if (rightTy <= TKeyset) { push(env, emitMixedKeysetCmp(env, op)); + } else if (rightTy <= TClsMeth) { + if (RuntimeOption::EvalHackArrDVArrs) { + push(env, emitMixedVecCmp(env, op)); + } else { + push(env, emitConstCmp(env, op, true, false)); + } } else { // Resources are always less than anything else. push(env, emitConstCmp(env, op, false, true)); @@ -1136,25 +1191,59 @@ void implClsMethCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { env, gen(env, XorBool, equalClsMeth(env, left, right), cns(env, true))); return; } + PUNT(ClsMeth-ClsMeth-cmp); + } else if (rightTy <= TDict) { + push(env, emitMixedDictCmp(env, op)); + return; + } else if (rightTy <= TKeyset) { + push(env, emitMixedKeysetCmp(env, op)); + return; } + if (RuntimeOption::EvalHackArrDVArrs) { + // Left (TClsMeth) is compatible with vec if (rightTy <= TVec) { raiseClsMethToVecWarningHelper(env); auto const arr = convertClsMethToVec(env, left); implVecCmp(env, op, arr, right); decRef(env, arr); - return; + } else { + push(env, emitMixedClsMethCmp(env, op)); } } else { - if (rightTy <= TArr) { + // Left (TClsMeth) is compatible with varray + if (rightTy.subtypeOfAny(TNull, TInt, TDbl, TStr)) { + // Null is always less than TClsMeth + // ints,dbls,strs are implicitly less than TClsMeth + push(env, emitConstCmp(env, op, true, false)); + } else if (rightTy <= TBool) { + push(env, gen(env, toBoolCmpOpcode(op), cns(env, true), right)); + } else if (rightTy <= TObj) { + // collections are greater than TClsMeth + push( + env, + emitCollectionCheck( + env, + op, + right, + [&]{ return emitConstCmp(env, op, false, true); } + ) + ); + } else if (rightTy <= TArr) { raiseClsMethToVecWarningHelper(env); auto const arr = convertClsMethToVec(env, left); implArrCmp(env, op, arr, right); decRef(env, arr); - return; + } else if (rightTy <= TVec) { + push(env, emitMixedVecCmp(env, op)); + } else if (rightTy <= TDict) { + push(env, emitMixedDictCmp(env, op)); + } else if (rightTy <= TKeyset) { + push(env, emitMixedKeysetCmp(env, op)); + } else { + PUNT(ClsMeth-cmp); } } - PUNT(ClsMeth-cmp); } void implRecordCmp(IRGS& env, Op op, SSATmp* left, SSATmp* right) { diff --git a/hphp/test/slow/global_func/class_meth/cmp.php b/hphp/test/slow/global_func/class_meth/cmp.php index 012a25932db..292372dabfa 100644 --- a/hphp/test/slow/global_func/class_meth/cmp.php +++ b/hphp/test/slow/global_func/class_meth/cmp.php @@ -29,8 +29,14 @@ function comp($x, $y) { function getTestcase(int $num) { $test_cases = [ - true, false, 0, 1, 0.0, 1.0, "Array", + null, + false, true, + 0, 1, + 0.0, 1.0, + "Array", + HH\fun("wrap"), array('A', 'func1'), + HH\Vector{'A', 'foo'}, varray['A', 'func1'], vec['A', 'func1'], darray[0 => 'A', 1 => 'func1'], @@ -41,7 +47,7 @@ function getTestcase(int $num) { } function comp_test($x) { - for ($i = 0; $i < 13; $i++) { + for ($i = 0; $i < 16; $i++) { print("Test ".$i."\n"); comp($x, getTestcase($i)); comp(getTestcase($i), $x); @@ -51,6 +57,6 @@ function comp_test($x) { <<__EntryPoint>> function main(): void { comp_test(getVArr()); - print("--- test class_meth --- \n"); + print("--- test class_meth ---\n"); comp_test(getClsMeth()); } diff --git a/hphp/test/slow/global_func/class_meth/cmp.php.expectf b/hphp/test/slow/global_func/class_meth/cmp.php.expectf index 627c0d3d7e9..96ec8092895 100644 --- a/hphp/test/slow/global_func/class_meth/cmp.php.expectf +++ b/hphp/test/slow/global_func/class_meth/cmp.php.expectf @@ -1,19 +1,49 @@ Test 0 bool(false) +bool(false) +bool(false) +bool(false) +bool(true) bool(true) + +bool(false) bool(false) bool(true) +bool(true) +bool(false) bool(false) + +Test 1 +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) bool(true) bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) + +Test 2 +bool(false) bool(true) bool(false) bool(true) bool(false) bool(true) -Test 1 +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) + +Test 3 bool(false) bool(false) bool(false) @@ -28,7 +58,7 @@ bool(true) bool(false) bool(false) -Test 2 +Test 4 bool(false) bool(false) bool(false) @@ -43,7 +73,7 @@ bool(true) bool(false) bool(false) -Test 3 +Test 5 bool(false) bool(false) bool(false) @@ -58,7 +88,7 @@ bool(true) bool(false) bool(false) -Test 4 +Test 6 bool(false) bool(false) bool(false) @@ -73,7 +103,7 @@ bool(true) bool(false) bool(false) -Test 5 +Test 7 bool(false) bool(false) bool(false) @@ -88,7 +118,7 @@ bool(true) bool(false) bool(false) -Test 6 +Test 8 bool(false) bool(false) bool(false) @@ -103,7 +133,7 @@ bool(true) bool(false) bool(false) -Test 7 +Test 9 bool(true) bool(true) bool(false) @@ -118,7 +148,22 @@ bool(true) bool(false) bool(true) -Test 8 +Test 10 +bool(false) +bool(false) +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object + +bool(false) +bool(false) +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object + +Test 11 bool(true) bool(true) bool(false) @@ -133,7 +178,7 @@ bool(true) bool(false) bool(true) -Test 9 +Test 12 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec @@ -148,7 +193,7 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec -Test 10 +Test 13 bool(true) bool(true) bool(false) @@ -163,7 +208,7 @@ bool(true) bool(false) bool(true) -Test 11 +Test 14 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts @@ -178,7 +223,7 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts -Test 12 +Test 15 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare keysets @@ -193,23 +238,53 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare keyset Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare keysets Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare keysets ---- test class_meth --- +--- test class_meth --- Test 0 bool(false) +bool(false) +bool(false) +bool(false) +bool(true) bool(true) + +bool(false) bool(false) bool(true) +bool(true) +bool(false) bool(false) + +Test 1 +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) bool(true) bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) + +Test 2 +bool(false) bool(true) bool(false) bool(true) bool(false) bool(true) -Test 1 +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) + +Test 3 bool(false) bool(false) bool(false) @@ -224,7 +299,7 @@ bool(true) bool(false) bool(false) -Test 2 +Test 4 bool(false) bool(false) bool(false) @@ -239,7 +314,7 @@ bool(true) bool(false) bool(false) -Test 3 +Test 5 bool(false) bool(false) bool(false) @@ -254,7 +329,7 @@ bool(true) bool(false) bool(false) -Test 4 +Test 6 bool(false) bool(false) bool(false) @@ -269,7 +344,7 @@ bool(true) bool(false) bool(false) -Test 5 +Test 7 bool(false) bool(false) bool(false) @@ -284,7 +359,7 @@ bool(true) bool(false) bool(false) -Test 6 +Test 8 bool(false) bool(false) bool(false) @@ -299,7 +374,7 @@ bool(true) bool(false) bool(false) -Test 7 +Test 9 bool(true) bool(true) bool(false) @@ -314,7 +389,22 @@ bool(true) bool(false) bool(true) -Test 8 +Test 10 +bool(false) +bool(false) +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object + +bool(false) +bool(false) +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a collection with an integer, double, string, array, or object + +Test 11 bool(true) bool(true) bool(false) @@ -329,7 +419,7 @@ bool(true) bool(false) bool(true) -Test 9 +Test 12 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec @@ -344,7 +434,7 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec -Test 10 +Test 13 bool(true) bool(true) bool(false) @@ -359,7 +449,7 @@ bool(true) bool(false) bool(true) -Test 11 +Test 14 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts @@ -374,7 +464,7 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare dicts -Test 12 +Test 15 bool(false) bool(false) Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare keysets diff --git a/hphp/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php.expectf b/hphp/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php.expectf index bc16f448d8c..5df5cbcfa36 100644 --- a/hphp/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php.expectf +++ b/hphp/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php.expectf @@ -25,73 +25,29 @@ Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec * clsmeth vs array: bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 10 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 12 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 13 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 16 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 21 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 27 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 32 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 38 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 43 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 49 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 54 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 10 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 12 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 13 bool(false) - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 16 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 21 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 27 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 32 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 38 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 43 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 49 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec - -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 54 -Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a vec with a non-vec +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth +Cannot use relational comparison operators (<, <=, >, >=, <=>) to compare a clsmeth with a non-clsmeth * vec vs vec: bool(true) bool(true) @@ -119,76 +75,76 @@ bool(false) bool(true) * clsmeth vs vec: -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 9 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 9 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 10 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 10 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 12 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 12 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 13 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 13 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 16 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 16 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 21 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 21 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 27 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 27 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 32 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 32 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 38 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 38 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 43 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 43 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 49 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 49 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 54 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 54 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 9 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 9 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 10 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 10 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 12 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 12 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 13 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 13 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 16 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 16 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 21 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 21 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 27 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 27 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 32 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 32 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 38 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 38 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 43 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 43 bool(true) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 49 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 49 bool(false) -Notice: Implicit clsmeth to vec conversion in %s/cmp_warn.php on line 54 +Notice: Implicit clsmeth to vec conversion in %s/test/slow/global_func/class_meth/dv_arr_hack_arr/cmp_warn.php on line 54 bool(true) * clsmeth vs clsmeth: bool(true) @@ -214,4 +170,4 @@ bool(false) bool(false) bool(true) bool(false) -bool(true) +bool(true) \ No newline at end of file -- 2.11.4.GIT