@@ -452,15 +452,15 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|T
452
452
op1 = GET_OP1_ZVAL_PTR_DEREF (BP_VAR_R );
453
453
op2 = GET_OP2_ZVAL_PTR_DEREF (BP_VAR_R );
454
454
if (Z_TYPE_P (op1 ) != Z_TYPE_P (op2 )) {
455
- /* They are not identical, return false. Note that this has to check for undefined variable errors when IS_NULL is possible. */
456
- ZEND_VM_C_LABEL (is_different_nothrow ):
455
+ /* They are not identical, return false. This has to check for __destruct errors (and undefined variable errors when IS_NULL is possible) */
457
456
FREE_OP1 ();
458
457
FREE_OP2 ();
459
458
ZEND_VM_SMART_BRANCH (0 , 1 );
460
459
return ;
461
460
}
462
461
if (Z_TYPE_P (op1 ) <= IS_TRUE ) {
463
462
/* They are identical, return true */
463
+ /* This has to check for undefined variable errors when IS_NULL is possible. */
464
464
FREE_OP1 ();
465
465
FREE_OP2 ();
466
466
ZEND_VM_SMART_BRANCH (1 , 1 );
@@ -469,16 +469,20 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|T
469
469
switch (Z_TYPE_P (op1 )) {
470
470
case IS_LONG :
471
471
result = (Z_LVAL_P (op1 ) == Z_LVAL_P (op2 ));
472
+ ZEND_VM_C_LABEL (free_nothrow ):
473
+ FREE_OP1 ();
474
+ FREE_OP2 ();
475
+ ZEND_VM_SMART_BRANCH (result , 0 );
472
476
break ;
473
477
case IS_RESOURCE :
474
478
result = (Z_RES_P (op1 ) == Z_RES_P (op2 ));
475
479
break ;
476
480
case IS_DOUBLE :
477
481
result = (Z_DVAL_P (op1 ) == Z_DVAL_P (op2 ));
478
- break ;
482
+ ZEND_VM_C_GOTO ( free_nothrow ) ;
479
483
case IS_STRING :
480
484
result = zend_string_equals (Z_STR_P (op1 ), Z_STR_P (op2 ));
481
- break ;
485
+ ZEND_VM_C_GOTO ( free_nothrow ) ;
482
486
case IS_ARRAY :
483
487
/* This may cause EG(exception) due to infinite nesting, but other zval types won't? */
484
488
/* XXX hash_zval_identical_function is not static */
@@ -488,11 +492,12 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|T
488
492
result = (Z_OBJ_P (op1 ) == Z_OBJ_P (op2 ));
489
493
break ;
490
494
default :
491
- ZEND_VM_C_GOTO ( is_different_nothrow ) ;
495
+ result = 1 ;
492
496
}
497
+ /* Check if freeing the operands (e.g. __destruct(), freeing resources (not sure about that), etc threw an exception before setting the result or branching */
493
498
FREE_OP1 ();
494
499
FREE_OP2 ();
495
- ZEND_VM_SMART_BRANCH (result , 0 );
500
+ ZEND_VM_SMART_BRANCH (result , 1 );
496
501
}
497
502
498
503
ZEND_VM_COLD_CONSTCONST_HANDLER (17 , ZEND_IS_NOT_IDENTICAL , CONST |TMP |VAR |CV , CONST |TMP |VAR |CV , SPEC (COMMUTATIVE ))
@@ -506,15 +511,15 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CON
506
511
op2 = GET_OP2_ZVAL_PTR_DEREF (BP_VAR_R );
507
512
508
513
if (Z_TYPE_P (op1 ) != Z_TYPE_P (op2 )) {
509
- /* They are not identical, return true. Note that this has to check for undefined variable errors when IS_NULL is possible. */
510
- ZEND_VM_C_LABEL (is_different_nothrow ):
511
- FREE_OP1 ();
514
+ /* They are not identical, return true. This has to check for __destruct errors (and undefined variable errors when IS_NULL is possible) */
515
+ FREE_OP1 ();
512
516
FREE_OP2 ();
513
517
ZEND_VM_SMART_BRANCH (1 , 1 );
514
518
return ;
515
519
}
516
520
if (Z_TYPE_P (op1 ) <= IS_TRUE ) {
517
- /* They are identical, return false */
521
+ /* They are identical, return false. */
522
+ /* This has to check for undefined variable errors when IS_NULL is possible. */
518
523
FREE_OP1 ();
519
524
FREE_OP2 ();
520
525
ZEND_VM_SMART_BRANCH (0 , 1 );
@@ -523,16 +528,20 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CON
523
528
switch (Z_TYPE_P (op1 )) {
524
529
case IS_LONG :
525
530
result = (Z_LVAL_P (op1 ) != Z_LVAL_P (op2 ));
531
+ ZEND_VM_C_LABEL (free_nothrow ):
532
+ FREE_OP1 ();
533
+ FREE_OP2 ();
534
+ ZEND_VM_SMART_BRANCH (result , 0 );
526
535
break ;
527
536
case IS_RESOURCE :
528
537
result = (Z_RES_P (op1 ) != Z_RES_P (op2 ));
529
538
break ;
530
539
case IS_DOUBLE :
531
540
result = (Z_DVAL_P (op1 ) != Z_DVAL_P (op2 ));
532
- break ;
541
+ ZEND_VM_C_GOTO ( free_nothrow ) ;
533
542
case IS_STRING :
534
543
result = !zend_string_equals (Z_STR_P (op1 ), Z_STR_P (op2 ));
535
- break ;
544
+ ZEND_VM_C_GOTO ( free_nothrow ) ;
536
545
case IS_ARRAY :
537
546
/* This may cause EG(exception) due to infinite nesting, but other zval types won't? */
538
547
/* XXX hash_zval_identical_function is not static */
@@ -542,11 +551,12 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CON
542
551
result = (Z_OBJ_P (op1 ) != Z_OBJ_P (op2 ));
543
552
break ;
544
553
default :
545
- ZEND_VM_C_GOTO ( is_different_nothrow ) ;
554
+ result = 1 ;
546
555
}
556
+ /* Check if freeing the operands (e.g. __destruct(), freeing resources (not sure about that), etc threw an exception before setting the result or branching */
547
557
FREE_OP1 ();
548
558
FREE_OP2 ();
549
- ZEND_VM_SMART_BRANCH (result , 0 );
559
+ ZEND_VM_SMART_BRANCH (result , 1 );
550
560
}
551
561
552
562
ZEND_VM_HELPER (zend_is_equal_helper , ANY , ANY , zval * op_1 , zval * op_2 )
0 commit comments