Skip to content

warning for UB ! exprs is too light #56190

@Gankra

Description

@Gankra

So this code produces a warning about the &*input expression being unreachable:

enum Void { };

fn process(input: *const Void) {
   let _input = &*input;
}
warning: unreachable expression

I can imagine this needs to "only" be a warning so someone can write some really janky macro code that very carefully ensures the expression isn't ever evaluated. Even if that's the case, I would appreciate that this get its own error-code, or just stronger language to indicate to the user that they are doing something Very Bad. In particular I believe evaluating this expr is Undefined Behaviour.

Activity

added
A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Nov 23, 2018
varkor

varkor commented on Nov 24, 2018

@varkor
Member

I think what we want to be doing is distinguishing between unreachable code due to (control-flow) divergence and due to undefined behaviour in the diagnostics, whereas currently they're treated as the same thing.

hanna-kruppe

hanna-kruppe commented on Nov 24, 2018

@hanna-kruppe
Contributor

&*input should never actually dereference anything or create a Void value, it just converts the raw pointer to a reference. Is the warning based on the assumption that &! is (validity-)uninhabited? AFAIK that is not decided yet.

Gankra

Gankra commented on Nov 24, 2018

@Gankra
ContributorAuthor

Ralf seemed to think this was materially different from transmuting to a reference, but I don't know why.

RalfJung

RalfJung commented on Nov 24, 2018

@RalfJung
Member

Hm, good question actually. I've been thinking that we should assert validity of a value on a dereference (i.e., when evaluating a *, whether or not memory actually gets accessed). I thought that's what is happening here.

But actually, miri only asserts validity when a value is copied at a certain type. That does not happen here. And your example code (after fixing syntax errors) actually has no "unreachable":

    bb0: {                              
        StorageLive(_2);                 // bb0[0]: scope 0 at src/lib.rs:4:8: 4:14
        _2 = &(*_1);                     // bb0[1]: scope 3 at src/lib.rs:4:26: 4:33
        StorageDead(_2);                 // bb0[2]: scope 0 at src/lib.rs:5:1: 5:2
        return;                          // bb0[3]: scope 0 at src/lib.rs:5:2: 5:2
    }

So there is no UB here, that miri sees anyway.

Things are very different if you use ! instead:

    bb0: {                              
        StorageLive(_2);                 // bb0[0]: scope 0 at src/lib.rs:3:8: 3:14
        _2 = &(*_1);                     // bb0[1]: scope 3 at src/lib.rs:3:26: 3:33
        StorageDead(_2);                 // bb0[2]: scope 0 at src/lib.rs:4:1: 4:2
        unreachable;                     // bb0[3]: scope 0 at src/lib.rs:2:29: 4:2
    }
RalfJung

RalfJung commented on Nov 24, 2018

@RalfJung
Member

I don't see a general principle here, but someone decided that a mere deref-without-actual-access on ! is insta-UB.

I think we should probably discuss this as part of rust-lang/unsafe-code-guidelines#8 in the UCG discussions. IMO, if we decide that references do not have to point to initialized data, then &* should not be UB. But if we decide that references have to point to initialized data, there is UB.

removed their assignment
on Nov 25, 2018
estebank

estebank commented on Sep 19, 2019

@estebank
Contributor

The current output for

enum Void { }

fn process(input: *const Void) {
   let _input = unsafe { &*input };
}

fn main() {}

is

warning: enum is never used: `Void`
 --> file2.rs:1:1
  |
1 | enum Void { }
  | ^^^^^^^^^
  |
  = note: #[warn(dead_code)] on by default

warning: function is never used: `process`
 --> file2.rs:3:1
  |
3 | fn process(input: *const Void) {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

17 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.A-type-systemArea: Type systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      warning for UB `!` exprs is too light · Issue #56190 · rust-lang/rust