rust-analyzer / rowan

Apache License 2.0
675 stars 57 forks source link

Undefined Behavior #163

Open Veykril opened 1 month ago

Veykril commented 1 month ago

  error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused
     --> src/green/node.rs:197:35
      |
  195 |         let repr: &Repr = &self.ptr;
      |                            -------- backing allocation comes from here
  196 |         unsafe {
  197 |             let repr: &ReprThin = &*(repr as *const Repr as *const ReprThin);
      |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: casting from `ThinArc<GreenNodeHead, GreenChild>` (8 bytes) to `HeaderSlice<GreenNodeHead, [GreenChild; 0]>` (16 bytes)
      = note: `#[deny(invalid_reference_casting)]` on by default

  error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused
     --> src/green/token.rs:139:35
      |
  138 |             let repr: &Repr = &self.ptr;
      |                                -------- backing allocation comes from here
  139 |             let repr: &ReprThin = &*(repr as *const Repr as *const ReprThin);
      |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: casting from `ThinArc<GreenTokenHead, u8>` (8 bytes) to `HeaderSlice<GreenTokenHead, [u8; 0]>` (16 bytes)

  error: could not compile `rowan` (lib) due to 2 previous errors
saethlin commented 1 month ago

FYI this is a false positive (or just a bug, because the reasoning the lint is engaging in here is totally wrong). I fixed this in https://github.com/rust-lang/rust/pull/124908 but did not realize at the time that it should have been backported.

Veykril commented 1 month ago

So while that fixed the UB reported here, there is still another UB popping up now


error: Undefined Behavior: trying to retag from <212251> for SharedReadWrite permission at alloc69839[0x0], but that tag does not exist in the borrow stack for this location
   --> src\arc.rs:71:18
    |
71  |         unsafe { &*self.ptr() }
    |                  ^^^^^^^^^^^^
    |                  |
    |                  trying to retag from <212251> for SharedReadWrite permission at alloc69839[0x0], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc69839[0x0..0x18]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <212251> was created by a SharedReadOnly retag at offsets [0x8..0x18]
   --> src\green\node.rs:246:33
    |
246 |         let arc = Arc::from_raw(&ptr.as_ref().data as *const ReprThin);
    |                                 ^^^^^^^^^^^^^^^^^^
    = note: BACKTRACE (of the first span) on thread `ast::tests::ensure_mut_panic_on_create`:
    = note: inside `arc::Arc::<arc::HeaderSlice<green::node::GreenNodeHead, [green::node::GreenChild]>>::inner` at src\arc.rs:71:18: 71:30
note: inside `<arc::Arc<arc::HeaderSlice<green::node::GreenNodeHead, [green::node::GreenChild]>> as std::clone::Clone>::clone`
   --> src\arc.rs:106:24
    |
106 |         let old_size = self.inner().count.fetch_add(1, Relaxed);
    |                        ^^^^^^^^^^^^
note: inside closure
   --> src\arc.rs:407:52
    |
407 |         ThinArc::with_arc(self, |a| Arc::into_thin(a.clone()))
    |                                                    ^^^^^^^^^
note: inside `arc::ThinArc::<green::node::GreenNodeHead, green::node::GreenChild>::with_arc::<{closure@src\arc.rs:407:33: 407:36}, arc::ThinArc<green::node::GreenNodeHead, green::node::GreenChild>>`
   --> src\arc.rs:315:22
    |
315 |         let result = f(&transient);
    |                      ^^^^^^^^^^^^^
note: inside `<arc::ThinArc<green::node::GreenNodeHead, green::node::GreenChild> as std::clone::Clone>::clone`
   --> src\arc.rs:407:9
    |
407 |         ThinArc::with_arc(self, |a| Arc::into_thin(a.clone()))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<green::node::GreenNode as std::clone::Clone>::clone`
   --> src\green\node.rs:51:5
    |
48  | #[derive(Clone, PartialEq, Eq, Hash)]
    |          ----- in this derive macro expansion
...
51  |     ptr: ThinArc<GreenNodeHead, GreenChild>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<green::node::GreenNodeData as std::borrow::ToOwned>::to_owned`
   --> src\green\node.rs:61:9
    |
61  |         GreenNode::clone(&green)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `cursor::SyntaxNode::clone_for_update`
   --> src\cursor.rs:554:46
    |
554 |             None => SyntaxNode::new_root_mut(self.green_ref().to_owned()),
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `api::SyntaxNode::<ast::tests::TestLanguage>::clone_for_update`
   --> src\api.rs:247:26
    |
247 |         SyntaxNode::from(self.raw.clone_for_update())
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `ast::tests::ensure_mut_panic_on_create`
   --> src\ast.rs:272:20
    |
272 |         let tree = build_immut_tree().clone_for_update();
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
   --> src\ast.rs:270:36
    |
268 |     #[test]
    |     ------- in this procedural macro expansion
269 |     #[should_panic = "tree is mutable"]
270 |     fn ensure_mut_panic_on_create() {
    |                                    ^
    = note: this error originates in the derive macro `Clone` which comes from the expansion of the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error