https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65908
--- Comment #8 from Jan Hubicka <hubicka at gcc dot gnu.org> --- I think pushing TYPE_CANONICAL is a bug: we do check ODR properties of the parameter and TYPE_CANONICAL is not guaranteed to be the same. Just remove the TYPE_CANONICAL wrap here. The patch seems OK with this change both for mainline and branch. We will match the types of DECL_ARGUMENTS when verifying the body here: for (arg1 = DECL_ARGUMENTS (decl), arg2 = DECL_ARGUMENTS (m_compared_func->decl); arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2)) if (!m_checker->compare_decl (arg1, arg2)) return return_false (); However I think there is one extra case to deal with. For functions that are !prototype_p, we get empty ARG_TYPES and only have ARGUMENTS. Such functions will bypass the checks: if (POINTER_TYPE_P (arg_types[i]) && (TYPE_RESTRICT (arg_types[i]) != TYPE_RESTRICT (m_compared_func->arg_types[i]))) return return_false_with_msg ("argument restrict flag mismatch"); /* nonnull_arg_p implies non-zero range to REFERENCE types. */ if (POINTER_TYPE_P (arg_types[i]) && TREE_CODE (arg_types[i]) != TREE_CODE (m_compared_func->arg_types[i]) && opt_for_fn (decl, flag_delete_null_pointer_checks)) return return_false_with_msg ("pointer wrt reference mismatch"); Please factor out this code to a function compatible_parm_types_p and call it both from sem_function::equals_wpa and the loop above. Honza