@@ -2084,7 +2084,7 @@ static void check_array_bounds(const TypePtr &array_type,
20842084 } else if (!are_types_equal (lhs_type, rhs_type)) {
20852085 parser_add_error (op_loc.begin .line ,
20862086 op_loc.begin .column ,
2087- op_name + " : incompatible types for assignment" );
2087+ op_name + " : incompatible types for assignment (' " + lhs_type-> debug_name () + " ' and ' " + rhs_type-> debug_name () + " ') " );
20882088 return nullptr ;
20892089 }
20902090 }
@@ -2111,7 +2111,53 @@ static void check_array_bounds(const TypePtr &array_type,
21112111 }
21122112
21132113 if (is_pointer_type (from_type) && is_pointer_type (to_type)) {
2114- return true ;
2114+ auto from_ptr = std::static_pointer_cast<PointerType>(from_type);
2115+ auto to_ptr = std::static_pointer_cast<PointerType>(to_type);
2116+
2117+ TypePtr from_pointee = strip_typedefs (from_ptr->pointee .type );
2118+ TypePtr to_pointee = strip_typedefs (to_ptr->pointee .type );
2119+
2120+ if (are_types_equal (from_pointee, to_pointee)) {
2121+ return true ;
2122+ }
2123+
2124+ // Allow void* conversions (void* can point to anything)
2125+ if (is_void_type (from_pointee) || is_void_type (to_pointee)) {
2126+ // TODO: add warning for void* casts
2127+ return true ;
2128+ }
2129+
2130+ // Allow casting between related class types (base/derived)
2131+ if (is_class_type (from_pointee) && is_class_type (to_pointee)) {
2132+ auto from_class = std::static_pointer_cast<ClassType>(from_pointee);
2133+ auto to_class = std::static_pointer_cast<ClassType>(to_pointee);
2134+
2135+ ClassTypePtr current = from_class;
2136+ while (current && current->base .base_type ) {
2137+ if (is_class_type (current->base .base_type )) {
2138+ ClassTypePtr base = std::static_pointer_cast<ClassType>(current->base .base_type );
2139+ if (are_types_equal (base, to_class)) {
2140+ return true ; // Upcasting (derived to base)
2141+ }
2142+ current = base;
2143+ } else {
2144+ break ;
2145+ }
2146+ }
2147+ current = to_class;
2148+ while (current && current->base .base_type ) {
2149+ if (is_class_type (current->base .base_type )) {
2150+ ClassTypePtr base = std::static_pointer_cast<ClassType>(current->base .base_type );
2151+ if (are_types_equal (base, from_class)) {
2152+ return true ; // Downcasting (base to derived) - allowed in explicit cast
2153+ }
2154+ current = base;
2155+ } else {
2156+ break ;
2157+ }
2158+ }
2159+ }
2160+ return false ;
21152161 }
21162162
21172163 // Special case: allow casting literal 0 to pointer type (NULL pointer idiom)
0 commit comments