From d66ba2cef247d780d0ef354492024a62f980cf85 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 19:32:40 -0600 Subject: [PATCH 1/9] Moved closure_0XX.phpt into their own folder; I needed to rerun them often for a bug I was fixing. --- Zend/tests/{closure_001.phpt => closure/001.phpt} | 0 Zend/tests/{closure_002.phpt => closure/002.phpt} | 0 Zend/tests/{closure_003.phpt => closure/003.phpt} | 0 Zend/tests/{closure_004.phpt => closure/004.phpt} | 0 Zend/tests/{closure_005.phpt => closure/005.phpt} | 2 +- Zend/tests/{closure_006.phpt => closure/006.phpt} | 0 Zend/tests/{closure_007.phpt => closure/007.phpt} | 0 Zend/tests/{closure_008.phpt => closure/008.phpt} | 0 Zend/tests/{closure_009.phpt => closure/009.phpt} | 0 Zend/tests/{closure_010.phpt => closure/010.phpt} | 0 Zend/tests/{closure_011.phpt => closure/011.phpt} | 0 Zend/tests/{closure_012.phpt => closure/012.phpt} | 4 ++-- Zend/tests/{closure_013.phpt => closure/013.phpt} | 0 Zend/tests/{closure_014.phpt => closure/014.phpt} | 0 Zend/tests/{closure_015.phpt => closure/015.phpt} | 4 ++-- Zend/tests/{closure_016.phpt => closure/016.phpt} | 0 Zend/tests/{closure_017.phpt => closure/017.phpt} | 0 Zend/tests/{closure_018.phpt => closure/018.phpt} | 4 ++-- Zend/tests/{closure_019.phpt => closure/019.phpt} | 6 +++--- Zend/tests/{closure_020.phpt => closure/020.phpt} | 0 Zend/tests/{closure_021.phpt => closure/021.phpt} | 0 Zend/tests/{closure_022.phpt => closure/022.phpt} | 2 +- Zend/tests/{closure_023.phpt => closure/023.phpt} | 0 Zend/tests/{closure_024.phpt => closure/024.phpt} | 0 Zend/tests/{closure_025.phpt => closure/025.phpt} | 0 Zend/tests/{closure_026.phpt => closure/026.phpt} | 0 Zend/tests/{closure_027.phpt => closure/027.phpt} | 0 Zend/tests/{closure_028.phpt => closure/028.phpt} | 0 Zend/tests/{closure_029.phpt => closure/029.phpt} | 0 Zend/tests/{closure_030.phpt => closure/030.phpt} | 0 Zend/tests/{closure_031.phpt => closure/031.phpt} | 0 Zend/tests/{closure_032.phpt => closure/032.phpt} | 0 Zend/tests/{closure_033.phpt => closure/033.phpt} | 2 +- Zend/tests/{closure_034.phpt => closure/034.phpt} | 0 Zend/tests/{closure_035.phpt => closure/035.phpt} | 0 Zend/tests/{closure_036.phpt => closure/036.phpt} | 0 Zend/tests/{closure_037.phpt => closure/037.phpt} | 0 Zend/tests/{closure_038.phpt => closure/038.phpt} | 0 Zend/tests/{closure_039.phpt => closure/039.phpt} | 0 Zend/tests/{closure_040.phpt => closure/040.phpt} | 0 Zend/tests/{closure_041.phpt => closure/041.phpt} | 0 Zend/tests/{closure_042.phpt => closure/042.phpt} | 0 Zend/tests/{closure_043.phpt => closure/043.phpt} | 0 Zend/tests/{closure_044.phpt => closure/044.phpt} | 0 Zend/tests/{closure_045.phpt => closure/045.phpt} | 0 Zend/tests/{closure_046.phpt => closure/046.phpt} | 0 Zend/tests/{closure_047.phpt => closure/047.phpt} | 0 Zend/tests/{closure_048.phpt => closure/048.phpt} | 0 48 files changed, 12 insertions(+), 12 deletions(-) rename Zend/tests/{closure_001.phpt => closure/001.phpt} (100%) rename Zend/tests/{closure_002.phpt => closure/002.phpt} (100%) rename Zend/tests/{closure_003.phpt => closure/003.phpt} (100%) rename Zend/tests/{closure_004.phpt => closure/004.phpt} (100%) rename Zend/tests/{closure_005.phpt => closure/005.phpt} (90%) rename Zend/tests/{closure_006.phpt => closure/006.phpt} (100%) rename Zend/tests/{closure_007.phpt => closure/007.phpt} (100%) rename Zend/tests/{closure_008.phpt => closure/008.phpt} (100%) rename Zend/tests/{closure_009.phpt => closure/009.phpt} (100%) rename Zend/tests/{closure_010.phpt => closure/010.phpt} (100%) rename Zend/tests/{closure_011.phpt => closure/011.phpt} (100%) rename Zend/tests/{closure_012.phpt => closure/012.phpt} (69%) rename Zend/tests/{closure_013.phpt => closure/013.phpt} (100%) rename Zend/tests/{closure_014.phpt => closure/014.phpt} (100%) rename Zend/tests/{closure_015.phpt => closure/015.phpt} (90%) rename Zend/tests/{closure_016.phpt => closure/016.phpt} (100%) rename Zend/tests/{closure_017.phpt => closure/017.phpt} (100%) rename Zend/tests/{closure_018.phpt => closure/018.phpt} (89%) rename Zend/tests/{closure_019.phpt => closure/019.phpt} (88%) rename Zend/tests/{closure_020.phpt => closure/020.phpt} (100%) rename Zend/tests/{closure_021.phpt => closure/021.phpt} (100%) rename Zend/tests/{closure_022.phpt => closure/022.phpt} (87%) rename Zend/tests/{closure_023.phpt => closure/023.phpt} (100%) rename Zend/tests/{closure_024.phpt => closure/024.phpt} (100%) rename Zend/tests/{closure_025.phpt => closure/025.phpt} (100%) rename Zend/tests/{closure_026.phpt => closure/026.phpt} (100%) rename Zend/tests/{closure_027.phpt => closure/027.phpt} (100%) rename Zend/tests/{closure_028.phpt => closure/028.phpt} (100%) rename Zend/tests/{closure_029.phpt => closure/029.phpt} (100%) rename Zend/tests/{closure_030.phpt => closure/030.phpt} (100%) rename Zend/tests/{closure_031.phpt => closure/031.phpt} (100%) rename Zend/tests/{closure_032.phpt => closure/032.phpt} (100%) rename Zend/tests/{closure_033.phpt => closure/033.phpt} (92%) rename Zend/tests/{closure_034.phpt => closure/034.phpt} (100%) rename Zend/tests/{closure_035.phpt => closure/035.phpt} (100%) rename Zend/tests/{closure_036.phpt => closure/036.phpt} (100%) rename Zend/tests/{closure_037.phpt => closure/037.phpt} (100%) rename Zend/tests/{closure_038.phpt => closure/038.phpt} (100%) rename Zend/tests/{closure_039.phpt => closure/039.phpt} (100%) rename Zend/tests/{closure_040.phpt => closure/040.phpt} (100%) rename Zend/tests/{closure_041.phpt => closure/041.phpt} (100%) rename Zend/tests/{closure_042.phpt => closure/042.phpt} (100%) rename Zend/tests/{closure_043.phpt => closure/043.phpt} (100%) rename Zend/tests/{closure_044.phpt => closure/044.phpt} (100%) rename Zend/tests/{closure_045.phpt => closure/045.phpt} (100%) rename Zend/tests/{closure_046.phpt => closure/046.phpt} (100%) rename Zend/tests/{closure_047.phpt => closure/047.phpt} (100%) rename Zend/tests/{closure_048.phpt => closure/048.phpt} (100%) diff --git a/Zend/tests/closure_001.phpt b/Zend/tests/closure/001.phpt similarity index 100% rename from Zend/tests/closure_001.phpt rename to Zend/tests/closure/001.phpt diff --git a/Zend/tests/closure_002.phpt b/Zend/tests/closure/002.phpt similarity index 100% rename from Zend/tests/closure_002.phpt rename to Zend/tests/closure/002.phpt diff --git a/Zend/tests/closure_003.phpt b/Zend/tests/closure/003.phpt similarity index 100% rename from Zend/tests/closure_003.phpt rename to Zend/tests/closure/003.phpt diff --git a/Zend/tests/closure_004.phpt b/Zend/tests/closure/004.phpt similarity index 100% rename from Zend/tests/closure_004.phpt rename to Zend/tests/closure/004.phpt diff --git a/Zend/tests/closure_005.phpt b/Zend/tests/closure/005.phpt similarity index 90% rename from Zend/tests/closure_005.phpt rename to Zend/tests/closure/005.phpt index 4e32faa017d75..97e31a6a36f73 100644 --- a/Zend/tests/closure_005.phpt +++ b/Zend/tests/closure/005.phpt @@ -71,4 +71,4 @@ echo "Done\n"; 7 Destroyed -Fatal error: Using $this when not in object context in %sclosure_005.php on line 28 +Fatal error: Using $this when not in object context in %s on line 28 diff --git a/Zend/tests/closure_006.phpt b/Zend/tests/closure/006.phpt similarity index 100% rename from Zend/tests/closure_006.phpt rename to Zend/tests/closure/006.phpt diff --git a/Zend/tests/closure_007.phpt b/Zend/tests/closure/007.phpt similarity index 100% rename from Zend/tests/closure_007.phpt rename to Zend/tests/closure/007.phpt diff --git a/Zend/tests/closure_008.phpt b/Zend/tests/closure/008.phpt similarity index 100% rename from Zend/tests/closure_008.phpt rename to Zend/tests/closure/008.phpt diff --git a/Zend/tests/closure_009.phpt b/Zend/tests/closure/009.phpt similarity index 100% rename from Zend/tests/closure_009.phpt rename to Zend/tests/closure/009.phpt diff --git a/Zend/tests/closure_010.phpt b/Zend/tests/closure/010.phpt similarity index 100% rename from Zend/tests/closure_010.phpt rename to Zend/tests/closure/010.phpt diff --git a/Zend/tests/closure_011.phpt b/Zend/tests/closure/011.phpt similarity index 100% rename from Zend/tests/closure_011.phpt rename to Zend/tests/closure/011.phpt diff --git a/Zend/tests/closure_012.phpt b/Zend/tests/closure/012.phpt similarity index 69% rename from Zend/tests/closure_012.phpt rename to Zend/tests/closure/012.phpt index 7e1b7a27937db..cbdc1454a06d2 100644 --- a/Zend/tests/closure_012.phpt +++ b/Zend/tests/closure/012.phpt @@ -16,9 +16,9 @@ $lambda(); var_dump($i); ?> --EXPECTF-- -Notice: Undefined variable: i in %sclosure_012.php on line 2 +Notice: Undefined variable: i in %s on line 2 -Notice: Undefined variable: i in %sclosure_012.php on line 7 +Notice: Undefined variable: i in %s on line 7 NULL int(2) diff --git a/Zend/tests/closure_013.phpt b/Zend/tests/closure/013.phpt similarity index 100% rename from Zend/tests/closure_013.phpt rename to Zend/tests/closure/013.phpt diff --git a/Zend/tests/closure_014.phpt b/Zend/tests/closure/014.phpt similarity index 100% rename from Zend/tests/closure_014.phpt rename to Zend/tests/closure/014.phpt diff --git a/Zend/tests/closure_015.phpt b/Zend/tests/closure/015.phpt similarity index 90% rename from Zend/tests/closure_015.phpt rename to Zend/tests/closure/015.phpt index 33c732d723722..a5687418bab66 100644 --- a/Zend/tests/closure_015.phpt +++ b/Zend/tests/closure/015.phpt @@ -14,6 +14,6 @@ print $x; print "\n"; ?> --EXPECTF-- -Error: Object of class Closure could not be converted to string at %sclosure_015.php(8) +Error: Object of class Closure could not be converted to string at %s(8) -Error: Object of class Closure could not be converted to string at %sclosure_015.php(10) +Error: Object of class Closure could not be converted to string at %s(10) diff --git a/Zend/tests/closure_016.phpt b/Zend/tests/closure/016.phpt similarity index 100% rename from Zend/tests/closure_016.phpt rename to Zend/tests/closure/016.phpt diff --git a/Zend/tests/closure_017.phpt b/Zend/tests/closure/017.phpt similarity index 100% rename from Zend/tests/closure_017.phpt rename to Zend/tests/closure/017.phpt diff --git a/Zend/tests/closure_018.phpt b/Zend/tests/closure/018.phpt similarity index 89% rename from Zend/tests/closure_018.phpt rename to Zend/tests/closure/018.phpt index 2dcf15c6aa161..4b5e37050a39d 100644 --- a/Zend/tests/closure_018.phpt +++ b/Zend/tests/closure/018.phpt @@ -22,10 +22,10 @@ var_dump($y, $x); ?> --EXPECTF-- -Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7 +Notice: Only variable references should be returned by reference in %s on line 7 int(4) -Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7 +Notice: Only variable references should be returned by reference in %s on line 7 int(16) int(16) int(16) diff --git a/Zend/tests/closure_019.phpt b/Zend/tests/closure/019.phpt similarity index 88% rename from Zend/tests/closure_019.phpt rename to Zend/tests/closure/019.phpt index 57aa2dec17cf7..aef16e89a39ea 100644 --- a/Zend/tests/closure_019.phpt +++ b/Zend/tests/closure/019.phpt @@ -20,10 +20,10 @@ test(); ?> --EXPECTF-- -Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4 +Notice: Only variable references should be returned by reference in %s on line 4 int(9) -Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4 +Notice: Only variable references should be returned by reference in %s on line 4 int(81) -Fatal error: Cannot pass parameter 1 by reference in %s on line %d +Fatal error: Cannot pass parameter 1 by reference in %s on line %d diff --git a/Zend/tests/closure_020.phpt b/Zend/tests/closure/020.phpt similarity index 100% rename from Zend/tests/closure_020.phpt rename to Zend/tests/closure/020.phpt diff --git a/Zend/tests/closure_021.phpt b/Zend/tests/closure/021.phpt similarity index 100% rename from Zend/tests/closure_021.phpt rename to Zend/tests/closure/021.phpt diff --git a/Zend/tests/closure_022.phpt b/Zend/tests/closure/022.phpt similarity index 87% rename from Zend/tests/closure_022.phpt rename to Zend/tests/closure/022.phpt index 8621d2c095f9c..c2d45c3af288a 100644 --- a/Zend/tests/closure_022.phpt +++ b/Zend/tests/closure/022.phpt @@ -8,5 +8,5 @@ $foo = function() use ($a) { $foo->a = 1; ?> --EXPECTF-- -Catchable fatal error: Closure object cannot have properties in %sclosure_022.php on line 5 +Catchable fatal error: Closure object cannot have properties in %s22.php on line 5 diff --git a/Zend/tests/closure_023.phpt b/Zend/tests/closure/023.phpt similarity index 100% rename from Zend/tests/closure_023.phpt rename to Zend/tests/closure/023.phpt diff --git a/Zend/tests/closure_024.phpt b/Zend/tests/closure/024.phpt similarity index 100% rename from Zend/tests/closure_024.phpt rename to Zend/tests/closure/024.phpt diff --git a/Zend/tests/closure_025.phpt b/Zend/tests/closure/025.phpt similarity index 100% rename from Zend/tests/closure_025.phpt rename to Zend/tests/closure/025.phpt diff --git a/Zend/tests/closure_026.phpt b/Zend/tests/closure/026.phpt similarity index 100% rename from Zend/tests/closure_026.phpt rename to Zend/tests/closure/026.phpt diff --git a/Zend/tests/closure_027.phpt b/Zend/tests/closure/027.phpt similarity index 100% rename from Zend/tests/closure_027.phpt rename to Zend/tests/closure/027.phpt diff --git a/Zend/tests/closure_028.phpt b/Zend/tests/closure/028.phpt similarity index 100% rename from Zend/tests/closure_028.phpt rename to Zend/tests/closure/028.phpt diff --git a/Zend/tests/closure_029.phpt b/Zend/tests/closure/029.phpt similarity index 100% rename from Zend/tests/closure_029.phpt rename to Zend/tests/closure/029.phpt diff --git a/Zend/tests/closure_030.phpt b/Zend/tests/closure/030.phpt similarity index 100% rename from Zend/tests/closure_030.phpt rename to Zend/tests/closure/030.phpt diff --git a/Zend/tests/closure_031.phpt b/Zend/tests/closure/031.phpt similarity index 100% rename from Zend/tests/closure_031.phpt rename to Zend/tests/closure/031.phpt diff --git a/Zend/tests/closure_032.phpt b/Zend/tests/closure/032.phpt similarity index 100% rename from Zend/tests/closure_032.phpt rename to Zend/tests/closure/032.phpt diff --git a/Zend/tests/closure_033.phpt b/Zend/tests/closure/033.phpt similarity index 92% rename from Zend/tests/closure_033.phpt rename to Zend/tests/closure/033.phpt index f6510066bbc68..ad9eee8fa5b61 100644 --- a/Zend/tests/closure_033.phpt +++ b/Zend/tests/closure/033.phpt @@ -25,4 +25,4 @@ $o->func(); --EXPECTF-- Test::{closure}() -Fatal error: Call to private method Test::func() from context '' in %sclosure_033.php on line %d +Fatal error: Call to private method Test::func() from context '' in %s on line %d diff --git a/Zend/tests/closure_034.phpt b/Zend/tests/closure/034.phpt similarity index 100% rename from Zend/tests/closure_034.phpt rename to Zend/tests/closure/034.phpt diff --git a/Zend/tests/closure_035.phpt b/Zend/tests/closure/035.phpt similarity index 100% rename from Zend/tests/closure_035.phpt rename to Zend/tests/closure/035.phpt diff --git a/Zend/tests/closure_036.phpt b/Zend/tests/closure/036.phpt similarity index 100% rename from Zend/tests/closure_036.phpt rename to Zend/tests/closure/036.phpt diff --git a/Zend/tests/closure_037.phpt b/Zend/tests/closure/037.phpt similarity index 100% rename from Zend/tests/closure_037.phpt rename to Zend/tests/closure/037.phpt diff --git a/Zend/tests/closure_038.phpt b/Zend/tests/closure/038.phpt similarity index 100% rename from Zend/tests/closure_038.phpt rename to Zend/tests/closure/038.phpt diff --git a/Zend/tests/closure_039.phpt b/Zend/tests/closure/039.phpt similarity index 100% rename from Zend/tests/closure_039.phpt rename to Zend/tests/closure/039.phpt diff --git a/Zend/tests/closure_040.phpt b/Zend/tests/closure/040.phpt similarity index 100% rename from Zend/tests/closure_040.phpt rename to Zend/tests/closure/040.phpt diff --git a/Zend/tests/closure_041.phpt b/Zend/tests/closure/041.phpt similarity index 100% rename from Zend/tests/closure_041.phpt rename to Zend/tests/closure/041.phpt diff --git a/Zend/tests/closure_042.phpt b/Zend/tests/closure/042.phpt similarity index 100% rename from Zend/tests/closure_042.phpt rename to Zend/tests/closure/042.phpt diff --git a/Zend/tests/closure_043.phpt b/Zend/tests/closure/043.phpt similarity index 100% rename from Zend/tests/closure_043.phpt rename to Zend/tests/closure/043.phpt diff --git a/Zend/tests/closure_044.phpt b/Zend/tests/closure/044.phpt similarity index 100% rename from Zend/tests/closure_044.phpt rename to Zend/tests/closure/044.phpt diff --git a/Zend/tests/closure_045.phpt b/Zend/tests/closure/045.phpt similarity index 100% rename from Zend/tests/closure_045.phpt rename to Zend/tests/closure/045.phpt diff --git a/Zend/tests/closure_046.phpt b/Zend/tests/closure/046.phpt similarity index 100% rename from Zend/tests/closure_046.phpt rename to Zend/tests/closure/046.phpt diff --git a/Zend/tests/closure_047.phpt b/Zend/tests/closure/047.phpt similarity index 100% rename from Zend/tests/closure_047.phpt rename to Zend/tests/closure/047.phpt diff --git a/Zend/tests/closure_048.phpt b/Zend/tests/closure/048.phpt similarity index 100% rename from Zend/tests/closure_048.phpt rename to Zend/tests/closure/048.phpt From 3c165fb71eeb5f4776de6471b4c4f9ccfebacabb Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 20:35:19 -0600 Subject: [PATCH 2/9] Added two new tests to deal with closures --- Zend/tests/closure/049.phpt | 24 ++++++++++++++++++++++++ Zend/tests/closure/050.phpt | 25 +++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 Zend/tests/closure/049.phpt create mode 100644 Zend/tests/closure/050.phpt diff --git a/Zend/tests/closure/049.phpt b/Zend/tests/closure/049.phpt new file mode 100644 index 0000000000000..f7c480829bdcb --- /dev/null +++ b/Zend/tests/closure/049.phpt @@ -0,0 +1,24 @@ +--TEST-- +Closure 049: static closure in non-static method. + +--FILE-- +a(); +var_dump($method); +var_dump($closure); +--EXPECT-- +string(1) "B" +string(1) "B" diff --git a/Zend/tests/closure/050.phpt b/Zend/tests/closure/050.phpt new file mode 100644 index 0000000000000..2d4c68128fa4f --- /dev/null +++ b/Zend/tests/closure/050.phpt @@ -0,0 +1,25 @@ +--TEST-- +Closure 050: non-static closure in non-static method. + +--FILE-- +a(); +var_dump($method); +var_dump($closure); + +--EXPECT-- +string(1) "B" +string(1) "B" From 87f00c2703577e97a8aac0c6a4444c63db43b8ef Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 20:39:08 -0600 Subject: [PATCH 3/9] Initial attempt at fixing bug 66622; didn't quite get it right --- Zend/zend_closures.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index d714b35b399e1..0e51faf350eca 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -489,6 +489,10 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { closure->this_ptr = this_ptr; Z_ADDREF_P(this_ptr); + } else if(closure->func.common.fn_flags & ZEND_ACC_STATIC) { + closure->func.common.scope = EG(called_scope); + closure->func.common.fn_flags |= ZEND_ACC_STATIC; + closure->this_ptr = NULL; } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; closure->this_ptr = NULL; From f810ef68f1708ac3df18f6bb84a44f50a64c4454 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 20:45:33 -0600 Subject: [PATCH 4/9] Pretty sure that line is unneeded. --- Zend/zend_closures.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 0e51faf350eca..e4b7228c2d970 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -491,7 +491,6 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent Z_ADDREF_P(this_ptr); } else if(closure->func.common.fn_flags & ZEND_ACC_STATIC) { closure->func.common.scope = EG(called_scope); - closure->func.common.fn_flags |= ZEND_ACC_STATIC; closure->this_ptr = NULL; } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; From 7539af6f734f7af907a42e0cd8f1a0278bf42c24 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 20:56:18 -0600 Subject: [PATCH 5/9] Added test case from bug report (except the non-static method calls that were called statically) --- Zend/tests/closure/bug66622.phpt | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Zend/tests/closure/bug66622.phpt diff --git a/Zend/tests/closure/bug66622.phpt b/Zend/tests/closure/bug66622.phpt new file mode 100644 index 0000000000000..f9f02acb412fa --- /dev/null +++ b/Zend/tests/closure/bug66622.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug 66622: Closures do not correctly capture the late bound class (static::) in some cases + +--FILE-- +foo(); + (new B)->bar(); + (new B)->baz(); + B::baz(); +} +test(); + +--EXPECT-- +B vs B +B vs B +B vs B +B vs B From 76adf726a27232cf3fbc796aa25becbd5b095f22 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 21:38:06 -0600 Subject: [PATCH 6/9] Class A's method a was considered a PHP4 constructor... fixing --- Zend/tests/closure/049.phpt | 4 ++-- Zend/tests/closure/050.phpt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/tests/closure/049.phpt b/Zend/tests/closure/049.phpt index f7c480829bdcb..3954307d2d3af 100644 --- a/Zend/tests/closure/049.phpt +++ b/Zend/tests/closure/049.phpt @@ -5,7 +5,7 @@ Closure 049: static closure in non-static method. a(); +list($method, $closure) = $b->foo(); var_dump($method); var_dump($closure); --EXPECT-- diff --git a/Zend/tests/closure/050.phpt b/Zend/tests/closure/050.phpt index 2d4c68128fa4f..32cf1347edf9b 100644 --- a/Zend/tests/closure/050.phpt +++ b/Zend/tests/closure/050.phpt @@ -5,7 +5,7 @@ Closure 050: non-static closure in non-static method. a(); +list($method, $closure) = $b->foo(); var_dump($method); var_dump($closure); From 3866c1ce787d0a2f5a012be5e25b4e8ba3247130 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Fri, 9 May 2014 22:33:18 -0600 Subject: [PATCH 7/9] A tinsy bit closer to fixing bug 66622 --- Zend/zend_closures.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index e4b7228c2d970..031662517e913 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -480,6 +480,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent } } + zend_function *active_op_array = EG(active_op_array); /* Invariants: * If the closure is unscoped, it has no bound object. * The the closure is scoped, it's either static or it's bound */ @@ -489,8 +490,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { closure->this_ptr = this_ptr; Z_ADDREF_P(this_ptr); - } else if(closure->func.common.fn_flags & ZEND_ACC_STATIC) { + } else if(closure->func.common.fn_flags & ZEND_ACC_STATIC || active_op_array->common.fn_flags & ZEND_ACC_STATIC) { closure->func.common.scope = EG(called_scope); + closure->func.common.fn_flags |= ZEND_ACC_STATIC; closure->this_ptr = NULL; } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; From f6f4cb6c84aba5fb29d7ead395a42f2816e1b480 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sat, 10 May 2014 10:49:55 -0600 Subject: [PATCH 8/9] Fixed bug 66622 without breaking anything \o/ --- Zend/zend_closures.c | 9 +-------- Zend/zend_vm_def.h | 8 +++++++- Zend/zend_vm_execute.h | 8 +++++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 031662517e913..bd2ede329d7fa 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -480,7 +480,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent } } - zend_function *active_op_array = EG(active_op_array); + closure->this_ptr = NULL; /* Invariants: * If the closure is unscoped, it has no bound object. * The the closure is scoped, it's either static or it's bound */ @@ -490,16 +490,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { closure->this_ptr = this_ptr; Z_ADDREF_P(this_ptr); - } else if(closure->func.common.fn_flags & ZEND_ACC_STATIC || active_op_array->common.fn_flags & ZEND_ACC_STATIC) { - closure->func.common.scope = EG(called_scope); - closure->func.common.fn_flags |= ZEND_ACC_STATIC; - closure->this_ptr = NULL; } else { closure->func.common.fn_flags |= ZEND_ACC_STATIC; - closure->this_ptr = NULL; } - } else { - closure->this_ptr = NULL; } } /* }}} */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 195772a3954c1..0ab4b9462a5f3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5408,7 +5408,13 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + int defined_function_is_static = op_array->common.fn_flags & ZEND_ACC_STATIC; + int function_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC; + if (defined_function_is_static || function_is_being_defined_inside_static_context) { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC); + } else { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4690c3e3ae117..cf38c7dab6f2d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6789,7 +6789,13 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + int defined_function_is_static = op_array->common.fn_flags & ZEND_ACC_STATIC; + int function_is_being_defined_inside_static_context = EX(prev_execute_data) && EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC; + if (defined_function_is_static || function_is_being_defined_inside_static_context) { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC); + } else { + zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC); + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); From 7912ad0fbe8d91546372cb7614828f2ef8d79021 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sun, 11 May 2014 21:29:26 -0600 Subject: [PATCH 9/9] Added a bunch of small, easy to diagnose tests for closures in various contexts --- Zend/tests/closure/049.phpt | 9 +++------ Zend/tests/closure/050.phpt | 9 +++------ Zend/tests/closure/051.phpt | 21 +++++++++++++++++++++ Zend/tests/closure/052.phpt | 21 +++++++++++++++++++++ Zend/tests/closure/053.phpt | 22 ++++++++++++++++++++++ Zend/tests/closure/054.phpt | 22 ++++++++++++++++++++++ Zend/tests/closure/055.phpt | 21 +++++++++++++++++++++ Zend/tests/closure/056.phpt | 21 +++++++++++++++++++++ 8 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 Zend/tests/closure/051.phpt create mode 100644 Zend/tests/closure/052.phpt create mode 100644 Zend/tests/closure/053.phpt create mode 100644 Zend/tests/closure/054.phpt create mode 100644 Zend/tests/closure/055.phpt create mode 100644 Zend/tests/closure/056.phpt diff --git a/Zend/tests/closure/049.phpt b/Zend/tests/closure/049.phpt index 3954307d2d3af..e812c9fe729a7 100644 --- a/Zend/tests/closure/049.phpt +++ b/Zend/tests/closure/049.phpt @@ -1,5 +1,5 @@ --TEST-- -Closure 049: static closure in non-static method. +Closure 049: static::class in static closure in non-static method. --FILE-- foo(); -var_dump($method); -var_dump($closure); +var_dump($b->foo()); --EXPECT-- string(1) "B" -string(1) "B" diff --git a/Zend/tests/closure/050.phpt b/Zend/tests/closure/050.phpt index 32cf1347edf9b..d43f325ef1f67 100644 --- a/Zend/tests/closure/050.phpt +++ b/Zend/tests/closure/050.phpt @@ -1,5 +1,5 @@ --TEST-- -Closure 050: non-static closure in non-static method. +Closure 050: static::class in non-static closure in non-static method. --FILE-- foo(); -var_dump($method); -var_dump($closure); +var_dump($b->foo()); --EXPECT-- string(1) "B" -string(1) "B" diff --git a/Zend/tests/closure/051.phpt b/Zend/tests/closure/051.phpt new file mode 100644 index 0000000000000..78b28d74a33d7 --- /dev/null +++ b/Zend/tests/closure/051.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 051: static::class in static closure in static method. + +--FILE-- +foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure/054.phpt b/Zend/tests/closure/054.phpt new file mode 100644 index 0000000000000..b2f87d1d6109f --- /dev/null +++ b/Zend/tests/closure/054.phpt @@ -0,0 +1,22 @@ +--TEST-- +Closure 054: self::class in non-static closure in non-static method. + +--FILE-- +foo()); + +--EXPECT-- +string(1) "A" diff --git a/Zend/tests/closure/055.phpt b/Zend/tests/closure/055.phpt new file mode 100644 index 0000000000000..047d72a89bd61 --- /dev/null +++ b/Zend/tests/closure/055.phpt @@ -0,0 +1,21 @@ +--TEST-- +Closure 055: self::class in static closure in static method. + +--FILE-- +