about summary refs log tree commit diff
path: root/tests/coverage/unicode.coverage
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-01-09 00:19:33 +0100
committerGitHub <noreply@github.com>2024-01-09 00:19:33 +0100
commit70e3f8d240ea6454be252db5d335d1f5bcb86764 (patch)
tree6acec7895569fc77d88622a1216ed8cf2be923d6 /tests/coverage/unicode.coverage
parentee7d4c15615ed0b6e1fd61c7b8b3462f32a9d68e (diff)
parent6971e9332d9a7fb1567a6df0f30d03452f505ed3 (diff)
Rollup merge of #119033 - Zalathar:unicode, r=davidtwco
coverage: `llvm-cov` expects column numbers to be bytes, not code points

Normally the compiler emits column numbers as a 1-based number of Unicode code points.

But when we embed coverage mappings for `-Cinstrument-coverage`, those mappings will ultimately be read by the `llvm-cov` tool. That tool assumes that column numbers are 1-based numbers of *bytes*, and relies on that assumption when slicing up source code to apply highlighting (in HTML reports, and in text-based reports with colour).

For the very common case of all-ASCII source code, bytes and code points are the same, so the difference isn't noticeable. But for code that contains non-ASCII characters, emitting column numbers as code points will result in `llvm-cov` slicing strings in the wrong places, producing mangled output or fatal errors.

(See https://github.com/taiki-e/cargo-llvm-cov/issues/275 as an example of what can go wrong.)
Diffstat (limited to 'tests/coverage/unicode.coverage')
-rw-r--r--tests/coverage/unicode.coverage40
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
new file mode 100644
index 00000000000..b284a557d57
--- /dev/null
+++ b/tests/coverage/unicode.coverage
@@ -0,0 +1,40 @@
+   LL|       |// edition: 2021
+   LL|       |// ignore-windows - we can't force `llvm-cov` to use ANSI escapes on Windows
+   LL|       |// llvm-cov-flags: --use-color
+   LL|       |
+   LL|       |// Check that column numbers are denoted in bytes, so that they don't cause
+   LL|       |// `llvm-cov` to fail or emit malformed output.
+   LL|       |//
+   LL|       |// Note that when `llvm-cov` prints ^ arrows on a subsequent line, it simply
+   LL|       |// inserts one space character for each "column", with no understanding of
+   LL|       |// Unicode or character widths. So those arrows will tend to be misaligned
+   LL|       |// for non-ASCII source code, regardless of whether column numbers are code
+   LL|       |// points or bytes.
+   LL|       |
+   LL|      1|fn main() {
+   LL|     33|    for _İ in 'А'..='Я' { /* Я */ }
+                      ^32                ^32
+   LL|       |
+   LL|      1|    if 申し訳ございません() && 申し訳ございません() {
+                                                      ^0
+   LL|      0|        println!("true");
+   LL|      1|    }
+   LL|       |
+   LL|      1|    サビ();
+   LL|      1|}
+   LL|       |
+   LL|      1|fn 申し訳ございません() -> bool {
+   LL|      1|    std::hint::black_box(false)
+   LL|      1|}
+   LL|       |
+   LL|       |macro_rules! macro_that_defines_a_function {
+   LL|       |    (fn $名:ident () $体:tt) => {
+   LL|      1|        fn $名 () $体 fn 他 () {}
+                                      ^0
+   LL|       |    }
+   LL|       |}
+   LL|       |
+   LL|       |macro_that_defines_a_function! {
+   LL|       |    fn サビ() {}
+   LL|       |}
+