Commit Graph

2723 Commits

Author SHA1 Message Date
Nikita Popov
2772751b58 Make constexpr compilation robust against multiple compilation
Instead of setting the old AST type to zero, replace the AST with
the compiled constexpr AST zval. This requires passing in a
zend_ast** instead of a zend_ast*.

This allows compiling ASTs containing constexprs multiple times
-- the second time, the existing compiled representation will be
resused.

This means we no longer need to copy the attributes AST for
promoted properties.
2020-09-27 11:24:22 +02:00
Nikita Popov
5686c16db4 Honor strict_types=1 for attributes, improve backtraces
Make ReflectionAttribute::newInstance() respect the strict_types=1
declaration at the attribute use-site. More generally, pretend that
we are calling the attribute constructor from the place where the
attribute is used, which also means that the attribute location will
show up properly in backtraces and inside "called in" error information.

This requires us to store the attributes strict_types scope (as flags),
as well as the attribute line number. The attribute filename can be
recovered from the symbol it is used on. We might want to expose the
attribute line number via reflection as well.

See also https://externals.io/message/111915.

Closes GH-6201.
2020-09-27 10:42:58 +02:00
Nikita Popov
c5f93d191e Fix detection of code outside namespace
Due to improvements to early binding, the opcode based check is
no longer accurate. Reuse the syntactic check we're already using
for declares instead.
2020-09-21 12:37:44 +02:00
Nikita Popov
34bb5ba2ea Remove support for EXT_NOP
This is an annoying edge case that regularly gets broken. As we're
not aware of significant users of this API, and there are other
ways to hook this, remove support for EXT_NOP.
2020-09-18 11:03:08 +02:00
Nikita Popov
16b9f19678 Fix compile-time/run-time discrepancies with unary operators
This addresses two issues:
 * ~ throws for a number of types, and we should not compile-time
   evaluate in that case. Add a check similar to what we do for
   binary ops.
 * Unary +/- may produce a different error message due to
   canonicalization of the constant operand to the RHS. To avoid
   this, put the constant operand on the RHS right away.

Fixes oss-fuzz #25649.
2020-09-15 15:08:55 +02:00
Tyson Andre
09904242af Avoid gap in AST_CLASS child nodes for attributes
See https://github.com/nikic/php-ast/pull/181

> Hm, I'm thinking it would make more sense to change the structure in php-src.
> All the function types have consistent AST structure, but there's no reason at
> all why classes should be consistent with functions.

It's unusual to have an unused child node between other child nodes that are
used (for name, extends, implements, and attributes of AST_CLASS)

> That gap is a leftover from a previous refactoring. An earlier version of
> attributes extended `zend_ast_decl` with a new member called `attributes` and
> therefore did not need to handle functions and classes in different ways.

Closes GH-6088
2020-09-10 09:33:46 -04:00
Ilija Tovilo
8a49310f4e
Adjust assignment line number for match
Otherwise the assignment will have the same number as the default arm
which will 1. mis-trigger a breakpoint and 2. mark the line as covered
even when it isn't.

Closes GH-6083
2020-09-08 00:08:18 +02:00
Nikita Popov
f5dbebd82e Accept zend_string instead of zval in zend_compile_string 2020-09-07 11:42:21 +02:00
Nikita Popov
9464576f29 Fix leaks in sapi tests
Make sure to always free compiled_filename on shutdown.
2020-09-03 12:59:30 +02:00
Nikita Popov
7620ea1580 Don't intern compiled_filename
For php-ast interning the file name is an effective memory leak,
see php-ast#134.

I don't think there's any reason to do this. At some point this
was needed due to bugs in the interned string mechanism that
caused issues if the string was later interned, e.g. through a
__FILE__ reference. These issues have since been resolved.

In conjunction with the filenames_table removal in c4016ecd44
this means that filenames now need to be refcounted like normal
strings. In particular the filename reference in op_arrays and CEs
are refcounted.
2020-09-03 12:31:23 +02:00
Nikita Popov
c4016ecd44 Remove CG(filenames_table)
This doesn't seem to serve any purpose anymore.
2020-09-03 11:33:54 +02:00
Benjamin Eberlei
8b37c1e993 Change Attribute Syntax from @@ to #[] 2020-09-02 20:26:50 +02:00
Nikita Popov
8b6b2bda09 Fix by-ref list assign LIST_W+MAKE_REF separation
Shift the responsibility for emitting MAKE_REF to the list assignment
code, to make sure that LIST_W and MAKE_REF are directly adjacent,
and there are no opcodes in between that could modify the LIST_W
result.

Additionally, adjust the zend_wrong_string_offset() code to not
perform a loop over opcodes and assert that the next opcode is
a relevant one. The VM write-safety model requires this.

This is a followup to a07c1f56aa
and the full fix for oss-fuzz #25352.
2020-09-02 10:26:55 +02:00
Nikita Popov
2022f2e5c9 Fix nullsafe operator with delayed oplines
Closes GH-6056.
2020-08-31 16:44:36 +02:00
Nikita Popov
86364013f9 Avoid ubsan warning with dummy cache slot addr 2020-08-28 17:24:21 +02:00
George Peter Banyard
fa8d9b1183 Improve type declarations for Zend APIs
Voidification of Zend API which always succeeded
Use bool argument types instead of int for boolean arguments
Use bool return type for functions which return true/false (1/0)
Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics

Closes GH-6002
2020-08-28 15:41:27 +02:00
George Peter Banyard
1b2ec73c1d Drop various unused macros/APIs
Also convert_libmagic_pattern() to return a zend_string*

Closes GH-6029
2020-08-26 12:59:43 +02:00
Nikita Popov
1954aed745 Fix over-eager named params optimization
We can't relax a named param to a positional param if we encountered
any unknown parameters in the meantime.
2020-08-26 11:01:15 +02:00
Nikita Popov
227f1f1481 Fix nullsafe operator on $this 2020-08-11 15:22:14 +02:00
Nikita Popov
a4c015b4b2 Fix handling of nullsafe method in empty()
Fixes oss-fuzz #24627.
2020-08-03 10:16:38 +02:00
Nikita Popov
d92229d8c7 Implement named parameters
From an engine perspective, named parameters mainly add three
concepts:

 * The SEND_* opcodes now accept a CONST op2, which is the
   argument name. For now, it is looked up by linear scan and
   runtime cached.
 * This may leave UNDEF arguments on the stack. To avoid having
   to deal with them in other places, a CHECK_UNDEF_ARGS opcode
   is used to either replace them with defaults, or error.
 * For variadic functions, EX(extra_named_params) are collected
   and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.

RFC: https://wiki.php.net/rfc/named_params

Closes GH-5357.
2020-07-31 15:53:36 +02:00
Deus Kane
f475edc2f1 Fixed bug #79897: Promoted constructor params with attribs cause crash
This was caused by the attribute AST being used twice, and was fixed by
creating a temporary copy of it (and destroying said copy) when neccesary.
2020-07-30 11:08:31 +02:00
Nikita Popov
ee7eecf321 Fix leak with nullsafe operator with constant LHS
Followup to 5303bcdd32. We need to
perform the addref after emitting the opline, because that might
intern the string.

Fixes oss-fuzz #24479.
2020-07-29 15:51:47 +02:00
Nikita Popov
5303bcdd32 Fix use-after-free when nullsafe used with constant LHS
Fixes oss-fuzz #24436.
2020-07-28 09:48:13 +02:00
Nikita Popov
08e6c20955 Fix null pointer deref in compile_return()
Fixes oss-fuzz #24387.
2020-07-27 10:27:26 +02:00
Nikita Popov
0a5b7c81b7 Make nested ternary without parentheses a compile error
This was deprecated in PHP 7.4.
2020-07-24 10:35:42 +02:00
Ilija Tovilo
9bf119832d
Implement nullsafe ?-> operator
RFC: https://wiki.php.net/rfc/nullsafe_operator

Closes GH-5619.

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
2020-07-24 10:05:03 +02:00
Nikita Popov
7a3dcc3e33 Treat namespaced names as single token
Namespace names are now lexed as single tokens of type
T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED or T_NAME_RELATIVE.

RFC: https://wiki.php.net/rfc/namespaced_names_as_token

Closes GH-5827.
2020-07-22 12:36:05 +02:00
Nikita Popov
7fd4212cc0 Add common code for magic method assignment
This was repeated three times.
2020-07-20 14:57:10 +02:00
Nikita Popov
149029b9d6 Unify magic method visibility check
This was missing entirely for the internal function case.
2020-07-20 11:12:47 +02:00
Nikita Popov
312fe2bdce Unify magic method return type checks 2020-07-20 10:51:48 +02:00
Nikita Popov
fbbcf82ab7 Unify static/non-static check for magic methods
And promote it to be fatal.
2020-07-20 10:39:43 +02:00
Nikita Popov
86a62eb1fc Fixed bug #79867
In line with usual rules, give untyped properties a null default
value. Otherwise constructor promotion would give you a property
declaration that cannot be achieved through any other means.
2020-07-17 15:10:45 +02:00
Pedro Magalhães
272b887b7b Ignore inheritance rules on private methods
Closes GH-5401
2020-07-15 17:09:57 +01:00
Ilija Tovilo
1c967df5a0
Fix free of uninitialized memory in MATCH_ERROR
As suggested by Tyson Andre:
https://github.com/php/php-src/pull/5371#issuecomment-657081464

Also fix line number of unhandled match error

Closes GH-5841.
2020-07-12 13:33:36 +02:00
Máté Kocsis
d30cd7d7e7
Review the usage of apostrophes in error messages
Closes GH-5590
2020-07-10 21:05:28 +02:00
Nikita Popov
5fc70243d7 Add missing addref for MATCH_ERROR operand 2020-07-10 15:58:42 +02:00
Ilija Tovilo
9fa1d13301
Implement match expression
RFC: https://wiki.php.net/rfc/match_expression_v2

Closes GH-5371.
2020-07-09 23:52:17 +02:00
Nikita Popov
2af1d36bc5 Skip special function optimization for redeclared disabled functions
As pointed out on GH-5817.
2020-07-08 10:11:00 +02:00
Nikita Popov
1e39469678 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #79783
2020-07-07 09:57:07 +02:00
Nikita Popov
971e5c5186 Fixed bug #79783
Make sure we don't drop the by-reference check when passing the
result of a VM builtin function.
2020-07-07 09:56:14 +02:00
moliata
4a0d6901bb refactor: class constants parsing
As part of my work on typed class constants, I wanted to make a
separate pull request for unrelated changes.

These include:

 * Moving from ast->child[0]->attr to ast->attr
 * Making zend_ast_export_ex() export class constants' visibility
 * Extracting an additional zend_compile_class_const_group() function

Closes GH-5812.
2020-07-06 18:34:41 +02:00
Nikita Popov
6a195cacf3 Treat attribute argument lists like normal argument lists
Allow trailing comma. Syntactically allow unpacking, but forbid it
during compilation.

The trailing comma test-case is adopted from GH-5796.
2020-07-02 15:27:45 +02:00
Martin Schröder
053ef28b8d Implement Attribute Amendments.
RFC: https://wiki.php.net/rfc/attribute_amendments

Support for attribute grouping is left out, because the short
attribute syntax RFC will likely make it obsolete.

Closes GH-5751.
2020-06-29 10:45:51 +02:00
Nikita Popov
1314ccbf8c Cache __unserialize() instead of unserialize()
We should use these cache slots for the new object serialization
mechanism rather than the old one.
2020-06-26 10:54:40 +02:00
Nikita Popov
c5caa05171 Fixed bug #79740 2020-06-26 10:31:55 +02:00
moliata
48e16a9dba Use ZEND_TOSTRING_FUNC_NAME
Closes GH-5736.
2020-06-18 17:06:19 +02:00
moliata
45d1c38dab Use zend_is_constructor() 2020-06-17 16:46:17 +02:00
Christoph M. Becker
92c4b06513 Use ZEND_UNREACHABLE() instead of ZEND_ASSERT(0)
Instead of marking unreachable code with `ZEND_ASSERT(0)`, we introduce
`ZEND_UNREACHABLE()`, so that MSVC which does not consider `assert(0)`
to mark unreachable code does no longer trigger C4715[1] warnings in
debug builds.  This may be useful for other compilers as well.

[1] <https://docs.microsoft.com/de-de/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4715?view=vs-2019>
2020-06-16 18:39:09 +02:00
twosee
83a77015ad Add helper APIs for maybe-interned string creation
Add ZVAL_CHAR/RETVAL_CHAR/RETURN_CHAR as a shortcut for using
ZVAL_INTERNED_STRING and ZSTR_CHAR.

Add zend_string_init_fast() as a helper for the empty string /
one char interned string / zend_string_init() pattern.

Also add corresponding ZVAL_STRINGL_FAST etc macros.

Closes GH-5684.
2020-06-08 15:31:52 +02:00
Nikita Popov
b03cafd19c Fix bug #77966: Cannot alias a method named "namespace"
This is a bit tricky: In this cases we have "namespace as", which
means that we will only recognize "namespace" as an identifier when
the lookahead token is already at the "as". This means that
zend_lex_tstring picks up the wrong identifier.

We solve this by actually assigning the identifier as the semantic
value on the parser stack -- as in almost all cases we will not
actually need the identifier, this is just an (offset, size)
reference, not a copy of the string.

Additionally, we need to teach the lexer feedback mechanism used
by tokenizer TOKEN_PARSE mode to apply feedback to something
other than the very last token. To that purpose we pass through
the token text and check the tokens in reverse order to find the
right one.

Closes GH-5668.
2020-06-08 12:55:14 +02:00
twosee
88355dd338 Constify char * arguments of APIs
Closes GH-5676.
2020-06-08 10:38:45 +02:00
twosee
7d6a0ba808 Fix expression warnings and break warnings
Close GH-5675.
2020-06-07 10:41:11 +02:00
Nikita Popov
064b464448 Implement "Constructor Promotion" RFC
RFC: https://wiki.php.net/rfc/constructor_promotion

Closes GH-5291.
2020-06-05 15:15:51 +02:00
Benjamin Eberlei
a7908c2d11 Add Attributes
Co-authored-by: Martin Schröder <m.schroeder2007@gmail.com>
2020-06-04 18:19:49 +02:00
Máté Kocsis
dd6e54b746
Fix #79652 Ensure that the mixed type is displayed instead of the union of all types
Closes GH-56430
2020-05-30 08:58:59 +02:00
Nikita Popov
baa285881f Fix variable type
This is no longer a boolean.
2020-05-26 15:58:36 +02:00
Tyson Andre
9b33272536 Allow generators to have a real return type of mixed or object
Fixes an edge case overlooked in
https://github.com/php/php-src/pull/5313

Generators are objects, so `object` should have also been allowed in addition to
`iterable` and `Traversable`

Closes GH-5626
2020-05-26 09:57:10 -04:00
Max Semenik
23ee4d4b57 Support catching exceptions without capturing them to variables
RFC: https://wiki.php.net/rfc/non-capturing_catches

Closes GH-5345.
2020-05-26 15:12:18 +02:00
George Peter Banyard
c803499e23 Remove depreacted curly brace offset syntax
Closes GH-5221
2020-05-22 16:52:17 +02:00
Máté Kocsis
aec4c0fd03
Add support for the mixed type
RFC: https://wiki.php.net/rfc/mixed_type_v2
Closes GH-5313

Co-authored-by: Dan Ackroyd <danack@basereality.com>
2020-05-22 16:08:12 +02:00
Nikita Popov
c2068e95b4 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fix bug #79603, by retrying on RTD key collision
2020-05-20 11:24:37 +02:00
Nikita Popov
4f47ba99f0 Fix bug #79603, by retrying on RTD key collision
This is a non-intrusive fix for 7.4, still trying to find a good
solution for master.

Closes GH-5597.
2020-05-20 11:22:50 +02:00
Nikita Popov
c6a6ca078b Use zend_zval_type_name() API where possible
Rather than zend_get_type_by_const(Z_TYPE_P()).
2020-05-13 14:56:05 +02:00
Nikita Popov
5bc1e224db Make numeric operations on resources, arrays and objects type errors
RFC: https://wiki.php.net/rfc/arithmetic_operator_type_checks

Closes GH-5331.
2020-05-05 16:11:13 +02:00
Nikita Popov
53eee290b6 Completely remove disabled functions from function table
Currently, disabling a function only replaces the internal
function handler with one that throws a warning, and a few
places in the engine special-case such functions, such as
function_exists. This leaves us with a Schrödinger's function,
which both does not exist (function_exists returns false) and
does exist (you cannot define a function with the same name).
In particular, this prevents the implementation of robust
polyfills, as reported in https://bugs.php.net/bug.php?id=79382:

    if (!function_exists('getallheaders')) {
        function getallheaders(...) { ... }
    }

If getallheaders() is a disabled function, this code will break.

This patch changes disable_functions to remove the functions from
the function table completely. For all intents and purposes, it
will look like the function does not exist.

This also renders two bits of PHP functionality obsolete and thus
deprecated:

 * ReflectionFunction::isDisabled(), as it will no longer be
   possible to construct the ReflectionFunction of a disabled
   function in the first place.
 * get_defined_functions() with $exclude_disabled=false, as
   get_defined_functions() now never returns disabled functions.

Fixed bug #79382.

Closes GH-5473.
2020-04-30 09:53:57 +02:00
Gabriel Caruso
34c460f329
Check __set_state structure
Fix Bug #79521.

Closes GH-5462.
2020-04-28 17:02:03 +02:00
Gabriel Caruso
7ce8c5ad89
Slipt error messages while checking magic methods attributes
Closes GH-5465
2020-04-27 16:32:00 +02:00
Nikita Popov
19e886d9d8 Avoid throw expression leaks
Mark "throw" used in expression context with a flag, and don't
treat it as a BB terminator in that case. This prevents us from
optimizing away the following opcodes as unreachable, which may
result in live ranges being dropped incorrectly.

Close GH-5450.
2020-04-27 15:22:05 +02:00
Nikita Popov
fd00c7cf10 Pass existing lcname to check_magic_method_implementation 2020-04-27 12:33:29 +02:00
Levi Morrison
90db6f2cc5 Add case insensitive find_ptr hash functions
- zend_hash_find_ptr_lc(ht, zend_string *key)
 - zend_hash_str_find_ptr_lc(ht, const char *str, size_t len)

Note that zend_hash_str_find_ptr_lc used to exist in zend_compile.c
as        zend_hash_find_ptr_lc. When exporting this I figured it
was best to use the same conventions as the rest of zend_hash.h.
2020-04-26 23:29:41 +02:00
Gabriel Caruso
6f908a0bf4
Check Serialization magic methods structure
Closes GH-5441
2020-04-26 02:16:39 +02:00
Nikita Popov
786e0ae574 Use zend_make_tmp_result() helper in more places 2020-04-24 12:10:06 +02:00
Nikita Popov
f264bf2d69 Accept result znode in zend_compile_class_decl()
Make this use the same pattern we use everywhere else.
2020-04-24 12:04:54 +02:00
Ilija Tovilo
f65240759f Use return in compile_expr for consistency 2020-04-24 12:01:10 +02:00
Ilija Tovilo
0810fcd0d0 Make throw statement an expression
RFC: https://wiki.php.net/rfc/throw_expression

This has an open issue with temporaries that are live at the time
of the throw being leaked. Landing this now for easier testing and
will revert if we cannot resolve the issue.

Closes GH-5279.
2020-04-23 12:51:23 +02:00
Nikita Popov
08c5c69eff Remove ZEND_ACC_DTOR flag
This is only used in reflection, where doing a simple string check
is acceptable.

I'm also dropping the "dtor" printing in the reflection dump.
Dtors are just one of many magic methods, I don't think there's
a point in explicitly highlighting them, when the name is already
unambiguous.
2020-04-17 15:32:47 +02:00
Gabriel Caruso
b10b73eb86
Fix magic method name 2020-04-16 10:39:25 +02:00
Gabriel Caruso
75a58ba522
Improve error messages for magic methods by appending method's class
Closes GH-5397.
2020-04-16 10:34:58 +02:00
Nikita Popov
4fb705a03d Add zend_string_concat2 API 2020-04-14 17:18:05 +02:00
Nikita Popov
bac5137e4e Add zend_create_member_string() API
This is a recurring pattern.
2020-04-14 16:52:13 +02:00
Nikita Popov
d030ddb2cd Export the zend_string_concat3() API 2020-04-09 15:06:53 +02:00
Nikita Popov
f1dd8b2af0 Make division by zero error check more accurate
For division (rather than modulus) we should check the double
value, otherwise the result might be zero after integer truncation,
but not zero as a floating point value.
2020-04-01 14:47:21 +02:00
Nikita Popov
1ed132e2e5 Unify checks for binary operator errors for ct eval
Move everything into one function and share it with opcache.
This fixes some discrepancies.
2020-04-01 14:42:58 +02:00
Nikita Popov
f74e30c07c Check abstract method signatures coming from traits
RFC: https://wiki.php.net/rfc/abstract_trait_method_validation

Closes GH-5068.
2020-03-26 10:07:22 +01:00
Nikita Popov
df79277de3 Revert "Fetch for read in nested property assignments"
This reverts commit bb43a3822e.

After thinking about this a bit more, this is now going to be
a complete solution for the "readonly properties" case, for example:

    unset($foo->readOnly->bar);

should also be legal and

    $foo->readOnly['bar'] = 42;

should also be legal if $foo->readOnly is not an array but an
ArrayAccess object.

I think it may be better to distinguish better on the BP_VAR flag
level. Reverting for now.
2020-03-18 14:54:43 +01:00
Nikita Popov
bb43a3822e Fetch for read in nested property assignments
$a->b->c = 'd';

is now compiled the same way as

    $b = $a->b;
    $b->c = 'd';

That is, we perform a read fetch on $a->b, rather than a write
fetch.

This is possible, because PHP 8 removed auto-vivification support
for objects, so $a->b->c = 'd' may no longer modify $a->b proper
(i.e. not counting interior mutability of the object).

Closes GH-5250.
2020-03-18 12:08:06 +01:00
Dmitry Stogov
78b64bd4ed Merge branch 'PHP-7.4'
* PHP-7.4:
  Check asserts early
  identation fix
  Call global code of preloaded script in global context
  Avoid "Anonymous class wasn't preloaded" error by lazely loading of not preloaded part of a preloaded script
2020-03-13 11:42:07 +03:00
Dmitry Stogov
c5159b3832 Check asserts early 2020-03-12 22:26:30 +03:00
Dmitry Stogov
2dddab01ae Avoid "Anonymous class wasn't preloaded" error by lazely loading of not preloaded part of a preloaded script 2020-03-12 16:31:24 +03:00
Nikita Popov
53efa1b0c6 Store aliased name of trait method
Currently, trait methods are aliased will continue to use the
original function name. In a few places in the codebase, we will
try to look up the actual method name instead. However, this does
not work if an aliased method is used indirectly
(https://bugs.php.net/bug.php?id=69180).

I think it would be better to instead actually change the method
name to the alias. This is in principle easy: We have to allow
function_name to be changed even if op array is otherwise shared
(similar to static_variables). This means we need to addref/release
the function_name separately, but I don't think there is a
performance concern here (especially as everything is usually
interned).

There is a bit of complication in opcache, where we need to make
sure that the function name is released the correct number of times
(interning may overwrite the name in the original op_array, but we
need to release it as many times as the op_array is shared).

Fixes bug #69180.
Fixes bug #74939.
Closes GH-5226.
2020-03-03 11:55:48 +01:00
Nikita Popov
336eb48c36 Automatically implement Stringable interface 2020-03-02 15:25:33 +01:00
Nicolas Grekas
9e775db025 Define Stringable with __toString():string method 2020-03-02 15:25:32 +01:00
Nikita Popov
819a872cfa Avoid more null arithmetic 2020-02-27 14:48:43 +01:00
Nikita Popov
5a90392c6a Use EX_NUM_TO_VAR() in more places
Not sure why I missed these before.
2020-02-27 13:13:24 +01:00
Nikita Popov
3b08f53c97 Deprecate required param after optional
As an exception, we allow "Type $foo = null" to occur before a
required parameter, because this pattern was used as a replacement
for nullable types in PHP versions older than 7.1.

Closes GH-5067.
2020-02-18 14:35:58 +01:00
Nikita Popov
72bd55902d Improve generated names for anonymous classes
In order of preference, the generated name will be:

    new class extends ParentClass {};
    // -> ParentClass@anonymous
    new class implements FirstInterface, SecondInterface {};
    // -> FirstInterface@anonymous
    new class {};
    // -> class@anonymous

This is intended to display a more useful class name in error messages
and stack traces, and thus make debugging easier.

Closes GH-5153.
2020-02-17 12:21:33 +01:00
Nikita Popov
43443857b7 Add static return type
RFC: https://wiki.php.net/rfc/static_return_type

The "static" type is represented as MAY_BE_STATIC, rather than
a class type like "self" and "parent", as it has special
resolution semantics, and cannot be cached in the runtime cache.

Closes GH-5062.
2020-02-17 11:51:09 +01:00
Nikita Popov
d933591674 Add support for $obj::class
This allows $obj::class, which gives the same result as get_class($obj).
Anything other than an object results in TypeError.

RFC: https://wiki.php.net/rfc/class_name_literal_on_object

Closes GH-5065.
2020-02-11 12:16:30 +01:00
Dmitry Stogov
64b40f69dc Make ASSIGN, ASSIGN_OP, INC and DEC opcodes to return IS_TMP_VAR instead of IS_VAR.
This helps to avoid unnecessary IS_REFERENCE checks.
This changes some notices "Only variables should be passed by reference" to exception "Cannot pass parameter %d by reference".

Also, for consistency, compile-time fatal error "Only variables can be passed by reference" was converted to exception "Cannot pass parameter %d by reference"
2020-02-07 13:36:52 +03:00
Nikita Popov
53e527ad43 Remove ZEND_ACC_IMPLEMENT_INTERFACES flag
This is equivalent to checking ce->num_interfaces. The only subtle
moment is during inheritance, where num_interface may change when
parent interfaces are inherited. The check in zend_do_link_class
thus uses "interfaces", not "ce->num_interfaces".
2020-02-06 10:53:12 +01:00
Nikita Popov
f57f0920fd Remove ZEND_ACC_IMPLEMENTS_TRAITS flag
This is equivalent to checking ce->num_traits.
2020-02-06 10:45:49 +01:00
Nikita Popov
4f5f72c7af Remove ZEND_ACC_INHERITED flag
It is equivalent to checking ce->parent != NULL. Just adds more
state that needs to be kept in sync.
2020-02-06 10:42:25 +01:00
Derick Rethans
d6b04bfbd5 Export zend_type_to_string() with ZEND_API 2020-02-03 10:26:20 +00:00
Nikita Popov
9c23a50939 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #79155
2020-01-23 12:55:59 +01:00
Nikita Popov
2eb33818b6 Fixed bug #79155
Make sure we only unset the NULLABLE flag temporarily for class
resolution, as the same type may be compiled multiple types.
2020-01-23 12:54:14 +01:00
Nikita Popov
9ec1ee5976 Add support for deprecating constants
Internal constants can be marked as CONST_DEPRECATED, in which
case accessing them will throw a deprecation warning.

For now this is only supported on global constants, not class
constants. Complain to me if you need to deprecate a class
constant...

Closes GH-5072.
2020-01-17 10:05:06 +01:00
Nikita Popov
bd1977282c Use zend_type inside type lists
Instead of having a completely independent encoding for type list
entries. This is going to use more memory, but I'm not particularly
concerned about that, as type unions that contain multiple classes
should be uncommon. On the other hand, this allows us to treat
top-level types and types inside lists mostly the same.

A new ZEND_TYPE_FOREACH macros allows to transparently treat list
and non-list types the same way. I'm not using it everywhere it could be
used for now, just the places that seemed most obvious.

Of course, this will make any future type system changes much simpler,
as it will not be necessary to duplicate all logic two times.
2020-01-17 09:37:54 +01:00
Nikita Popov
d2110e9880 Use helper in one more place 2020-01-13 12:44:16 +01:00
Nikita Popov
5d869df753 Make class name references use the class_name production
Throw a compile error for "static" references instead, where it
isn't already the case.

Also extract the code that does that -- we have quite a few places
where we get a const class ref and require it to be default.
2020-01-13 11:51:09 +01:00
Dmitry Stogov
621842e3f5 RECV opcode optimization 2019-12-20 06:46:25 +03:00
Dmitry Stogov
b1f08079b5 Merge branch 'PHP-7.4'
* PHP-7.4:
  Property names of internal classes from temporary extensins, loaded by dl(), may be emalloc-ed strings.
2019-12-17 10:13:13 +03:00
Dmitry Stogov
d89cd0bb22 Property names of internal classes from temporary extensins, loaded by dl(), may be emalloc-ed strings. 2019-12-17 10:10:11 +03:00
Nikita Popov
a40a69fdd0 Merge branch 'PHP-7.4'
* PHP-7.4:
  Introduce extra counter to avoid RTD key collisions
2019-12-13 11:05:41 +01:00
Nikita Popov
0f2cdbf214 Introduce extra counter to avoid RTD key collisions
Also generate a fatal error if a collision occurs in zend_compile.

This is not perfect, because collisions might still be introduced
via opcache, if one file is included multiple times during a request,
invalidate in the meantime and recompiled by different processes.

This still needs to be addressed, but this patch fixes the much
more common case of collisions occuring when opcache is not used.

Fixes bug #78903.
2019-12-13 11:04:44 +01:00
Nikita Popov
d56768817b Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #78950: Preloading trait method with static variables
2019-12-12 11:52:51 +01:00
Nikita Popov
be89a5c7f1 Fixed bug #78950: Preloading trait method with static variables
We need to make sure that trait methods with static variables
allocate a separate MAP slot for the static variables pointer,
rather than working in-place.
2019-12-12 11:52:43 +01:00
Nikita Popov
231bc7c8be Merge branch 'PHP-7.4'
* PHP-7.4:
  Revert "Fixed bug #78903: Conflict in RTD key for closures results in crash"
2019-12-11 14:40:02 +01:00
Nikita Popov
502cd7b1f1 Revert "Fixed bug #78903: Conflict in RTD key for closures results in crash"
This reverts commit b55033fa18.

This breaks ext/opcache/tests/bug65915.phpt.
2019-12-11 14:38:48 +01:00
Nikita Popov
33648585d6 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #78903: Conflict in RTD key for closures results in crash
2019-12-11 13:08:12 +01:00
Nikita Popov
b55033fa18 Fixed bug #78903: Conflict in RTD key for closures results in crash
I wasn't able to create a simple reproducer for this. General approach
is the same as for anonymous classes: If the key is already used, reuse
the old definition.
2019-12-11 13:07:45 +01:00
Dmitry Stogov
8fb3ef6e37 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #78937 (Preloading unlinkable anonymous class can segfault)
2019-12-11 00:47:15 +03:00
Dmitry Stogov
20ef51db22 Fixed bug #78937 (Preloading unlinkable anonymous class can segfault) 2019-12-11 00:46:30 +03:00
Nikita Popov
5cdea8d5e8 Merge branch 'PHP-7.4'
* PHP-7.4:
  Add support for class_alias to preloading
  Fixed bug #78935: Check that all linked classes can be preloaded
2019-12-10 13:12:29 +01:00
Nikita Popov
3f86adb0ef Fixed bug #78935: Check that all linked classes can be preloaded
During preloading, check that all classes that have been included
as part of the preload script itself (rather than through opcache_compile_file)
can actually be preloaded, i.e. satisfy Windows restrictions, have
resolved initializers and resolved property types. When resolving
initializers and property types, also autoload additional classes.
Because of this, the resolution runs in a loop.
2019-12-10 13:05:48 +01:00
Nikita Popov
8b1b68d3ba Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #78926: Handle class table reallocation on failed link
2019-12-09 09:16:48 +01:00
Nikita Popov
32c1f37574 Fixed bug #78926: Handle class table reallocation on failed link
When we change back the bucket key on a class linking failure,
make sure to reload the bucket pointer, as the class table may
have been reallocated in the meantime.

Also remove a bogus bucket key change in anon class registration:
We don't actually rename the class in this case anymore, the RTD
key is already the final name.
2019-12-09 09:15:27 +01:00
Nikita Popov
9554fb3498 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fix constant evaluation of && and ||
2019-12-06 11:11:12 +01:00
Nikita Popov
07fc0764d1 Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix constant evaluation of && and ||
2019-12-06 11:10:31 +01:00
Nikita Popov
249e49092d Fix constant evaluation of && and ||
The "return" in the for loop should have been a break on the switch,
otherwise the result is just ignored... but because it prevents
evaluation of the other operand, it also violates the invariant that
everything has been constant evaluated, resulting in an assertion
failure.

The for loop isn't correct in any case though, because it's not legal
to determine the result based on just the second operand, as the
first one may have a side-effect that cannot be optimized away.
2019-12-06 11:07:57 +01:00
Tyson Andre
67adcc5132 Remove no-op check for 'use strict;'
This should be checking for ZEND_SYMBOL_CLASS, not T_CLASS.

This was first added in 37ac1b96ed
2019-11-28 09:16:15 -05:00
Dmitry Stogov
36afe4e39e Optimize $x === null into is_null($x) 2019-11-12 13:49:55 +03:00
Dmitry Stogov
32274d81a1 Merge branch 'PHP-7.4'
* PHP-7.4:
  ws
2019-11-12 10:52:09 +03:00
Dmitry Stogov
c3f23642da ws 2019-11-12 10:51:55 +03:00
Tyson Andre
937fa6d9e2 Optimize is_scalar($x) into a TYPE_CHECK opcode
Optimizations such as specializations for is_resource were first added in
dfb4f6b38d9efedafab7d2d98b9333715561256

I don't see any mention of is_scalar (and optimizing it) in the commit history,
or in prior PRs on github, or searching for is_scalar in externals.io
2019-11-12 10:17:10 +03:00
Nikita Popov
999e32b65a Implement union types
According to RFC: https://wiki.php.net/rfc/union_types_v2

The type representation now makes use of both the pointer payload
and the type mask at the same time. Additionall, zend_type_list is
introduced as a new kind of pointer payload, which is used to store
multiple class types. Each of the class types is a tagged pointer,
which may be either a class name or class entry. The latter is only
used for typed properties, while arguments/returns will instead use
cache slots. A type list can contain a mix of both names and CEs at
the same time, as not all classes may be resolvable.

One thing this is missing is support for union types in arginfo
and stubs, which I want to handle separately.

I've also dropped the special object code from the JIT implementation
for now -- I plan to add this back in a different form at a later time.
For now I did not want to include non-trivial JIT changes together
with large functional changes.

Another possible piece of follow-up work is to implement "iterable"
as an internal alias for "array|Traversable". I believe this will
eliminate quite a few special-cases that had to be implemented.

Closes GH-4838.
2019-11-08 15:15:48 +01:00
Nikita Popov
ac4e0f0852 Make zend_type a 2-field struct
We now store the pointer payload and the type mask separately. This
is in preparation for union types, where we will be using both at
the same time.

To avoid increasing the size of arginfo structures, the
pass_by_reference and is_variadic fields are now stored as part of
the type_mask (8-bit are reserved for custom use).

Different types of pointer payloads are distinguished based on bits
in the type_mask.
2019-11-08 15:15:48 +01:00
Nikita Popov
e710862f8c Add compile warning for "confusable" types
We have a number of "types" like integer which are not actually
supported as builtin types -- instead they are silently interpreted
as class types.

I've seen this cause confusion a few types already. This change adds
a warning in this case. In the unlikely case that someone legitimately
wants to type against an integer class, the warning can be suppressed
by writing \integer or "use integer", or using Integer (this warning
will only trigger for lowercase spellings).

Closes GH-4815.
2019-11-07 15:05:08 +01:00
Nikita Popov
aef8836110 Don't check $this existence in object opcodes
We are now guaranteed that $this always exists inside methods, as
well as insides closures (if they use $this at all).

This removes checks for $this existence from the individual object
opcodes. Instead ZEND_FETCH_THIS is used in the cases where $this
is not guaranteed to exist, which is mainly the pseudo-main scope.

Closes GH-3822.
2019-10-30 09:30:13 +01:00
Nikita Popov
5c24f8042d Promote "Cannot use parent" to fatal error 2019-10-15 11:46:48 +02:00
Dmitry Stogov
d37f5da75e typo and cleanup 2019-10-09 17:58:35 +03:00
Dmitry Stogov
f6f32f2cf0 SAMRT BRANCH improvement.
Avoid need of insertion NOP opcoes between unrelated SMART BRANCH instruction and following JMPZ/JMPNZ.
Now instead of checking the opcode of following instruction, the same information is encoded into SMART BRANH result_type.
2019-10-09 13:48:39 +03:00
Nikita Popov
a32f130f94 Merge branch 'PHP-7.4' 2019-10-08 17:34:25 +02:00
Nikita Popov
bea832cbf6 Don't check type of simple parameter default values
After fixing the int->double coercion case, this is already verified
at compile-time, so there is no need to redo this type check on
every call.

Only perform the type check every time for the case of AST default
values.
2019-10-08 17:29:41 +02:00
Nikita Popov
cffa81e438 Merge branch 'PHP-7.4' 2019-10-08 15:52:18 +02:00
Dmitry Stogov
56ae3f6c4a Added "const" qualifier 2019-10-08 16:50:04 +03:00
Nikita Popov
9004102b99 Fixed bug #78648 2019-10-08 15:39:22 +02:00
Nikita Popov
5050507282 Merge branch 'PHP-7.4' 2019-10-04 22:47:10 +02:00
Nikita Popov
b078ae6c01 Merge branch 'PHP-7.3' into PHP-7.4 2019-10-04 22:46:53 +02:00
Nikita Popov
239e2dda64 Make sure T_ERROR is returned for all lexer exceptions
This originally manifested as a leak in oss-fuzz #18000. The following
is a reduced test case:

    <?php
    [
        5 => 1,
        "foo" > 1,
        "      " => "" == 0
    ];
    <<<BAR
    $x
     BAR;

Because this particular error condition did not return T_ERROR,
EG(exception) was set while performing binary operation constant
evaluation, which checks exceptions for cast failures.

Instead of adding this indirect test case, I'm adding an assertion
that the lexer has to return T_ERROR if EG(exception) is set.
2019-10-04 22:42:14 +02:00