Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
19 changes: 19 additions & 0 deletions Zend/tests/enum/gh21760.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
GH-21760 (Trait with class constant name conflict against enum case causes SEGV)
--FILE--
<?php

trait X {
public const Up = 1;
}

enum Direction {
use X;

case Up;
case Down;
}

?>
--EXPECTF--
Fatal error: Cannot use trait X, because constant Up conflicts with enum case Direction::Up in %s on line %d
17 changes: 17 additions & 0 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,18 @@ static void emit_incompatible_trait_constant_error(
);
}

static void emit_trait_constant_enum_case_conflict_error(
const zend_class_entry *ce, const zend_class_constant *trait_constant, zend_string *name
) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use trait %s, because constant %s conflicts with enum case %s::%s",
Comment thread
prateekbhujel marked this conversation as resolved.
Outdated
ZSTR_VAL(trait_constant->ce->name),
ZSTR_VAL(name),
ZSTR_VAL(ce->name),
ZSTR_VAL(name)
);
}

static bool do_trait_constant_check(
zend_class_entry *ce, zend_class_constant *trait_constant, zend_string *name, zend_class_entry **traits, size_t current_trait
) {
Expand All @@ -2770,6 +2782,11 @@ static bool do_trait_constant_check(

zend_class_constant *existing_constant = Z_PTR_P(zv);

if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(existing_constant) & ZEND_CLASS_CONST_IS_CASE)) {
emit_trait_constant_enum_case_conflict_error(ce, trait_constant, name);
return false;
}

if ((ZEND_CLASS_CONST_FLAGS(trait_constant) & flags_mask) != (ZEND_CLASS_CONST_FLAGS(existing_constant) & flags_mask)) {
emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant, name, traits, current_trait);
return false;
Expand Down
Loading