From d27fac618d0e9e054fbc65130788eaacda259a9f Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Sun, 25 Feb 2018 11:41:08 +1100 Subject: [PATCH 1/3] Fix find_width_of_character_at_span bounds check Commit 0bd96671f0 added bounds checking of our current target byte position to prevent infinite loops. Unfortunately it was comparing the file-relative `target` versus the global relative `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. Fixes #48508 --- src/libsyntax/codemap.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index df5845f6c217d..5d36f39b2e43c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -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); From c237d4f859c47ddc3f03b485915d2cadbd741a1c Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Mon, 26 Feb 2018 19:25:10 +1100 Subject: [PATCH 2/3] Add test for #48508 This is named for the issue as it's testing the specific details of that bug. It's a bit tricky as the ICE requires multiple files and debug info enabled to trigger. --- src/test/run-pass/issue-48508-aux.rs | 16 ++++++++++++++++ src/test/run-pass/issue-48508.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/test/run-pass/issue-48508-aux.rs create mode 100644 src/test/run-pass/issue-48508.rs diff --git a/src/test/run-pass/issue-48508-aux.rs b/src/test/run-pass/issue-48508-aux.rs new file mode 100644 index 0000000000000..a00361a2c9d33 --- /dev/null +++ b/src/test/run-pass/issue-48508-aux.rs @@ -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 or the MIT license +// , 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; + µ +} diff --git a/src/test/run-pass/issue-48508.rs b/src/test/run-pass/issue-48508.rs new file mode 100644 index 0000000000000..303ea2aa6012f --- /dev/null +++ b/src/test/run-pass/issue-48508.rs @@ -0,0 +1,27 @@ +// 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 or the MIT license +// , 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 + +#![feature(non_ascii_idents)] + +#[path = "issue-48508-aux.rs"] +mod other_file; + +fn main() { + other_file::other(); +} From 363d6040fdac7baa8eb18a804f02832fec5ad35f Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Thu, 1 Mar 2018 17:51:14 +1100 Subject: [PATCH 3/3] Add ignore-pretty for issue-48506.rs The out-of-line module #37195 --- src/test/run-pass/issue-48508.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/issue-48508.rs b/src/test/run-pass/issue-48508.rs index 303ea2aa6012f..1b10d873f11c4 100644 --- a/src/test/run-pass/issue-48508.rs +++ b/src/test/run-pass/issue-48508.rs @@ -16,6 +16,7 @@ // issue-48508-aux.rs // compile-flags:-g +// ignore-pretty issue #37195 #![feature(non_ascii_idents)]