- Add runtime check mechanism for objects that require value validation - Prevent null assignment to typed objects after unset with proper error message - Disable native call optimizations when object values become unpredictable - Maintain class constraints even after unset and reassignment - Generate appropriate error handling for invalid object operations - Update SSA analysis to recognize unset operations as dangerous for property hoisting - Add comprehensive tests for typed object unset behavior scenariospull/47/head
parent
a4f1188a7e
commit
70927ee68a
17 changed files with 232 additions and 11 deletions
@ -0,0 +1,22 @@ |
||||
<?php |
||||
|
||||
use native_types; |
||||
|
||||
class NativePropertyUnsetDisablesHoist |
||||
{ |
||||
public int $value = 7; |
||||
|
||||
public function run(): void |
||||
{ |
||||
var_dump($this->value); |
||||
unset($this->value); |
||||
var_dump($this->value); |
||||
$this->value = 11; |
||||
var_dump($this->value); |
||||
} |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
(new NativePropertyUnsetDisablesHoist())->run(); |
||||
} |
||||
@ -0,0 +1,12 @@ |
||||
<?php |
||||
|
||||
class TypedObjectUnsetNullValue |
||||
{ |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$value = new TypedObjectUnsetNullValue(); |
||||
unset($value); |
||||
$value = null; |
||||
} |
||||
@ -0,0 +1,58 @@ |
||||
--TEST-- |
||||
unset typed object retains its declared class constraint on reassignment |
||||
--FILE-- |
||||
<?php |
||||
class UnsetReassignExpected |
||||
{ |
||||
public function value(): string |
||||
{ |
||||
return 'expected'; |
||||
} |
||||
} |
||||
|
||||
class UnsetReassignOther |
||||
{ |
||||
} |
||||
|
||||
function makeUnsetReassignExpected(): UnsetReassignExpected |
||||
{ |
||||
return new UnsetReassignExpected(); |
||||
} |
||||
|
||||
function makeUnsetReassignOtherDynamic(): mixed |
||||
{ |
||||
return new UnsetReassignOther(); |
||||
} |
||||
|
||||
function makeUnsetReassignNullDynamic(): mixed |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
function main() |
||||
{ |
||||
$value = makeUnsetReassignExpected(); |
||||
unset($value); |
||||
|
||||
try { |
||||
$value = makeUnsetReassignOtherDynamic(); |
||||
echo "invalid assignment accepted\n"; |
||||
} catch (Throwable $error) { |
||||
echo $error::class, "\n"; |
||||
} |
||||
|
||||
try { |
||||
$value = makeUnsetReassignNullDynamic(); |
||||
echo "null assignment accepted\n"; |
||||
} catch (Throwable $error) { |
||||
echo $error::class, "\n"; |
||||
} |
||||
|
||||
$value = makeUnsetReassignExpected(); |
||||
var_dump($value->value()); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
TypeError |
||||
TypeError |
||||
string(8) "expected" |
||||
@ -0,0 +1,58 @@ |
||||
--TEST-- |
||||
unset typed object invalidates native-call assumptions and reads as null |
||||
--FILE-- |
||||
<?php |
||||
class UnsetTypedObjectValue |
||||
{ |
||||
public function value(): string |
||||
{ |
||||
return 'value'; |
||||
} |
||||
} |
||||
|
||||
function makeUnsetTypedObjectValue(): UnsetTypedObjectValue |
||||
{ |
||||
return new UnsetTypedObjectValue(); |
||||
} |
||||
|
||||
function acceptUnsetTypedObjectValue(UnsetTypedObjectValue $value): string |
||||
{ |
||||
echo "entered\n"; |
||||
return $value->value(); |
||||
} |
||||
|
||||
function main() |
||||
{ |
||||
$value = makeUnsetTypedObjectValue(); |
||||
unset($value); |
||||
|
||||
var_dump(@$value === null); |
||||
var_dump(@$value instanceof UnsetTypedObjectValue); |
||||
var_dump(isset($value)); |
||||
|
||||
try { |
||||
acceptUnsetTypedObjectValue(@$value); |
||||
} catch (Throwable $error) { |
||||
echo $error::class, "\n"; |
||||
} |
||||
|
||||
try { |
||||
@$value->value(); |
||||
} catch (Throwable $error) { |
||||
echo $error::class, "\n"; |
||||
} |
||||
|
||||
$value = makeUnsetTypedObjectValue(); |
||||
var_dump(acceptUnsetTypedObjectValue($value)); |
||||
var_dump($value->value()); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
bool(true) |
||||
bool(false) |
||||
bool(false) |
||||
TypeError |
||||
Error |
||||
entered |
||||
string(5) "value" |
||||
string(5) "value" |
||||
Loading…
Reference in new issue