about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2018-02-28 23:33:31 -0800
committerManish Goregaokar <manishsmail@gmail.com>2018-03-01 09:29:40 -0800
commit75b8c103912f1d5a38d4f4ecb2564a0010444902 (patch)
tree3c4d4bf250db2c16837d587aced46f153ace1f7d /src
parent38f4d557d0c227230a580b328ded5c06a4a20509 (diff)
parent363d6040fdac7baa8eb18a804f02832fec5ad35f (diff)
downloadrust-75b8c103912f1d5a38d4f4ecb2564a0010444902.tar.gz
rust-75b8c103912f1d5a38d4f4ecb2564a0010444902.zip
Rollup merge of #48522 - etaoins:fix-find-width-of-character-at-span-bounds-check, r=estebank
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 `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 #48508
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/codemap.rs19
-rw-r--r--src/test/run-pass/issue-48508-aux.rs16
-rw-r--r--src/test/run-pass/issue-48508.rs28
3 files changed, 55 insertions, 8 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 926548b6031..fcd2b236213 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);
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 00000000000..a00361a2c9d
--- /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 <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;
+    µ
+}
diff --git a/src/test/run-pass/issue-48508.rs b/src/test/run-pass/issue-48508.rs
new file mode 100644
index 00000000000..1b10d873f11
--- /dev/null
+++ b/src/test/run-pass/issue-48508.rs
@@ -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();
+}