https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77517
--- Comment #5 from Harald Anlauf <anlauf at gmx dot de> --- Besides the lack of diagnosing the conflicting definitions, I think there is a missing check in gfc_check_move_alloc(). The test case program p class(*), allocatable :: a, b call move_alloc (a, b) contains subroutine a end end hits near the end of the function /* CLASS arguments: Make sure the vtab of from is present. */ if (to->ts.type == BT_CLASS && !UNLIMITED_POLY (from)) gfc_find_vtab (&from->ts); However, for that case I get (gdb) print from->ts.type $7 = BT_PROCEDURE which should never happen, and is not expected. To avoid an ICE, one might add a check just before this block, like: if (to->ts.type == BT_CLASS && from->ts.type != BT_CLASS) { gfc_error ("The FROM and TO arguments at %L are incompatible", &to->where); return false; }