Skip to content

Commit

Permalink
Rollup merge of rust-lang#48522 - etaoins:fix-find-width-of-character…
Browse files Browse the repository at this point in the history
…-at-span-bounds-check, r=estebank

Fix find_width_of_character_at_span bounds check

Commit 0bd9667 added bounds checking of our current target byte position to prevent infinite loops. Unfortunately it was comparing the file-relative `target` versus the global `file_start_pos` and `file_end_pos`.

The result is failing to detect multibyte characters unless their file-relative offset fit within their global offset. This causes other parts of the compiler to generate spans pointing to the middle of a
multibyte character which will ultimately panic in `bytepos_to_file_charpos`.

Fix by comparing the `target` to the total file size when moving forward and doing checked subtraction when moving backwards. This should preserve the intent of the bounds check while removing the offset confusion.

cc @davidtwco

Fixes rust-lang#48508
  • Loading branch information
Manishearth committed Mar 1, 2018
2 parents 38f4d55 + 363d604 commit 75b8c10
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,17 +705,20 @@ impl CodeMap {
};
debug!("find_width_of_character_at_span: snippet=`{:?}`", snippet);

let file_start_pos = local_begin.fm.start_pos.to_usize();
let file_end_pos = local_begin.fm.end_pos.to_usize();
debug!("find_width_of_character_at_span: file_start_pos=`{:?}` file_end_pos=`{:?}`",
file_start_pos, file_end_pos);

let mut target = if forwards { end_index + 1 } else { end_index - 1 };
debug!("find_width_of_character_at_span: initial target=`{:?}`", target);

while !snippet.is_char_boundary(target - start_index)
&& target >= file_start_pos && target <= file_end_pos {
target = if forwards { target + 1 } else { target - 1 };
while !snippet.is_char_boundary(target - start_index) && target < source_len {
target = if forwards {
target + 1
} else {
match target.checked_sub(1) {
Some(target) => target,
None => {
break;
}
}
};
debug!("find_width_of_character_at_span: target=`{:?}`", target);
}
debug!("find_width_of_character_at_span: final target=`{:?}`", target);
Expand Down
16 changes: 16 additions & 0 deletions src/test/run-pass/issue-48508-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-test Not a test. Used by issue-48508.rs

pub fn other() -> f64 {
let µ = 1.0;
µ
}
28 changes: 28 additions & 0 deletions src/test/run-pass/issue-48508.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Regression test for issue #48508:
//
// Confusion between global and local file offsets caused incorrect handling of multibyte character
// spans when compiling multiple files. One visible effect was an ICE generating debug information
// when a multibyte character is at the end of a scope. The problematic code is actually in
// issue-48508-aux.rs

// compile-flags:-g
// ignore-pretty issue #37195

#![feature(non_ascii_idents)]

#[path = "issue-48508-aux.rs"]
mod other_file;

fn main() {
other_file::other();
}

0 comments on commit 75b8c10

Please sign in to comment.