Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/add_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: add operator with scalars
class A {
public int $value;

public function __add(int $other, bool $left): A
public operator +(int $other, bool $left): A
{
$return = new A();
$return->value = $this->value + $other;
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/div_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: div operator with scalars
class A {
public int $value;

public function __div(int $other, bool $left): A
public operator /(int $other, bool $left): A
{
$return = new A();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: equals fallback to comparison operator
class A {
public int $value;

public function __compareto(mixed $other): int
public operator <=>(mixed $other): int
{
return ($this->value <=> $other);
}
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/equals_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: equals operator
class A {
public int $value;

public function __equals(mixed $other): bool
public operator ==(mixed $other): bool
{
return ($this->value == $other);
}
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/mod_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: mod operator with scalars
class A {
public int $value;

public function __mod(int $other, bool $left): A
public operator %(int $other, bool $left): A
{
$return = new A();

Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/mul_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: mul operator with scalars
class A {
public int $value;

public function __mul(int $other, bool $left): A
public operator *(int $other, bool $left): A
{
$return = new A();
$return->value = $this->value * $other;
Expand Down
4 changes: 2 additions & 2 deletions Zend/tests/operator_overloads/operator_omitted_type.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: no explicit type
class A {
public int $value;

public function __add($other, bool $left): self
public operator +($other, bool $left): self
{
$return = new A();
$return->value = $this->value + $other;
Expand All @@ -16,4 +16,4 @@ class A {
}
?>
--EXPECTF--
Fatal error: A::__add(): Parameter #1 ($other) must explicitly define a type in %s on line %d
Fatal error: A::+(): Parameter #1 ($other) must explicitly define a type in %s on line %d
94 changes: 47 additions & 47 deletions Zend/tests/operator_overloads/operator_overloaded.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,64 @@ operator overload: overload called
<?php

class A {
public function __add(mixed $other, bool $left): self
public operator +(mixed $other, bool $left): self
{
echo "__add() called\n";
echo "+() called\n";
return $this;
}
public function __sub(mixed $other, bool $left): self
public operator -(mixed $other, bool $left): self
{
echo "__sub() called\n";
echo "-() called\n";
return $this;
}
public function __mul(mixed $other, bool $left): self
public operator *(mixed $other, bool $left): self
{
echo "__mul() called\n";
echo "*() called\n";
return $this;
}
public function __div(mixed $other, bool $left): self
public operator /(mixed $other, bool $left): self
{
echo "__div() called\n";
echo "/() called\n";
return $this;
}
public function __mod(mixed $other, bool $left): self
public operator %(mixed $other, bool $left): self
{
echo "__mod() called\n";
echo "%() called\n";
return $this;
}
public function __pow(mixed $other, bool $left): self
public operator **(mixed $other, bool $left): self
{
echo "__pow() called\n";
echo "**() called\n";
return $this;
}
public function __bitwiseAnd(mixed $other, bool $left): self
public operator &(mixed $other, bool $left): self
{
echo "__bitwiseAnd() called\n";
echo "&() called\n";
return $this;
}
public function __bitwiseOr(mixed $other, bool $left): self
public operator |(mixed $other, bool $left): self
{
echo "__bitwiseOr() called\n";
echo "|() called\n";
return $this;
}
public function __bitwiseXor(mixed $other, bool $left): self
public operator ^(mixed $other, bool $left): self
{
echo "__bitwiseXor() called\n";
echo "^() called\n";
return $this;
}
public function __bitwiseNot(): self
public operator ~(): self
{
echo "__bitwiseNot() called\n";
echo "~() called\n";
return $this;
}
public function __bitwiseShiftLeft(mixed $other, bool $left): self
public operator <<(mixed $other, bool $left): self
{
echo "__bitwiseShiftLeft() called\n";
echo "<<() called\n";
return $this;
}
public function __bitwiseShiftRight(mixed $other, bool $left): self
public operator >>(mixed $other, bool $left): self
{
echo "__bitwiseShiftRight() called\n";
echo ">>() called\n";
return $this;
}
}
Expand Down Expand Up @@ -94,26 +94,26 @@ $obj >> 1;

?>
--EXPECT--
__add() called
__add() called
__sub() called
__sub() called
__mul() called
__mul() called
__div() called
__div() called
__mod() called
__mod() called
__pow() called
__pow() called
__bitwiseAnd() called
__bitwiseAnd() called
__bitwiseOr() called
__bitwiseOr() called
__bitwiseXor() called
__bitwiseXor() called
__bitwiseShiftLeft() called
__bitwiseShiftLeft() called
__bitwiseShiftRight() called
__bitwiseShiftRight() called
__bitwiseNot() called
+() called
+() called
-() called
-() called
*() called
*() called
/() called
/() called
%() called
%() called
**() called
**() called
&() called
&() called
|() called
|() called
^() called
^() called
<<() called
<<() called
>>() called
>>() called
~() called
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/operator_unimplemented.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class A {
class B {
public int $value;

public function __add(int|A $other, bool $left): B
public operator +(int|A $other, bool $left): B
{
$return = new B();
if (is_int($other)) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/pow_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: pow operator with scalars
class A {
public int $value;

public function __pow(int $other, bool $left): A
public operator **(int $other, bool $left): A
{
$return = new A();

Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/operator_overloads/sub_operator.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ operator overload: sub operator with scalars
class A {
public int $value;

public function __sub(int $other, bool $left): A
public operator -(int $other, bool $left): A
{
$return = new A();

Expand Down
112 changes: 58 additions & 54 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -2551,6 +2551,41 @@ static void zend_check_magic_method_equality_operator_overload(

ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */
{
if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) {
zend_check_magic_method_unary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) {
zend_check_magic_method_equality_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) {
zend_check_magic_method_args(1, ce, fptr, error_type);
zend_check_magic_method_non_static(ce, fptr, error_type);
zend_check_magic_method_public(ce, fptr, error_type);
zend_check_magic_method_explicit_type(0, ce, fptr, error_type);
zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY);
zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG);
}

if (ZSTR_VAL(fptr->common.function_name)[0] != '_'
|| ZSTR_VAL(fptr->common.function_name)[1] != '_') {
return;
Expand Down Expand Up @@ -2642,45 +2677,42 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce,
zend_check_magic_method_non_static(ce, fptr, error_type);
zend_check_magic_method_public(ce, fptr, error_type);
zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID);
} else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
}
}
/* }}} */

ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname)
{
if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) {
ce->__add = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__sub = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__mul = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__div = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__mod = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__pow = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__bitwiseand = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__bitwiseor = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__bitwisexor = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) {
ce->__bitwisenot = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
ce->__bitwiseshiftleft = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) {
zend_check_magic_method_binary_operator_overload(ce, fptr, error_type);
} else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) {
zend_check_magic_method_unary_operator_overload(ce, fptr, error_type);
ce->__bitwiseshiftright = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) {
zend_check_magic_method_equality_operator_overload(ce, fptr, error_type);
ce->__equals = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) {
zend_check_magic_method_args(1, ce, fptr, error_type);
zend_check_magic_method_non_static(ce, fptr, error_type);
zend_check_magic_method_public(ce, fptr, error_type);
zend_check_magic_method_explicit_type(0, ce, fptr, error_type);
zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ANY);
zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_LONG);
ce->__compareto = fptr;
}
}
/* }}} */

ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname)
{

if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') {
/* pass */
} else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) {
Expand Down Expand Up @@ -2714,34 +2746,6 @@ ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, z
ce->__serialize = fptr;
} else if (zend_string_equals_literal(lcname, "__unserialize")) {
ce->__unserialize = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_ADD_FUNC_NAME)) {
ce->__add = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_SUB_FUNC_NAME)) {
ce->__sub = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_MUL_FUNC_NAME)) {
ce->__mul = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_DIV_FUNC_NAME)) {
ce->__div = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_MOD_FUNC_NAME)) {
ce->__mod = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_POW_FUNC_NAME)) {
ce->__pow = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWAND_FUNC_NAME)) {
ce->__bitwiseand = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWOR_FUNC_NAME)) {
ce->__bitwiseor = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWXOR_FUNC_NAME)) {
ce->__bitwisexor = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWNOT_FUNC_NAME)) {
ce->__bitwisenot = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWSL_FUNC_NAME)) {
ce->__bitwiseshiftleft = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_BWSR_FUNC_NAME)) {
ce->__bitwiseshiftright = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_EQ_FUNC_NAME)) {
ce->__equals = fptr;
} else if (zend_string_equals_literal(lcname, ZEND_COMPARE_FUNC_NAME)) {
ce->__compareto = fptr;
}
}

Expand Down
Loading