In cp/cvt.c we have this code in cp_convert_to_pointer: if (INTEGRAL_CODE_P (form)) { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width as a pointer. */ gcc_assert (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) == GET_MODE_SIZE (TYPE_MODE (type)));
return convert_to_pointer (type, expr); } Note that it always converts to a POINTER_SIZE pointer, regardless of the size of TYPE (the target type), then asserts that the result is the same size as TYPE. However, in s390.c, we have: static bool s390_valid_pointer_mode (enum machine_mode mode) { return (mode == SImode || (TARGET_64BIT && mode == DImode)); } Note that more than one mode is supported simultaneously. Thus, it's legal for the application to specify SI or DI mode for pointer (via __attribute__((mode))), but cc1plus then aborts. So... who is right? Are we supposed to support multiple pointer sizes in the same compilation unit, or not?