@@ -130,9 +130,23 @@ bool c_typecheck_baset::gcc_types_compatible_p(
130130 else if (type1.id ()==ID_array &&
131131 type2.id ()==ID_array)
132132 {
133- return gcc_types_compatible_p (
134- to_array_type (type1).element_type (),
135- to_array_type (type2).element_type ()); // ignore size
133+ // For C11 6.2.7: array types are compatible if element types are
134+ // compatible and both size specifiers are present and equal, OR
135+ // one or both size specifiers are absent.
136+ if (!gcc_types_compatible_p (
137+ to_array_type (type1).element_type (),
138+ to_array_type (type2).element_type ()))
139+ return false ;
140+
141+ const array_typet &a_type1 = to_array_type (type1);
142+ const array_typet &a_type2 = to_array_type (type2);
143+
144+ // If either size is absent (incomplete), arrays are compatible
145+ if (!a_type1.is_complete () || !a_type2.is_complete ())
146+ return true ;
147+
148+ // Both sizes are present - they must be equal
149+ return a_type1.size () == a_type2.size ();
136150 }
137151 else if (type1.id ()==ID_code &&
138152 type2.id ()==ID_code)
@@ -463,9 +477,18 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
463477 {
464478 if (irep.get (ID_type_arg) == ID_default)
465479 default_match = static_cast <const exprt &>(irep.find (ID_value));
466- else if (op_type == static_cast < const typet &>(irep. find (ID_type_arg)))
480+ else
467481 {
468- assoc_match = static_cast <const exprt &>(irep.find (ID_value));
482+ const typet &assoc_type =
483+ static_cast <const typet &>(irep.find (ID_type_arg));
484+ // Use type compatibility matching instead of exact equality.
485+ // This allows pointer-to-array types with specified dimensions
486+ // to match pointer-to-array types with unspecified dimensions,
487+ // which is required by C11 6.5.1.1 Generic selection.
488+ if (gcc_types_compatible_p (op_type, assoc_type))
489+ {
490+ assoc_match = static_cast <const exprt &>(irep.find (ID_value));
491+ }
469492 }
470493 }
471494
0 commit comments