Coverage Report

Created: 2026-01-18 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/Optimizer/zend_inference.h
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine, e-SSA based Type & Range Inference                      |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) The PHP Group                                          |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 3.01 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | https://www.php.net/license/3_01.txt                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Authors: Dmitry Stogov <dmitry@php.net>                              |
16
   +----------------------------------------------------------------------+
17
*/
18
19
#ifndef ZEND_INFERENCE_H
20
#define ZEND_INFERENCE_H
21
22
#include "zend_optimizer.h"
23
#include "zend_ssa.h"
24
#include "zend_bitset.h"
25
26
/* Bitmask for type inference (zend_ssa_var_info.type) */
27
#include "zend_type_info.h"
28
29
#include <stdint.h>
30
31
0
#define MAY_BE_PACKED_GUARD         (1<<27) /* needs packed array guard */
32
0
#define MAY_BE_CLASS_GUARD          (1<<27) /* needs class guard */
33
29.7k
#define MAY_BE_GUARD                (1<<28) /* needs type guard */
34
35
#define MAY_HAVE_DTOR \
36
97
  (MAY_BE_OBJECT|MAY_BE_RESOURCE \
37
97
  |MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE)
38
39
#define DEFINE_SSA_OP_HAS_RANGE(opN) \
40
  static zend_always_inline bool _ssa_##opN##_has_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
41
8.62k
  { \
42
8.62k
    if (opline->opN##_type == IS_CONST) { \
43
1.22k
      zval *zv = CRT_CONSTANT(opline->opN); \
44
1.22k
      return (Z_TYPE_P(zv) == IS_LONG); \
45
7.40k
    } else { \
46
7.40k
      return (opline->opN##_type != IS_UNUSED && \
47
7.40k
            ssa->var_info && \
48
7.40k
            ssa_op->opN##_use >= 0 && \
49
7.40k
          ssa->var_info[ssa_op->opN##_use].has_range); \
50
7.40k
    } \
51
8.62k
    return 0; \
52
8.62k
  } \
Unexecuted instantiation: zend_jit.c:_ssa_op1_has_range
Unexecuted instantiation: zend_jit.c:_ssa_op2_has_range
Unexecuted instantiation: dce.c:_ssa_op1_has_range
Unexecuted instantiation: dce.c:_ssa_op2_has_range
Unexecuted instantiation: dfa_pass.c:_ssa_op1_has_range
Unexecuted instantiation: dfa_pass.c:_ssa_op2_has_range
Unexecuted instantiation: escape_analysis.c:_ssa_op1_has_range
Unexecuted instantiation: escape_analysis.c:_ssa_op2_has_range
Unexecuted instantiation: sccp.c:_ssa_op1_has_range
Unexecuted instantiation: sccp.c:_ssa_op2_has_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_has_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_has_range
Unexecuted instantiation: zend_dump.c:_ssa_op1_has_range
Unexecuted instantiation: zend_dump.c:_ssa_op2_has_range
Unexecuted instantiation: zend_func_info.c:_ssa_op1_has_range
Unexecuted instantiation: zend_func_info.c:_ssa_op2_has_range
zend_inference.c:_ssa_op1_has_range
Line
Count
Source
41
4.89k
  { \
42
4.89k
    if (opline->opN##_type == IS_CONST) { \
43
449
      zval *zv = CRT_CONSTANT(opline->opN); \
44
449
      return (Z_TYPE_P(zv) == IS_LONG); \
45
4.44k
    } else { \
46
4.44k
      return (opline->opN##_type != IS_UNUSED && \
47
4.44k
            ssa->var_info && \
48
4.44k
            ssa_op->opN##_use >= 0 && \
49
4.44k
          ssa->var_info[ssa_op->opN##_use].has_range); \
50
4.44k
    } \
51
4.89k
    return 0; \
52
4.89k
  } \
zend_inference.c:_ssa_op2_has_range
Line
Count
Source
41
3.73k
  { \
42
3.73k
    if (opline->opN##_type == IS_CONST) { \
43
771
      zval *zv = CRT_CONSTANT(opline->opN); \
44
771
      return (Z_TYPE_P(zv) == IS_LONG); \
45
2.96k
    } else { \
46
2.96k
      return (opline->opN##_type != IS_UNUSED && \
47
2.96k
            ssa->var_info && \
48
2.96k
            ssa_op->opN##_use >= 0 && \
49
2.96k
          ssa->var_info[ssa_op->opN##_use].has_range); \
50
2.96k
    } \
51
3.73k
    return 0; \
52
3.73k
  } \
Unexecuted instantiation: zend_optimizer.c:_ssa_op1_has_range
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_has_range
Unexecuted instantiation: zend_ssa.c:_ssa_op1_has_range
Unexecuted instantiation: zend_ssa.c:_ssa_op2_has_range
53
54
#define DEFINE_SSA_OP_MIN_RANGE(opN) \
55
  static zend_always_inline zend_long _ssa_##opN##_min_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
56
5.86k
  { \
57
5.86k
    if (opline->opN##_type == IS_CONST) { \
58
501
      zval *zv = CRT_CONSTANT(opline->opN); \
59
501
      if (Z_TYPE_P(zv) == IS_LONG) { \
60
501
        return Z_LVAL_P(zv); \
61
501
      } \
62
5.36k
    } else if (opline->opN##_type != IS_UNUSED && \
63
5.36k
        ssa->var_info && \
64
5.36k
        ssa_op->opN##_use >= 0 && \
65
5.36k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
66
5.36k
      return ssa->var_info[ssa_op->opN##_use].range.min; \
67
5.36k
    } \
68
5.86k
    return ZEND_LONG_MIN; \
69
5.86k
  } \
Unexecuted instantiation: dce.c:_ssa_op1_min_range
Unexecuted instantiation: dce.c:_ssa_op2_min_range
Unexecuted instantiation: dfa_pass.c:_ssa_op1_min_range
Unexecuted instantiation: dfa_pass.c:_ssa_op2_min_range
Unexecuted instantiation: escape_analysis.c:_ssa_op1_min_range
Unexecuted instantiation: escape_analysis.c:_ssa_op2_min_range
Unexecuted instantiation: sccp.c:_ssa_op1_min_range
Unexecuted instantiation: sccp.c:_ssa_op2_min_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_min_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_min_range
Unexecuted instantiation: zend_dump.c:_ssa_op1_min_range
Unexecuted instantiation: zend_dump.c:_ssa_op2_min_range
Unexecuted instantiation: zend_func_info.c:_ssa_op1_min_range
Unexecuted instantiation: zend_func_info.c:_ssa_op2_min_range
Unexecuted instantiation: zend_optimizer.c:_ssa_op1_min_range
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_min_range
Unexecuted instantiation: zend_ssa.c:_ssa_op1_min_range
Unexecuted instantiation: zend_ssa.c:_ssa_op2_min_range
70
71
#define DEFINE_SSA_OP_MAX_RANGE(opN) \
72
  static zend_always_inline zend_long _ssa_##opN##_max_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
73
5.81k
  { \
74
5.81k
    if (opline->opN##_type == IS_CONST) { \
75
453
      zval *zv = CRT_CONSTANT(opline->opN); \
76
453
      if (Z_TYPE_P(zv) == IS_LONG) { \
77
453
        return Z_LVAL_P(zv); \
78
453
      } \
79
5.36k
    } else if (opline->opN##_type != IS_UNUSED && \
80
5.36k
        ssa->var_info && \
81
5.36k
        ssa_op->opN##_use >= 0 && \
82
5.36k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
83
5.36k
      return ssa->var_info[ssa_op->opN##_use].range.max; \
84
5.36k
    } \
85
5.81k
    return ZEND_LONG_MAX; \
86
5.81k
  } \
Unexecuted instantiation: dce.c:_ssa_op1_max_range
Unexecuted instantiation: dce.c:_ssa_op2_max_range
Unexecuted instantiation: dfa_pass.c:_ssa_op1_max_range
Unexecuted instantiation: dfa_pass.c:_ssa_op2_max_range
Unexecuted instantiation: escape_analysis.c:_ssa_op1_max_range
Unexecuted instantiation: escape_analysis.c:_ssa_op2_max_range
Unexecuted instantiation: sccp.c:_ssa_op1_max_range
Unexecuted instantiation: sccp.c:_ssa_op2_max_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_max_range
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_max_range
Unexecuted instantiation: zend_dump.c:_ssa_op1_max_range
Unexecuted instantiation: zend_dump.c:_ssa_op2_max_range
Unexecuted instantiation: zend_func_info.c:_ssa_op1_max_range
Unexecuted instantiation: zend_func_info.c:_ssa_op2_max_range
Unexecuted instantiation: zend_optimizer.c:_ssa_op1_max_range
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_max_range
Unexecuted instantiation: zend_ssa.c:_ssa_op1_max_range
Unexecuted instantiation: zend_ssa.c:_ssa_op2_max_range
87
88
#define DEFINE_SSA_OP_RANGE_UNDERFLOW(opN) \
89
  static zend_always_inline char _ssa_##opN##_range_underflow(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
90
4.97k
  { \
91
4.97k
    if (opline->opN##_type == IS_CONST) { \
92
406
      zval *zv = CRT_CONSTANT(opline->opN); \
93
406
      if (Z_TYPE_P(zv) == IS_LONG) { \
94
406
        return 0; \
95
406
      } \
96
4.56k
    } else if (opline->opN##_type != IS_UNUSED && \
97
4.56k
        ssa->var_info && \
98
4.56k
        ssa_op->opN##_use >= 0 && \
99
4.56k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
100
4.56k
      return ssa->var_info[ssa_op->opN##_use].range.underflow; \
101
4.56k
    } \
102
4.97k
    return 1; \
103
4.97k
  } \
Unexecuted instantiation: zend_jit.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_jit.c:_ssa_op2_range_underflow
Unexecuted instantiation: dce.c:_ssa_op1_range_underflow
Unexecuted instantiation: dce.c:_ssa_op2_range_underflow
Unexecuted instantiation: dfa_pass.c:_ssa_op1_range_underflow
Unexecuted instantiation: dfa_pass.c:_ssa_op2_range_underflow
Unexecuted instantiation: escape_analysis.c:_ssa_op1_range_underflow
Unexecuted instantiation: escape_analysis.c:_ssa_op2_range_underflow
Unexecuted instantiation: sccp.c:_ssa_op1_range_underflow
Unexecuted instantiation: sccp.c:_ssa_op2_range_underflow
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_range_underflow
Unexecuted instantiation: zend_dump.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_dump.c:_ssa_op2_range_underflow
Unexecuted instantiation: zend_func_info.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_func_info.c:_ssa_op2_range_underflow
zend_inference.c:_ssa_op1_range_underflow
Line
Count
Source
90
3.31k
  { \
91
3.31k
    if (opline->opN##_type == IS_CONST) { \
92
57
      zval *zv = CRT_CONSTANT(opline->opN); \
93
57
      if (Z_TYPE_P(zv) == IS_LONG) { \
94
57
        return 0; \
95
57
      } \
96
3.25k
    } else if (opline->opN##_type != IS_UNUSED && \
97
3.25k
        ssa->var_info && \
98
3.25k
        ssa_op->opN##_use >= 0 && \
99
3.25k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
100
3.25k
      return ssa->var_info[ssa_op->opN##_use].range.underflow; \
101
3.25k
    } \
102
3.31k
    return 1; \
103
3.31k
  } \
zend_inference.c:_ssa_op2_range_underflow
Line
Count
Source
90
1.65k
  { \
91
1.65k
    if (opline->opN##_type == IS_CONST) { \
92
349
      zval *zv = CRT_CONSTANT(opline->opN); \
93
349
      if (Z_TYPE_P(zv) == IS_LONG) { \
94
349
        return 0; \
95
349
      } \
96
1.30k
    } else if (opline->opN##_type != IS_UNUSED && \
97
1.30k
        ssa->var_info && \
98
1.30k
        ssa_op->opN##_use >= 0 && \
99
1.30k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
100
1.30k
      return ssa->var_info[ssa_op->opN##_use].range.underflow; \
101
1.30k
    } \
102
1.65k
    return 1; \
103
1.65k
  } \
Unexecuted instantiation: zend_optimizer.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_range_underflow
Unexecuted instantiation: zend_ssa.c:_ssa_op1_range_underflow
Unexecuted instantiation: zend_ssa.c:_ssa_op2_range_underflow
104
105
#define DEFINE_SSA_OP_RANGE_OVERFLOW(opN) \
106
  static zend_always_inline char _ssa_##opN##_range_overflow(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
107
4.58k
  { \
108
4.58k
    if (opline->opN##_type == IS_CONST) { \
109
406
      zval *zv = CRT_CONSTANT(opline->opN); \
110
406
      if (Z_TYPE_P(zv) == IS_LONG) { \
111
406
        return 0; \
112
406
      } \
113
4.17k
    } else if (opline->opN##_type != IS_UNUSED && \
114
4.17k
        ssa->var_info && \
115
4.17k
        ssa_op->opN##_use >= 0 && \
116
4.17k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
117
4.17k
      return ssa->var_info[ssa_op->opN##_use].range.overflow; \
118
4.17k
    } \
119
4.58k
    return 1; \
120
4.58k
  } \
Unexecuted instantiation: zend_jit.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_jit.c:_ssa_op2_range_overflow
Unexecuted instantiation: dce.c:_ssa_op1_range_overflow
Unexecuted instantiation: dce.c:_ssa_op2_range_overflow
Unexecuted instantiation: dfa_pass.c:_ssa_op1_range_overflow
Unexecuted instantiation: dfa_pass.c:_ssa_op2_range_overflow
Unexecuted instantiation: escape_analysis.c:_ssa_op1_range_overflow
Unexecuted instantiation: escape_analysis.c:_ssa_op2_range_overflow
Unexecuted instantiation: sccp.c:_ssa_op1_range_overflow
Unexecuted instantiation: sccp.c:_ssa_op2_range_overflow
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_range_overflow
Unexecuted instantiation: zend_dump.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_dump.c:_ssa_op2_range_overflow
Unexecuted instantiation: zend_func_info.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_func_info.c:_ssa_op2_range_overflow
zend_inference.c:_ssa_op1_range_overflow
Line
Count
Source
107
2.90k
  { \
108
2.90k
    if (opline->opN##_type == IS_CONST) { \
109
57
      zval *zv = CRT_CONSTANT(opline->opN); \
110
57
      if (Z_TYPE_P(zv) == IS_LONG) { \
111
57
        return 0; \
112
57
      } \
113
2.84k
    } else if (opline->opN##_type != IS_UNUSED && \
114
2.84k
        ssa->var_info && \
115
2.84k
        ssa_op->opN##_use >= 0 && \
116
2.84k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
117
2.84k
      return ssa->var_info[ssa_op->opN##_use].range.overflow; \
118
2.84k
    } \
119
2.90k
    return 1; \
120
2.90k
  } \
zend_inference.c:_ssa_op2_range_overflow
Line
Count
Source
107
1.68k
  { \
108
1.68k
    if (opline->opN##_type == IS_CONST) { \
109
349
      zval *zv = CRT_CONSTANT(opline->opN); \
110
349
      if (Z_TYPE_P(zv) == IS_LONG) { \
111
349
        return 0; \
112
349
      } \
113
1.33k
    } else if (opline->opN##_type != IS_UNUSED && \
114
1.33k
        ssa->var_info && \
115
1.33k
        ssa_op->opN##_use >= 0 && \
116
1.33k
        ssa->var_info[ssa_op->opN##_use].has_range) { \
117
1.33k
      return ssa->var_info[ssa_op->opN##_use].range.overflow; \
118
1.33k
    } \
119
1.68k
    return 1; \
120
1.68k
  } \
Unexecuted instantiation: zend_optimizer.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_range_overflow
Unexecuted instantiation: zend_ssa.c:_ssa_op1_range_overflow
Unexecuted instantiation: zend_ssa.c:_ssa_op2_range_overflow
121
122
DEFINE_SSA_OP_HAS_RANGE(op1)
123
3.04k
DEFINE_SSA_OP_MIN_RANGE(op1)
Unexecuted instantiation: zend_jit.c:_ssa_op1_min_range
Unexecuted instantiation: zend_inference.c:_ssa_op1_min_range
124
3.04k
DEFINE_SSA_OP_MAX_RANGE(op1)
Unexecuted instantiation: zend_jit.c:_ssa_op1_max_range
Unexecuted instantiation: zend_inference.c:_ssa_op1_max_range
125
DEFINE_SSA_OP_RANGE_UNDERFLOW(op1)
126
DEFINE_SSA_OP_RANGE_OVERFLOW(op1)
127
DEFINE_SSA_OP_HAS_RANGE(op2)
128
2.82k
DEFINE_SSA_OP_MIN_RANGE(op2)
Unexecuted instantiation: zend_jit.c:_ssa_op2_min_range
Unexecuted instantiation: zend_inference.c:_ssa_op2_min_range
129
2.77k
DEFINE_SSA_OP_MAX_RANGE(op2)
Unexecuted instantiation: zend_jit.c:_ssa_op2_max_range
Unexecuted instantiation: zend_inference.c:_ssa_op2_max_range
130
DEFINE_SSA_OP_RANGE_UNDERFLOW(op2)
131
DEFINE_SSA_OP_RANGE_OVERFLOW(op2)
132
133
7.80k
#define OP1_HAS_RANGE()       (_ssa_op1_has_range (op_array, ssa, opline, ssa_op))
134
3.04k
#define OP1_MIN_RANGE()       (_ssa_op1_min_range (op_array, ssa, opline, ssa_op))
135
3.04k
#define OP1_MAX_RANGE()       (_ssa_op1_max_range (op_array, ssa, opline, ssa_op))
136
4.87k
#define OP1_RANGE_UNDERFLOW() (_ssa_op1_range_underflow (op_array, ssa, opline, ssa_op))
137
4.46k
#define OP1_RANGE_OVERFLOW()  (_ssa_op1_range_overflow (op_array, ssa, opline, ssa_op))
138
3.79k
#define OP2_HAS_RANGE()       (_ssa_op2_has_range (op_array, ssa, opline, ssa_op))
139
2.82k
#define OP2_MIN_RANGE()       (_ssa_op2_min_range (op_array, ssa, opline, ssa_op))
140
2.77k
#define OP2_MAX_RANGE()       (_ssa_op2_max_range (op_array, ssa, opline, ssa_op))
141
3.21k
#define OP2_RANGE_UNDERFLOW() (_ssa_op2_range_underflow (op_array, ssa, opline, ssa_op))
142
2.94k
#define OP2_RANGE_OVERFLOW()  (_ssa_op2_range_overflow (op_array, ssa, opline, ssa_op))
143
144
BEGIN_EXTERN_C()
145
ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv);
146
END_EXTERN_C()
147
148
17.6k
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
149
17.6k
  if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
150
0
    return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
151
17.6k
  } else if (Z_TYPE_P(zv) == IS_ARRAY) {
152
7
    return zend_array_type_info(zv);
153
17.6k
  } else {
154
17.6k
    uint32_t tmp = (1 << Z_TYPE_P(zv));
155
156
17.6k
    if (Z_REFCOUNTED_P(zv)) {
157
2.79k
      tmp |= MAY_BE_RC1 | MAY_BE_RCN;
158
14.8k
    } else if (Z_TYPE_P(zv) == IS_STRING) {
159
12.6k
      tmp |= MAY_BE_RCN;
160
12.6k
    }
161
17.6k
    return tmp;
162
17.6k
  }
163
17.6k
}
Unexecuted instantiation: zend_jit.c:_const_op_type
Unexecuted instantiation: dce.c:_const_op_type
dfa_pass.c:_const_op_type
Line
Count
Source
148
45
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
149
45
  if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
150
0
    return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
151
45
  } else if (Z_TYPE_P(zv) == IS_ARRAY) {
152
0
    return zend_array_type_info(zv);
153
45
  } else {
154
45
    uint32_t tmp = (1 << Z_TYPE_P(zv));
155
156
45
    if (Z_REFCOUNTED_P(zv)) {
157
14
      tmp |= MAY_BE_RC1 | MAY_BE_RCN;
158
31
    } else if (Z_TYPE_P(zv) == IS_STRING) {
159
31
      tmp |= MAY_BE_RCN;
160
31
    }
161
45
    return tmp;
162
45
  }
163
45
}
Unexecuted instantiation: escape_analysis.c:_const_op_type
Unexecuted instantiation: sccp.c:_const_op_type
Unexecuted instantiation: zend_call_graph.c:_const_op_type
Unexecuted instantiation: zend_dump.c:_const_op_type
Unexecuted instantiation: zend_func_info.c:_const_op_type
zend_inference.c:_const_op_type
Line
Count
Source
148
9.32k
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
149
9.32k
  if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
150
0
    return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
151
9.32k
  } else if (Z_TYPE_P(zv) == IS_ARRAY) {
152
0
    return zend_array_type_info(zv);
153
9.32k
  } else {
154
9.32k
    uint32_t tmp = (1 << Z_TYPE_P(zv));
155
156
9.32k
    if (Z_REFCOUNTED_P(zv)) {
157
1.47k
      tmp |= MAY_BE_RC1 | MAY_BE_RCN;
158
7.84k
    } else if (Z_TYPE_P(zv) == IS_STRING) {
159
6.33k
      tmp |= MAY_BE_RCN;
160
6.33k
    }
161
9.32k
    return tmp;
162
9.32k
  }
163
9.32k
}
zend_optimizer.c:_const_op_type
Line
Count
Source
148
8.30k
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
149
8.30k
  if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
150
0
    return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
151
8.30k
  } else if (Z_TYPE_P(zv) == IS_ARRAY) {
152
7
    return zend_array_type_info(zv);
153
8.29k
  } else {
154
8.29k
    uint32_t tmp = (1 << Z_TYPE_P(zv));
155
156
8.29k
    if (Z_REFCOUNTED_P(zv)) {
157
1.30k
      tmp |= MAY_BE_RC1 | MAY_BE_RCN;
158
6.98k
    } else if (Z_TYPE_P(zv) == IS_STRING) {
159
6.28k
      tmp |= MAY_BE_RCN;
160
6.28k
    }
161
8.29k
    return tmp;
162
8.29k
  }
163
8.30k
}
Unexecuted instantiation: zend_ssa.c:_const_op_type
164
165
static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa_var_num)
166
99.2k
{
167
99.2k
  if (ssa->var_info && ssa_var_num >= 0) {
168
81.9k
    return ssa->var_info[ssa_var_num].type;
169
81.9k
  } else {
170
17.3k
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
17.3k
  }
172
99.2k
}
Unexecuted instantiation: zend_jit.c:get_ssa_var_info
dce.c:get_ssa_var_info
Line
Count
Source
166
97
{
167
97
  if (ssa->var_info && ssa_var_num >= 0) {
168
97
    return ssa->var_info[ssa_var_num].type;
169
97
  } else {
170
0
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
0
  }
172
97
}
dfa_pass.c:get_ssa_var_info
Line
Count
Source
166
489
{
167
489
  if (ssa->var_info && ssa_var_num >= 0) {
168
489
    return ssa->var_info[ssa_var_num].type;
169
489
  } else {
170
0
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
0
  }
172
489
}
escape_analysis.c:get_ssa_var_info
Line
Count
Source
166
31
{
167
31
  if (ssa->var_info && ssa_var_num >= 0) {
168
31
    return ssa->var_info[ssa_var_num].type;
169
31
  } else {
170
0
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
0
  }
172
31
}
Unexecuted instantiation: sccp.c:get_ssa_var_info
Unexecuted instantiation: zend_call_graph.c:get_ssa_var_info
Unexecuted instantiation: zend_dump.c:get_ssa_var_info
Unexecuted instantiation: zend_func_info.c:get_ssa_var_info
zend_inference.c:get_ssa_var_info
Line
Count
Source
166
48.9k
{
167
48.9k
  if (ssa->var_info && ssa_var_num >= 0) {
168
38.3k
    return ssa->var_info[ssa_var_num].type;
169
38.3k
  } else {
170
10.5k
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
10.5k
  }
172
48.9k
}
zend_optimizer.c:get_ssa_var_info
Line
Count
Source
166
49.7k
{
167
49.7k
  if (ssa->var_info && ssa_var_num >= 0) {
168
42.9k
    return ssa->var_info[ssa_var_num].type;
169
42.9k
  } else {
170
6.75k
    return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
171
6.75k
  }
172
49.7k
}
Unexecuted instantiation: zend_ssa.c:get_ssa_var_info
173
174
#define DEFINE_SSA_OP_INFO(opN) \
175
  static zend_always_inline uint32_t _ssa_##opN##_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
176
86.6k
  {                                   \
177
86.6k
    if (opline->opN##_type == IS_CONST) {             \
178
17.6k
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
68.9k
    } else { \
180
68.9k
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
68.9k
    } \
182
86.6k
  } \
Unexecuted instantiation: zend_jit.c:_ssa_op1_info
Unexecuted instantiation: zend_jit.c:_ssa_op2_info
Unexecuted instantiation: zend_jit.c:_ssa_result_info
dce.c:_ssa_op2_info
Line
Count
Source
176
91
  {                                   \
177
91
    if (opline->opN##_type == IS_CONST) {             \
178
0
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
91
    } else { \
180
91
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
91
    } \
182
91
  } \
dce.c:_ssa_op1_info
Line
Count
Source
176
6
  {                                   \
177
6
    if (opline->opN##_type == IS_CONST) {             \
178
0
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
6
    } else { \
180
6
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
6
    } \
182
6
  } \
Unexecuted instantiation: dce.c:_ssa_result_info
dfa_pass.c:_ssa_op2_info
Line
Count
Source
176
209
  {                                   \
177
209
    if (opline->opN##_type == IS_CONST) {             \
178
16
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
193
    } else { \
180
193
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
193
    } \
182
209
  } \
dfa_pass.c:_ssa_op1_info
Line
Count
Source
176
325
  {                                   \
177
325
    if (opline->opN##_type == IS_CONST) {             \
178
29
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
296
    } else { \
180
296
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
296
    } \
182
325
  } \
Unexecuted instantiation: dfa_pass.c:_ssa_result_info
escape_analysis.c:_ssa_op1_info
Line
Count
Source
176
30
  {                                   \
177
30
    if (opline->opN##_type == IS_CONST) {             \
178
0
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
30
    } else { \
180
30
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
30
    } \
182
30
  } \
escape_analysis.c:_ssa_op2_info
Line
Count
Source
176
1
  {                                   \
177
1
    if (opline->opN##_type == IS_CONST) {             \
178
0
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
1
    } else { \
180
1
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
1
    } \
182
1
  } \
Unexecuted instantiation: escape_analysis.c:_ssa_result_info
Unexecuted instantiation: sccp.c:_ssa_op1_info
Unexecuted instantiation: sccp.c:_ssa_op2_info
Unexecuted instantiation: sccp.c:_ssa_result_info
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_info
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_info
Unexecuted instantiation: zend_call_graph.c:_ssa_result_info
Unexecuted instantiation: zend_dump.c:_ssa_op1_info
Unexecuted instantiation: zend_dump.c:_ssa_op2_info
Unexecuted instantiation: zend_dump.c:_ssa_result_info
Unexecuted instantiation: zend_func_info.c:_ssa_op1_info
Unexecuted instantiation: zend_func_info.c:_ssa_op2_info
Unexecuted instantiation: zend_func_info.c:_ssa_result_info
zend_inference.c:_ssa_result_info
Line
Count
Source
176
388
  {                                   \
177
388
    if (opline->opN##_type == IS_CONST) {             \
178
0
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
388
    } else { \
180
388
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
388
    } \
182
388
  } \
zend_inference.c:_ssa_op1_info
Line
Count
Source
176
23.2k
  {                                   \
177
23.2k
    if (opline->opN##_type == IS_CONST) {             \
178
1.00k
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
22.2k
    } else { \
180
22.2k
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
22.2k
    } \
182
23.2k
  } \
zend_inference.c:_ssa_op2_info
Line
Count
Source
176
22.8k
  {                                   \
177
22.8k
    if (opline->opN##_type == IS_CONST) {             \
178
8.31k
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
14.5k
    } else { \
180
14.5k
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
14.5k
    } \
182
22.8k
  } \
zend_optimizer.c:_ssa_op1_info
Line
Count
Source
176
19.7k
  {                                   \
177
19.7k
    if (opline->opN##_type == IS_CONST) {             \
178
1.07k
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
18.6k
    } else { \
180
18.6k
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
18.6k
    } \
182
19.7k
  } \
zend_optimizer.c:_ssa_op2_info
Line
Count
Source
176
19.7k
  {                                   \
177
19.7k
    if (opline->opN##_type == IS_CONST) {             \
178
7.23k
      return _const_op_type(CRT_CONSTANT(opline->opN)); \
179
12.5k
    } else { \
180
12.5k
      return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_use : -1); \
181
12.5k
    } \
182
19.7k
  } \
Unexecuted instantiation: zend_optimizer.c:_ssa_result_info
Unexecuted instantiation: zend_ssa.c:_ssa_op1_info
Unexecuted instantiation: zend_ssa.c:_ssa_op2_info
Unexecuted instantiation: zend_ssa.c:_ssa_result_info
183
184
#define DEFINE_SSA_OP_DEF_INFO(opN) \
185
  static zend_always_inline uint32_t _ssa_##opN##_def_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) \
186
18.5k
  { \
187
18.5k
    return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_def : -1); \
188
18.5k
  } \
Unexecuted instantiation: zend_jit.c:_ssa_result_def_info
Unexecuted instantiation: zend_jit.c:_ssa_op1_def_info
Unexecuted instantiation: zend_jit.c:_ssa_op2_def_info
Unexecuted instantiation: dce.c:_ssa_op1_def_info
Unexecuted instantiation: dce.c:_ssa_op2_def_info
Unexecuted instantiation: dce.c:_ssa_result_def_info
Unexecuted instantiation: dfa_pass.c:_ssa_op1_def_info
Unexecuted instantiation: dfa_pass.c:_ssa_op2_def_info
Unexecuted instantiation: dfa_pass.c:_ssa_result_def_info
Unexecuted instantiation: escape_analysis.c:_ssa_op1_def_info
Unexecuted instantiation: escape_analysis.c:_ssa_op2_def_info
Unexecuted instantiation: escape_analysis.c:_ssa_result_def_info
Unexecuted instantiation: sccp.c:_ssa_op1_def_info
Unexecuted instantiation: sccp.c:_ssa_op2_def_info
Unexecuted instantiation: sccp.c:_ssa_result_def_info
Unexecuted instantiation: zend_call_graph.c:_ssa_op1_def_info
Unexecuted instantiation: zend_call_graph.c:_ssa_op2_def_info
Unexecuted instantiation: zend_call_graph.c:_ssa_result_def_info
Unexecuted instantiation: zend_dump.c:_ssa_op1_def_info
Unexecuted instantiation: zend_dump.c:_ssa_op2_def_info
Unexecuted instantiation: zend_dump.c:_ssa_result_def_info
Unexecuted instantiation: zend_func_info.c:_ssa_op1_def_info
Unexecuted instantiation: zend_func_info.c:_ssa_op2_def_info
Unexecuted instantiation: zend_func_info.c:_ssa_result_def_info
Unexecuted instantiation: zend_inference.c:_ssa_op1_def_info
Unexecuted instantiation: zend_inference.c:_ssa_op2_def_info
Unexecuted instantiation: zend_inference.c:_ssa_result_def_info
zend_optimizer.c:_ssa_op1_def_info
Line
Count
Source
186
148
  { \
187
148
    return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_def : -1); \
188
148
  } \
zend_optimizer.c:_ssa_result_def_info
Line
Count
Source
186
18.3k
  { \
187
18.3k
    return get_ssa_var_info(ssa, ssa->var_info ? ssa_op->opN##_def : -1); \
188
18.3k
  } \
Unexecuted instantiation: zend_optimizer.c:_ssa_op2_def_info
Unexecuted instantiation: zend_ssa.c:_ssa_op1_def_info
Unexecuted instantiation: zend_ssa.c:_ssa_op2_def_info
Unexecuted instantiation: zend_ssa.c:_ssa_result_def_info
189
190
191
DEFINE_SSA_OP_INFO(op1)
192
DEFINE_SSA_OP_INFO(op2)
193
DEFINE_SSA_OP_INFO(result)
194
DEFINE_SSA_OP_DEF_INFO(op1)
195
DEFINE_SSA_OP_DEF_INFO(op2)
196
DEFINE_SSA_OP_DEF_INFO(result)
197
198
43.1k
#define OP1_INFO()           (_ssa_op1_info(op_array, ssa, opline, ssa_op))
199
42.8k
#define OP2_INFO()           (_ssa_op2_info(op_array, ssa, opline, ssa_op))
200
234
#define OP1_DATA_INFO()      (_ssa_op1_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
201
#define OP2_DATA_INFO()      (_ssa_op2_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
202
388
#define RES_USE_INFO()       (_ssa_result_info(op_array, ssa, opline, ssa_op))
203
148
#define OP1_DEF_INFO()       (_ssa_op1_def_info(op_array, ssa, opline, ssa_op))
204
#define OP2_DEF_INFO()       (_ssa_op2_def_info(op_array, ssa, opline, ssa_op))
205
#define OP1_DATA_DEF_INFO()  (_ssa_op1_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
206
#define OP2_DATA_DEF_INFO()  (_ssa_op2_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
207
18.3k
#define RES_INFO()           (_ssa_result_def_info(op_array, ssa, opline, ssa_op))
208
209
169
static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {
210
169
  return (b > 0 && a > ZEND_LONG_MAX - b)
211
160
    || (b < 0 && a < ZEND_LONG_MIN - b);
212
169
}
Unexecuted instantiation: zend_jit.c:zend_add_will_overflow
Unexecuted instantiation: dce.c:zend_add_will_overflow
Unexecuted instantiation: dfa_pass.c:zend_add_will_overflow
Unexecuted instantiation: escape_analysis.c:zend_add_will_overflow
Unexecuted instantiation: sccp.c:zend_add_will_overflow
Unexecuted instantiation: zend_call_graph.c:zend_add_will_overflow
Unexecuted instantiation: zend_dump.c:zend_add_will_overflow
Unexecuted instantiation: zend_func_info.c:zend_add_will_overflow
zend_inference.c:zend_add_will_overflow
Line
Count
Source
209
18
static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {
210
18
  return (b > 0 && a > ZEND_LONG_MAX - b)
211
9
    || (b < 0 && a < ZEND_LONG_MIN - b);
212
18
}
Unexecuted instantiation: zend_optimizer.c:zend_add_will_overflow
zend_ssa.c:zend_add_will_overflow
Line
Count
Source
209
151
static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {
210
151
  return (b > 0 && a > ZEND_LONG_MAX - b)
211
151
    || (b < 0 && a < ZEND_LONG_MIN - b);
212
151
}
213
56
static zend_always_inline bool zend_sub_will_overflow(zend_long a, zend_long b) {
214
56
  return (b > 0 && a < ZEND_LONG_MIN + b)
215
52
    || (b < 0 && a > ZEND_LONG_MAX + b);
216
56
}
Unexecuted instantiation: zend_jit.c:zend_sub_will_overflow
Unexecuted instantiation: dce.c:zend_sub_will_overflow
Unexecuted instantiation: dfa_pass.c:zend_sub_will_overflow
Unexecuted instantiation: escape_analysis.c:zend_sub_will_overflow
Unexecuted instantiation: sccp.c:zend_sub_will_overflow
Unexecuted instantiation: zend_call_graph.c:zend_sub_will_overflow
Unexecuted instantiation: zend_dump.c:zend_sub_will_overflow
Unexecuted instantiation: zend_func_info.c:zend_sub_will_overflow
zend_inference.c:zend_sub_will_overflow
Line
Count
Source
213
8
static zend_always_inline bool zend_sub_will_overflow(zend_long a, zend_long b) {
214
8
  return (b > 0 && a < ZEND_LONG_MIN + b)
215
4
    || (b < 0 && a > ZEND_LONG_MAX + b);
216
8
}
Unexecuted instantiation: zend_optimizer.c:zend_sub_will_overflow
zend_ssa.c:zend_sub_will_overflow
Line
Count
Source
213
48
static zend_always_inline bool zend_sub_will_overflow(zend_long a, zend_long b) {
214
48
  return (b > 0 && a < ZEND_LONG_MIN + b)
215
48
    || (b < 0 && a > ZEND_LONG_MAX + b);
216
48
}
217
218
BEGIN_EXTERN_C()
219
220
ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, const zend_ssa *ssa);
221
ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa);
222
ZEND_API zend_result zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level);
223
224
ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert);
225
226
ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp);
227
228
ZEND_API uint32_t zend_fetch_arg_info_type(
229
  const zend_script *script, const zend_arg_info *arg_info, zend_class_entry **pce);
230
ZEND_API void zend_init_func_return_info(
231
  const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret);
232
uint32_t zend_get_return_info_from_signature_only(
233
    const zend_function *func, const zend_script *script,
234
    zend_class_entry **ce, bool *ce_is_instanceof, bool use_tentative_return_info);
235
236
ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, const zend_ssa *ssa, uint32_t t1, uint32_t t2);
237
ZEND_API bool zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, const zend_ssa *ssa);
238
239
ZEND_API zend_result zend_update_type_info(
240
  const zend_op_array *op_array, zend_ssa *ssa, const zend_script *script,
241
  const zend_op *opline, zend_ssa_op *ssa_op, const zend_op **ssa_opcodes,
242
  zend_long optimization_level);
243
244
END_EXTERN_C()
245
246
#endif /* ZEND_INFERENCE_H */