Skip to content

Duplicated errors on UB inside a promoted #61821

Closed

Description

@estebank

The following output should only emit the error once:

#![warn(const_err)]

fn main() {
    &{ [1, 2, 3][4] };
}
error: index out of bounds: the len is 3 but the index is 4
  --> $DIR/array-literal-index-oob.rs:2:7
   |
LL |     &{[1, 2, 3][4]};
   |       ^^^^^^^^^^^^
   |
   = note: `#[deny(const_err)]` on by default

error: reaching this expression at runtime will panic or abort
  --> $DIR/array-literal-index-oob.rs:2:7
   |
LL |     &{[1, 2, 3][4]};
   |     --^^^^^^^^^^^^-
   |       |
   |       index out of bounds: the len is 3 but the index is 4

error: aborting due to 2 previous errors

Follow up to #61598

Activity

  1. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    A-diagnosticsArea: Messages for errors, warnings, and lints
    P-lowLow priority
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)
    on Jun 14, 2019
  2. estebank commented on Aug 27, 2019

    @estebank
    Author
  3. changed the title [-]3 duplicated errors on index out of bound const evaluation instead[/-] [+]Duplicated errors on index out of bound const evaluation instead[/+] on Sep 1, 2019
  4. changed the title [-]Duplicated errors on index out of bound const evaluation instead[/-] [+]Duplicated errors on index out of bound const evaluation[/+] on Sep 8, 2019
  5. RalfJung commented on Dec 1, 2019

    @RalfJung
    Member

    One of the two errors is coming from evaluating the Assert MIR terminator that does the bounds-check and panics if it fails. The other message comes from actually evaluating the place[4] even though the index is out-of-bounds.

    What is surprising here is that the evaluation of the place expression even happens even though that should be dead code. @oli-obk @wesleywiser any idea?

    (This is not fixed by #66927.)

  6. RalfJung commented on Dec 1, 2019

    @RalfJung
    Member

    What is surprising here is that the evaluation of the place expression even happens even though that should be dead code.

    The reason is that the MIR of the promoted actually looks like this:

    promoted[0] in  main: i32 = {
        let mut _0: i32;                     // return place in scope 0 at src/main.rs:3:5: 3:20
        let mut _1: i32;                     // in scope 0 at src/main.rs:3:6: 3:20
        let mut _2: [i32; 3];                // in scope 0 at src/main.rs:3:7: 3:16
        let mut _3: usize;                   // in scope 0 at src/main.rs:3:17: 3:18
    
        bb0: {
            _2 = [const 1i32, const 2i32, const 3i32]; // bb0[0]: scope 0 at src/main.rs:3:7: 3:16
            _3 = const 4usize;               // bb0[1]: scope 0 at src/main.rs:3:17: 3:18
            _1 = _2[_3];                     // bb0[2]: scope 0 at src/main.rs:3:7: 3:19
            _0 = move _1;                    // bb0[3]: scope 0 at src/main.rs:3:5: 3:20
            return;                          // bb0[4]: scope 0 at src/main.rs:3:5: 3:20
        }
    }
    

    Notice the unchecked array access. That's how this is not dead code.

    I assume the other error comes from ConstProp (likely of the Assert terminator), but I am not sure.

  7. RalfJung commented on Dec 1, 2019

    @RalfJung
    Member

    Cc @ecstatic-morse @eddyb because promotion is involved

  8. eddyb commented on Dec 2, 2019

    @eddyb
    Contributor

    I don't think const_err should include promoteds, since any checks for anything they might do are still in the runtime code (doing anything else would require something much more complex than what we have today).

    But also, if we constant-fold the assert, we can know that using the promoted is dead code (I guess this doesn't apply to codegen generating those warnings instead of constant folding).

  9. RalfJung commented on Feb 10, 2020

    @RalfJung
    Member

    @eddyb so basically, const_prop should cease to emit warnings when it is working inside a promoted? Or maybe it shouldn't run there at all?
    Cc @wesleywiser

  10. eddyb commented on Feb 10, 2020

    @eddyb
    Contributor

    You could still have warnings inside a promoted that are not from things covered by Asserts, but other odd conditions const_prop checks.

    Basically "this expression will panic at runtime" type warnings shouldn't be emitted from a promoted, others might be fine.

  11. RalfJung commented on Feb 11, 2020

    @RalfJung
    Member

    Actually, I think the first ("error: index out of bounds") is not a warning in any meaningful way... trying to evaluate that promoted fails with a hard const-error ("UB: OOB array access") and produces no result. I does not seem wise to me to not report such hard errors.

    I am pretty sure the "reaching this expression at runtime will panic or abort" part is not from inside the promoted. That one gets raised by const-prop when partially evaluating the Assert terminator that is left in the fn.

    So @eddyb I don't think any of your proposals so far actually solves this problem. Or do you suggest we ignore UB in promoteds?

  12. RalfJung commented on Feb 11, 2020

    @RalfJung
    Member

    Also, in latest master a third warning crept in again:

    warning: erroneous constant used
      --> $DIR/array-literal-index-oob.rs:7:5
       |
    LL |     &{ [1, 2, 3][4] };
       |     ^^^^^^^^^^^^^^^^^ referenced constant has errors
    

    The third error was added by #67000

  13. RalfJung commented on Feb 11, 2020

    @RalfJung
    Member

    FWIW, this affects not just array indexing but also div-by-zero. At least the two are consistent. ;)

  14. changed the title [-]Duplicated errors on index out of bound const evaluation[/-] [+]Duplicated errors on UB inside a promoted[/+] on Feb 11, 2020
  15. eddyb commented on Feb 11, 2020

    @eddyb
    Contributor

    Or do you suggest we ignore UB in promoteds?

    If we want to be clever we could only check promoteds that are still reachable after constant folding + simplify_cfg.
    Because the Assert guarding the use of the erroring promoted would have become unconditional.

    Actually, do we have an unconditional Panic terminator?

  16. added
    D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.
    on Feb 15, 2020
  17. added a commit that references this issue on Feb 20, 2020
  18. steveklabnik commented on Jan 14, 2021

    @steveklabnik
    Contributor

    Triage: no change

  19. RalfJung commented on Jan 15, 2021

    @RalfJung
    Member

    #80579 will solve this by not promoting division and array indexing any more when they could fail.

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-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-verboseDiagnostics: Too much output caused by a single piece of incorrect code.P-lowLow priorityT-compilerRelevant to the compiler 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