diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7f014501528c..ca6945e7c227 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -122,7 +122,7 @@ jobs: configurationParameters: >- --${{ matrix.debug && 'enable' || 'disable' }}-debug --${{ matrix.zts && 'enable' || 'disable' }}-zts - ${{ matrix.asan && 'CFLAGS="-fsanitize=undefined,address -fno-sanitize=pointer-overflow -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address -fno-sanitize=pointer-overflow" CC=clang-16 CXX=clang++-16' || '' }} + ${{ matrix.asan && 'CFLAGS="-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address" CC=clang-16 CXX=clang++-16' || '' }} skipSlow: ${{ matrix.asan }} - name: make run: make -j$(/usr/bin/nproc) >/dev/null diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index 7ce11c2c8772..964c713c0256 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -58,16 +58,16 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa && ssa && !(ssa->cfg.flags & ZEND_SSA_TSSA)) { zend_op_array *op_array = call_info->caller_op_array; - uint32_t t1 = _ssa_op1_info(op_array, ssa, call_info->arg_info[0].opline, - &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes]); - uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline, - &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes]); + uint32_t t1 = _ssa_op1_info(op_array, ssa, op_array->opcodes, + ssa->ops ? &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes] : NULL); + uint32_t t2 = _ssa_op1_info(op_array, ssa, op_array->opcodes, + ssa->ops ? &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes] : NULL); uint32_t t3 = 0; uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY; if (call_info->num_args == 3) { - t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline, - &ssa->ops[call_info->arg_info[2].opline - op_array->opcodes]); + t3 = _ssa_op1_info(op_array, ssa, op_array->opcodes, + ssa->ops ? &ssa->ops[call_info->arg_info[2].opline - op_array->opcodes] : NULL); } if ((t1 & MAY_BE_STRING) && (t2 & MAY_BE_STRING)) { tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING; diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index a4aca39e2edb..6b929c5d471d 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5185,7 +5185,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op return 0; case ZEND_ASSIGN_DIM: if ((opline+1)->op1_type == IS_CV) { - if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) { + if (OP1_DATA_INFO() & MAY_BE_UNDEF) { return 1; } } @@ -5196,7 +5196,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op return 1; } if ((opline+1)->op1_type == IS_CV) { - if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) { + if (OP1_DATA_INFO() & MAY_BE_UNDEF) { return 1; } } diff --git a/Zend/Optimizer/zend_inference.h b/Zend/Optimizer/zend_inference.h index ffcf4f0ae137..666abc586592 100644 --- a/Zend/Optimizer/zend_inference.h +++ b/Zend/Optimizer/zend_inference.h @@ -197,13 +197,13 @@ DEFINE_SSA_OP_DEF_INFO(result) #define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline, ssa_op)) #define OP2_INFO() (_ssa_op2_info(op_array, ssa, opline, ssa_op)) -#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), (ssa_op+1))) -#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL)) +#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL)) #define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline, ssa_op)) #define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline, ssa_op)) #define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline, ssa_op)) -#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), (ssa_op+1))) -#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), (ssa_op+1))) +#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL)) +#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL)) #define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline, ssa_op)) static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) { diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 294ed1db8eaf..caf9e8d086c6 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -243,6 +243,11 @@ static int zend_jit_is_constant_cmp_long_long(const zend_op *opline, return 0; } +#define ADVANCE_SSA_OP(ssa_op, offset) \ + do { \ + if (ssa_op) ssa_op += offset; \ + } while (0) + static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, const zend_op *opline, int call_level, zend_jit_trace_rec *trace) { int skip; @@ -250,7 +255,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons if (trace) { zend_jit_trace_rec *p = trace; - ssa_op++; + ADVANCE_SSA_OP(ssa_op, 1); while (1) { if (p->op == ZEND_JIT_TRACE_VM) { switch (p->opline->opcode) { @@ -305,7 +310,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons return 1; } } - ssa_op += zend_jit_trace_op_len(opline); + ADVANCE_SSA_OP(ssa_op, zend_jit_trace_op_len(opline)); } else if (p->op == ZEND_JIT_TRACE_ENTER || p->op == ZEND_JIT_TRACE_BACK || p->op == ZEND_JIT_TRACE_END) { @@ -319,7 +324,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons const zend_op *end = op_array->opcodes + op_array->last; opline++; - ssa_op++; + ADVANCE_SSA_OP(ssa_op, 1); skip = (call_level == 1); while (opline != end) { if (!skip) { @@ -381,7 +386,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons return 0; } opline++; - ssa_op++; + ADVANCE_SSA_OP(ssa_op, 1); } return 1; @@ -395,7 +400,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons } opline++; - ssa_op++; + ADVANCE_SSA_OP(ssa_op, 1); skip = (call_level == 1); while (opline != end) { if (skip) { @@ -421,7 +426,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons } } opline++; - ssa_op++; + ADVANCE_SSA_OP(ssa_op, 1); } return 0; @@ -441,7 +446,7 @@ static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ss if (ZEND_TYPE_IS_SET(arg_info->type)) { if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) { zend_op *opline = call_info->arg_info[num_args].opline; - zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[opline - op_array->opcodes] : NULL; uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type); if ((OP1_INFO() & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) { break; diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index cb595becb179..dfd667599e62 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -15240,7 +15240,7 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_ jit->b = -1; } } else { - zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[opline - op_array->opcodes] : NULL; uint32_t op1_info = OP1_INFO(); zend_jit_addr op1_addr = OP1_ADDR(); const zend_op *default_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); @@ -16301,7 +16301,7 @@ static int zend_jit_trace_start(zend_jit_ctx *jit, if (parent) { int i; int parent_vars_count = parent->exit_info[exit_num].stack_size; - zend_jit_trace_stack *parent_stack = + zend_jit_trace_stack *parent_stack = parent_vars_count == 0 ? NULL : parent->stack_map + parent->exit_info[exit_num].stack_offset; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 1bb5f8e8daf6..749b2a307812 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2779,7 +2779,7 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t zend_jit_trace_stack *stack; uint32_t parent_vars_count = parent_trace ? zend_jit_traces[parent_trace].exit_info[exit_num].stack_size : 0; - zend_jit_trace_stack *parent_stack = parent_trace ? + zend_jit_trace_stack *parent_stack = parent_vars_count ? zend_jit_traces[parent_trace].stack_map + zend_jit_traces[parent_trace].exit_info[exit_num].stack_offset : NULL; checkpoint = zend_arena_checkpoint(CG(arena)); @@ -8386,7 +8386,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf /* Deoptimization of VM stack state */ uint32_t i; uint32_t stack_size = t->exit_info[exit_num].stack_size; - zend_jit_trace_stack *stack = t->stack_map + t->exit_info[exit_num].stack_offset; + zend_jit_trace_stack *stack = stack_size ? t->stack_map + t->exit_info[exit_num].stack_offset : NULL; if (t->exit_info[exit_num].flags & ZEND_JIT_EXIT_RESTORE_CALL) { zend_execute_data *call = (zend_execute_data *)regs->gpr[ZREG_RX];