- Feature Name: undefined_intrinsic
- Start Date: 2015-01-25
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)
Translate undefined generic intrinsics to an LLVM unreachable
and a lint.
Many generic intrinsics are only defined for particular type substitutions. For
example, transmute
is only defined when both arguments have the same size,
and atomic operations are only defined for types with a CPU-supported size
and alignmen.
Unsafe code often desires to do these operations opportunistically - for example, to use an atomic operation if that is supported, and to otherwise default to mutual exclusion.
In addition, the precise constraints required by these operations are hard to encode in the type-system, which means that even if we wanted to use specialization for opportunsitic operations, we would be restricted.
Finally, the current strategy for handling undefined intrinsics is to cause compilation errors in a fairly fragmented and buggy way (that's it, either rustc errors or LLVM assertions). As that kind of undefined use is often unintentional, this has the useful effect of not causing subtle crashes, but is obviously suboptimal.
When translating an undefined intrinsic, translate it to an LLVM unreachable
instruction, without causing an error or emitting invalid LLVM-IR.
This is not a safety issue as intrinsics are unsafe, and unsafe code can
easily cause an LLVM unreachable
through generating code that exhibits
UB.
To retain the error-detecting effect of the previous strategy, introduce
a undefined_intrinsic
lint, which should warn when an unreachable
is generated in this way. As intrinsics are generated by monomorphization,
the lint would need to be stored in metadata.
Metadata lints are annoying and may pose implementation difficulties. In addition they make intrinsic reexports more different from intrinsic wrappers than they are now.
If we do not check generic functions, we risk accidental modifications
causing hard-to-track unreachable
generation and code erasure. Luckily,
unlike other kinds of UB, these unreachable
instructions would still
appear in debug mode.
- Keep the current fragmented strategy, with its disadvantages.
- Do not do the
undefined_intrinsic
check on generic functions, or cross-crate instantiations.
What should we do with the lint?