@@ -2382,15 +2382,29 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen
23822382
23832383 uint32_t tmp = zend_convert_type_declaration_mask (ZEND_TYPE_PURE_MASK (type ));
23842384 if (ZEND_TYPE_IS_COMPLEX (type )) {
2385- tmp |= MAY_BE_OBJECT ;
2386- if (pce ) {
2387- /* As we only have space to store one CE,
2388- * we use a plain object type for class unions. */
2389- if (ZEND_TYPE_HAS_NAME (type )) {
2390- zend_string * lcname = zend_string_tolower (ZEND_TYPE_NAME (type ));
2391- // TODO: Pass through op_array.
2392- * pce = zend_optimizer_get_class_entry (script , NULL , lcname );
2393- zend_string_release_ex (lcname , 0 );
2385+ /* A complex type is a class/object type, unless it is made up solely of
2386+ * literal types, which contribute their base scalar type instead. */
2387+ bool has_class = false;
2388+ const zend_type * single_type ;
2389+ ZEND_TYPE_FOREACH (type , single_type ) {
2390+ if (ZEND_TYPE_HAS_LITERAL (* single_type )) {
2391+ /* int/float/string literal -> MAY_BE_LONG/DOUBLE/STRING */
2392+ tmp |= 1u << Z_TYPE_P (ZEND_TYPE_LITERAL_VALUE (* single_type ));
2393+ } else {
2394+ has_class = true;
2395+ }
2396+ } ZEND_TYPE_FOREACH_END ();
2397+ if (has_class ) {
2398+ tmp |= MAY_BE_OBJECT ;
2399+ if (pce ) {
2400+ /* As we only have space to store one CE,
2401+ * we use a plain object type for class unions. */
2402+ if (ZEND_TYPE_HAS_NAME (type )) {
2403+ zend_string * lcname = zend_string_tolower (ZEND_TYPE_NAME (type ));
2404+ // TODO: Pass through op_array.
2405+ * pce = zend_optimizer_get_class_entry (script , NULL , lcname );
2406+ zend_string_release_ex (lcname , 0 );
2407+ }
23942408 }
23952409 }
23962410 }
0 commit comments