granite-rust/compiler
Matthias Krüger 78529d9841
Rollup merge of #124921 - RalfJung:offset-from-same-addr, r=oli-obk
offset_from: always allow pointers to point to the same address

This PR implements the last remaining part of the t-opsem consensus in https://github.com/rust-lang/unsafe-code-guidelines/issues/472: always permits offset_from when both pointers have the same address, no matter how they are computed. This is required to achieve *provenance monotonicity*.

Tracking issue: https://github.com/rust-lang/rust/issues/117945

### What is provenance monotonicity and why does it matter?

Provenance monotonicity is the property that adding arbitrary provenance to any no-provenance pointer must never make the program UB. More specifically, in the program state, data in memory is stored as a sequence of [abstract bytes](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#abstract-byte), where each byte can optionally carry provenance. When a pointer is stored in memory, all of the bytes it is stored in carry that provenance. Provenance monotonicity means: if we take some byte that does not have provenance, and give it some arbitrary provenance, then that cannot change program behavior or introduce UB into a UB-free program.

We care about provenance monotonicity because we want to allow the optimizer to remove provenance-stripping operations. Removing a provenance-stripping operation effectively means the program after the optimization has provenance where the program before the optimization did not -- since the provenance removal does not happen in the optimized program. IOW, the compiler transformation added provenance to previously provenance-free bytes. This is exactly what provenance monotonicity lets us do.

We care about removing provenance-stripping operations because `*ptr = *ptr` is, in general, (likely) a provenance-stripping operation. Specifically, consider `ptr: *mut usize` (or any integer type), and imagine the data at `*ptr` is actually a pointer (i.e., we are type-punning between pointers and integers). Then `*ptr` on the right-hand side evaluates to the data in memory *without* any provenance (because [integers do not have provenance](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html#integers-do-not-have-provenance)). Storing that back to `*ptr` means that the abstract bytes `ptr` points to are the same as before, except their provenance is now gone. This makes  `*ptr = *ptr`  a provenance-stripping operation  (Here we assume `*ptr` is fully initialized. If it is not initialized, evaluating `*ptr` to a value is UB, so removing `*ptr = *ptr` is trivially correct.)

### What does `offset_from` have to do with provenance monotonicity?

With `ptr = without_provenance(N)`, `ptr.offset_from(ptr)` is always well-defined and returns 0. By provenance monotonicity, I can now add provenance to the two arguments of `offset_from` and it must still be well-defined. Crucially, I can add *different* provenance to the two arguments, and it must still be well-defined. In other words, this must always be allowed: `ptr1.with_addr(N).offset_from(ptr2.with_addr(N))` (and it returns 0). But the current spec for `offset_from` says that the two pointers must either both be derived from an integer or both be derived from the same allocation, which is not in general true for arbitrary `ptr1`, `ptr2`.

To obtain provenance monotonicity, this PR hence changes the spec for offset_from to say that if both pointers have the same address, the function is always well-defined.

### What further consequences does this have?

It means the compiler can no longer transform `end2 = begin.offset(end.offset_from(begin))` into `end2 = end`. However, it can still be transformed into `end2 = begin.with_addr(end.addr())`, which later parts of the backend (when provenance has been erased) can trivially turn into `end2 = end`.

The only alternative I am aware of is a fundamentally different handling of zero-sized accesses, where a "no provenance" pointer is not allowed to do zero-sized accesses and instead we have a special provenance that indicates "may be used for zero-sized accesses (and nothing else)". `offset` and `offset_from` would then always be UB on a "no provenance" pointer, and permit zero-sized offsets on a "zero-sized provenance" pointer. This achieves provenance monotonicity. That is, however, a breaking change as it contradicts what we landed in https://github.com/rust-lang/rust/pull/117329. It's also a whole bunch of extra UB, which doesn't seem worth it just to achieve that transformation.

### What about the backend?

LLVM currently doesn't have an intrinsic for pointer difference, so we anyway cast to integer and subtract there. That's never UB so it is compatible with any relaxation we may want to apply.

If LLVM gets a `ptrsub` in the future, then plausibly it will be consistent with `ptradd` and [consider two equal pointers to be inbounds](https://github.com/rust-lang/rust/pull/124921#issuecomment-2205795829).
2024-07-15 21:11:47 +02:00
..
rustc Change SIGPIPE ui from #[unix_sigpipe = "..."] to -Zon-broken-pipe=... 2024-05-02 19:48:29 +02:00
rustc_abi Rollup merge of #123043 - GoldsteinE:fix/repr-c-dead-branches, r=oli-obk 2024-07-04 18:16:22 +02:00
rustc_arena Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_ast Rollup merge of #127558 - nnethercote:more-Attribute-cleanups, r=petrochenkov 2024-07-13 20:19:46 -07:00
rustc_ast_ir Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_ast_lowering Auto merge of #127200 - fee1-dead-contrib:trait_def_const_trait, r=compiler-errors 2024-07-09 06:51:35 +00:00
rustc_ast_passes Report usage of lib features in ast validation 2024-07-10 16:53:41 -04:00
rustc_ast_pretty Rollup merge of #127092 - compiler-errors:rtn-dots-redux, r=estebank 2024-07-03 23:30:07 +02:00
rustc_attr Use a dedicated type instead of a reference for the diagnostic context 2024-06-18 15:42:11 +00:00
rustc_baked_icu_data Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_borrowck Rollup merge of #127625 - SkiFire13:revert-comment-deletion, r=workingjubilee 2024-07-12 03:43:36 +02:00
rustc_builtin_macros Rollup merge of #127308 - nnethercote:Attribute-cleanups, r=petrochenkov 2024-07-07 14:22:01 +02:00
rustc_codegen_cranelift Merge commit '659243d85c7489412bd0faa1c068d904a6042941' into sync_cg_clif-2024-07-13 2024-07-13 18:39:03 +00:00
rustc_codegen_gcc Remove lang feature for type ascription 2024-07-11 20:40:38 -04:00
rustc_codegen_llvm Rollup merge of #127654 - nikic:llvm-ndebug-fix, r=cuviper 2024-07-13 00:24:35 -04:00
rustc_codegen_ssa Rollup merge of #127434 - onur-ozkan:use-bootstrap-instead-of-rustbuild, r=Mark-Simulacrum 2024-07-13 20:19:45 -07:00
rustc_const_eval Rollup merge of #124921 - RalfJung:offset-from-same-addr, r=oli-obk 2024-07-15 21:11:47 +02:00
rustc_data_structures Use uplifted rustc-stable-hash crate in rustc_data_structures 2024-07-11 16:51:16 +02:00
rustc_driver Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_driver_impl Move codegen_and_build_linker from Queries to Linker 2024-07-01 11:00:49 +00:00
rustc_error_codes Correct description of E0502 2024-07-06 09:13:14 +03:00
rustc_error_messages Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_errors Rollup merge of #120248 - WaffleLapkin:bonk-ptr-object-casts, r=compiler-errors,oli-obk,lnicola 2024-07-08 16:28:15 +02:00
rustc_expand Rollup merge of #127558 - nnethercote:more-Attribute-cleanups, r=petrochenkov 2024-07-13 20:19:46 -07:00
rustc_feature Rollup merge of #127630 - compiler-errors:type-ascription, r=chenyukang 2024-07-14 20:24:59 +02:00
rustc_fluent_macro Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_fs_util Remove useless tidy-alphabetical markers. 2024-06-20 09:23:20 +10:00
rustc_graphviz Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_hir Add rustdoc support for use<> in (local) RPITs 2024-07-12 05:24:51 -04:00
rustc_hir_analysis find_field does not need to be a query. 2024-07-14 13:25:25 +00:00
rustc_hir_pretty implement new effects desugaring 2024-06-28 10:57:35 +00:00
rustc_hir_typeck find_field does not need to be a query. 2024-07-14 13:25:25 +00:00
rustc_incremental Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_index Auto merge of #127170 - bjorn3:no_specialize_index_borrowck, r=michaelwoerister 2024-07-04 14:24:43 +00:00
rustc_index_macros Remove usage of specialization from newtype_index! 2024-06-30 16:42:53 +00:00
rustc_infer Rollup merge of #127619 - compiler-errors:precise-capturing-better-sugg, r=oli-obk 2024-07-12 13:47:09 -07:00
rustc_interface Rollup merge of #126502 - cuviper:dump-mir-exclude-alloc-bytes, r=estebank 2024-07-12 13:47:05 -07:00
rustc_lexer Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_lint Rollup merge of #127631 - compiler-errors:yeet-fully-norm, r=lcnr 2024-07-12 13:47:09 -07:00
rustc_lint_defs Auto merge of #127097 - compiler-errors:async-closure-lint, r=oli-obk 2024-07-11 06:59:10 +00:00
rustc_llvm Remove LLVMRustDIBuilderInsertDeclareAtEnd return value 2024-07-12 22:15:10 +02:00
rustc_log Bump tracing-tree and allow rendering lines again 2024-06-12 10:11:41 +00:00
rustc_macros Make sure that labels are defined after the primary span in diagnostics 2024-07-10 18:55:45 -04:00
rustc_metadata report pat no field error no recoverd struct variant 2024-07-11 00:18:47 +08:00
rustc_middle Auto merge of #127718 - cjgillot:find_field, r=compiler-errors 2024-07-14 23:35:45 +00:00
rustc_mir_build Address review comments 2024-07-09 22:47:35 +02:00
rustc_mir_dataflow Propagate places through assignments. 2024-07-13 12:02:10 +00:00
rustc_mir_transform Create mapped places upon seeing them in the body. 2024-07-13 11:54:25 +00:00
rustc_monomorphize Auto merge of #113128 - WaffleLapkin:become_trully_unuwuable, r=oli-obk,RalfJung 2024-07-08 04:35:04 +00:00
rustc_next_trait_solver enable fuzzing of SearchGraph 2024-07-12 06:30:19 -04:00
rustc_parse Rollup merge of #127273 - nnethercote:fix-DebugParser, r=workingjubilee 2024-07-14 20:24:58 +02:00
rustc_parse_format Use tidy to sort crate attributes for all compiler crates. 2024-06-12 15:49:10 +10:00
rustc_passes Report usage of lib features in ast validation 2024-07-10 16:53:41 -04:00
rustc_pattern_analysis Replace f16 and f128 pattern matching stubs with real implementations 2024-06-23 04:28:42 -05:00
rustc_privacy Do not ICE in privacy when type inference fails. 2024-06-17 10:09:27 +00:00
rustc_query_impl Allow tracing through item_bounds query invocations on opaques 2024-06-19 08:47:55 +00:00
rustc_query_system enable fuzzing of SearchGraph 2024-07-12 06:30:19 -04:00
rustc_resolve Rollup merge of #127310 - chenyukang:yukang-fix-suggest-import-ice, r=estebank 2024-07-12 13:47:07 -07:00
rustc_sanitizers Split out IntoIterator and non-Iterator constructors for AliasTy/AliasTerm/TraitRef/projection 2024-06-24 11:28:21 -04:00
rustc_serialize chore: remove duplicate words 2024-07-02 11:25:31 +08:00
rustc_session Auto merge of #127670 - compiler-errors:no-type-length-limit, r=jackh726 2024-07-14 12:44:07 +00:00
rustc_smir Remove extern "wasm" ABI 2024-07-11 12:20:26 +02:00
rustc_span Added the xop target feature and xop_target_feature gate 2024-07-12 23:30:22 +05:30
rustc_symbol_mangling Fix FnMut/Fn shim for coroutine-closures that capture references 2024-06-29 17:38:02 -04:00
rustc_target Auto merge of #127265 - harmou01:dev/harmou01/target-spec-metadata, r=Nilstrieb 2024-07-15 08:37:39 +00:00
rustc_trait_selection Rollup merge of #127631 - compiler-errors:yeet-fully-norm, r=lcnr 2024-07-12 13:47:09 -07:00
rustc_traits Split out overflow handling into its own module 2024-07-09 09:51:56 -04:00
rustc_transmute safe transmute: support non-ZST, variantful, uninhabited enums 2024-06-14 21:11:08 +00:00
rustc_ty_utils Auto merge of #123351 - beetrees:x86-ret-snan-rust, r=nikic,workingjubilee 2024-07-12 20:36:43 +00:00
rustc_type_ir Rollup merge of #127627 - lcnr:rustc_search_graph, r=compiler-errors 2024-07-12 14:38:00 +02:00
rustc_type_ir_macros Uplift TraitPredicate 2024-05-11 18:20:00 -04:00
stable_mir Remove extern "wasm" ABI 2024-07-11 12:20:26 +02:00