Skip to content

Commit cac55bd

Browse files
authored
Rollup merge of #144616 - Zalathar:try-in-macro, r=jieyouxu
coverage: Regression test for "function name is empty" bug Regression test for #141577, which was triggered by #144298. The bug was triggered by a particular usage of the `?` try operator in a proc-macro expansion. Thanks to lqd for the minimization at #144571 (comment). --- I have manually verified that reverting the relevant follow-up fixes (#144480 and #144530) causes this test to reproduce the bug: ```sh git revert -m1 8aa3d41 c462895 ``` --- r? compiler
2 parents 9578146 + 7ca4d1f commit cac55bd

8 files changed

+266
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//@ edition: 2024
2+
// (The proc-macro crate doesn't need to be instrumented.)
3+
//@ compile-flags: -Cinstrument-coverage=off
4+
5+
use proc_macro::TokenStream;
6+
7+
/// Minimized form of `#[derive(arbitrary::Arbitrary)]` that still triggers
8+
/// the original bug.
9+
const CODE: &str = "
10+
impl Arbitrary for MyEnum {
11+
fn try_size_hint() -> Option<usize> {
12+
Some(0)?;
13+
None
14+
}
15+
}
16+
";
17+
18+
#[proc_macro_attribute]
19+
pub fn attr(_attr: TokenStream, _item: TokenStream) -> TokenStream {
20+
CODE.parse().unwrap()
21+
}
22+
23+
#[proc_macro]
24+
pub fn bang(_item: TokenStream) -> TokenStream {
25+
CODE.parse().unwrap()
26+
}
27+
28+
#[proc_macro_derive(Arbitrary)]
29+
pub fn derive_arbitrary(_item: TokenStream) -> TokenStream {
30+
CODE.parse().unwrap()
31+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Function name: <try_in_macro::MyEnum as try_in_macro::Arbitrary>::try_size_hint
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 1e, 2a, 00, 2b]
3+
Number of files: 1
4+
- file 0 => $DIR/try-in-macro.rs
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 30, 42) to (start + 0, 43)
8+
Highest counter ID seen: (none)
9+
10+
Function name: try_in_macro::main
11+
Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02]
12+
Number of files: 1
13+
- file 0 => $DIR/try-in-macro.rs
14+
Number of expressions: 0
15+
Number of file 0 mappings: 3
16+
- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 10)
17+
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
18+
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
19+
Highest counter ID seen: c0
20+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
LL| |//! Regression test for <https://github.com/rust-lang/rust/issues/141577>.
2+
LL| |//!
3+
LL| |//! The changes in <https://github.com/rust-lang/rust/pull/144298> exposed a
4+
LL| |//! latent bug that would sometimes cause the compiler to emit a covfun record
5+
LL| |//! for a function, but not emit a corresponding PGO symbol name entry, because
6+
LL| |//! the function did not have any physical coverage counters. The `llvm-cov`
7+
LL| |//! tool would then fail to resolve the covfun record's function name hash,
8+
LL| |//! and exit with the cryptic error:
9+
LL| |//!
10+
LL| |//! ```text
11+
LL| |//! malformed instrumentation profile data: function name is empty
12+
LL| |//! ```
13+
LL| |//!
14+
LL| |//! The bug was then triggered in the wild by the macro-expansion of
15+
LL| |//! `#[derive(arbitrary::Arbitrary)]`.
16+
LL| |//!
17+
LL| |//! This test uses a minimized form of the `Arbitrary` derive macro that was
18+
LL| |//! found to still trigger the original bug. The bug could also be triggered
19+
LL| |//! by a bang proc-macro or an attribute proc-macro.
20+
LL| |
21+
LL| |//@ edition: 2024
22+
LL| |//@ revisions: attr bang derive
23+
LL| |//@ proc-macro: try_in_macro_helper.rs
24+
LL| |
25+
LL| |trait Arbitrary {
26+
LL| | fn try_size_hint() -> Option<usize>;
27+
LL| |}
28+
LL| |
29+
LL| |// Expand via an attribute proc-macro.
30+
LL| |#[cfg_attr(attr, try_in_macro_helper::attr)]
31+
LL| |const _: () = ();
32+
LL| |
33+
LL| |// Expand via a regular bang-style proc-macro.
34+
LL| |#[cfg(bang)]
35+
LL| |try_in_macro_helper::bang!();
36+
LL| |
37+
LL| |// Expand via a derive proc-macro.
38+
LL| |#[cfg_attr(derive, derive(try_in_macro_helper::Arbitrary))]
39+
LL| |enum MyEnum {}
40+
LL| |
41+
LL| 1|fn main() {
42+
LL| 1| MyEnum::try_size_hint();
43+
LL| 1|}
44+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Function name: <try_in_macro::MyEnum as try_in_macro::Arbitrary>::try_size_hint
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 23, 1c, 00, 1d]
3+
Number of files: 1
4+
- file 0 => $DIR/try-in-macro.rs
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 35, 28) to (start + 0, 29)
8+
Highest counter ID seen: (none)
9+
10+
Function name: try_in_macro::main
11+
Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02]
12+
Number of files: 1
13+
- file 0 => $DIR/try-in-macro.rs
14+
Number of expressions: 0
15+
Number of file 0 mappings: 3
16+
- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 10)
17+
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
18+
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
19+
Highest counter ID seen: c0
20+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
LL| |//! Regression test for <https://github.com/rust-lang/rust/issues/141577>.
2+
LL| |//!
3+
LL| |//! The changes in <https://github.com/rust-lang/rust/pull/144298> exposed a
4+
LL| |//! latent bug that would sometimes cause the compiler to emit a covfun record
5+
LL| |//! for a function, but not emit a corresponding PGO symbol name entry, because
6+
LL| |//! the function did not have any physical coverage counters. The `llvm-cov`
7+
LL| |//! tool would then fail to resolve the covfun record's function name hash,
8+
LL| |//! and exit with the cryptic error:
9+
LL| |//!
10+
LL| |//! ```text
11+
LL| |//! malformed instrumentation profile data: function name is empty
12+
LL| |//! ```
13+
LL| |//!
14+
LL| |//! The bug was then triggered in the wild by the macro-expansion of
15+
LL| |//! `#[derive(arbitrary::Arbitrary)]`.
16+
LL| |//!
17+
LL| |//! This test uses a minimized form of the `Arbitrary` derive macro that was
18+
LL| |//! found to still trigger the original bug. The bug could also be triggered
19+
LL| |//! by a bang proc-macro or an attribute proc-macro.
20+
LL| |
21+
LL| |//@ edition: 2024
22+
LL| |//@ revisions: attr bang derive
23+
LL| |//@ proc-macro: try_in_macro_helper.rs
24+
LL| |
25+
LL| |trait Arbitrary {
26+
LL| | fn try_size_hint() -> Option<usize>;
27+
LL| |}
28+
LL| |
29+
LL| |// Expand via an attribute proc-macro.
30+
LL| |#[cfg_attr(attr, try_in_macro_helper::attr)]
31+
LL| |const _: () = ();
32+
LL| |
33+
LL| |// Expand via a regular bang-style proc-macro.
34+
LL| |#[cfg(bang)]
35+
LL| |try_in_macro_helper::bang!();
36+
LL| |
37+
LL| |// Expand via a derive proc-macro.
38+
LL| |#[cfg_attr(derive, derive(try_in_macro_helper::Arbitrary))]
39+
LL| |enum MyEnum {}
40+
LL| |
41+
LL| 1|fn main() {
42+
LL| 1| MyEnum::try_size_hint();
43+
LL| 1|}
44+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Function name: <try_in_macro::MyEnum as try_in_macro::Arbitrary>::try_size_hint
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 26, 38, 00, 39]
3+
Number of files: 1
4+
- file 0 => $DIR/try-in-macro.rs
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 38, 56) to (start + 0, 57)
8+
Highest counter ID seen: (none)
9+
10+
Function name: try_in_macro::main
11+
Raw bytes (19): 0x[01, 01, 00, 03, 01, 29, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02]
12+
Number of files: 1
13+
- file 0 => $DIR/try-in-macro.rs
14+
Number of expressions: 0
15+
Number of file 0 mappings: 3
16+
- Code(Counter(0)) at (prev + 41, 1) to (start + 0, 10)
17+
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 26)
18+
- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
19+
Highest counter ID seen: c0
20+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
LL| |//! Regression test for <https://github.com/rust-lang/rust/issues/141577>.
2+
LL| |//!
3+
LL| |//! The changes in <https://github.com/rust-lang/rust/pull/144298> exposed a
4+
LL| |//! latent bug that would sometimes cause the compiler to emit a covfun record
5+
LL| |//! for a function, but not emit a corresponding PGO symbol name entry, because
6+
LL| |//! the function did not have any physical coverage counters. The `llvm-cov`
7+
LL| |//! tool would then fail to resolve the covfun record's function name hash,
8+
LL| |//! and exit with the cryptic error:
9+
LL| |//!
10+
LL| |//! ```text
11+
LL| |//! malformed instrumentation profile data: function name is empty
12+
LL| |//! ```
13+
LL| |//!
14+
LL| |//! The bug was then triggered in the wild by the macro-expansion of
15+
LL| |//! `#[derive(arbitrary::Arbitrary)]`.
16+
LL| |//!
17+
LL| |//! This test uses a minimized form of the `Arbitrary` derive macro that was
18+
LL| |//! found to still trigger the original bug. The bug could also be triggered
19+
LL| |//! by a bang proc-macro or an attribute proc-macro.
20+
LL| |
21+
LL| |//@ edition: 2024
22+
LL| |//@ revisions: attr bang derive
23+
LL| |//@ proc-macro: try_in_macro_helper.rs
24+
LL| |
25+
LL| |trait Arbitrary {
26+
LL| | fn try_size_hint() -> Option<usize>;
27+
LL| |}
28+
LL| |
29+
LL| |// Expand via an attribute proc-macro.
30+
LL| |#[cfg_attr(attr, try_in_macro_helper::attr)]
31+
LL| |const _: () = ();
32+
LL| |
33+
LL| |// Expand via a regular bang-style proc-macro.
34+
LL| |#[cfg(bang)]
35+
LL| |try_in_macro_helper::bang!();
36+
LL| |
37+
LL| |// Expand via a derive proc-macro.
38+
LL| |#[cfg_attr(derive, derive(try_in_macro_helper::Arbitrary))]
39+
LL| |enum MyEnum {}
40+
LL| |
41+
LL| 1|fn main() {
42+
LL| 1| MyEnum::try_size_hint();
43+
LL| 1|}
44+

tests/coverage/try-in-macro.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/141577>.
2+
//!
3+
//! The changes in <https://github.com/rust-lang/rust/pull/144298> exposed a
4+
//! latent bug that would sometimes cause the compiler to emit a covfun record
5+
//! for a function, but not emit a corresponding PGO symbol name entry, because
6+
//! the function did not have any physical coverage counters. The `llvm-cov`
7+
//! tool would then fail to resolve the covfun record's function name hash,
8+
//! and exit with the cryptic error:
9+
//!
10+
//! ```text
11+
//! malformed instrumentation profile data: function name is empty
12+
//! ```
13+
//!
14+
//! The bug was then triggered in the wild by the macro-expansion of
15+
//! `#[derive(arbitrary::Arbitrary)]`.
16+
//!
17+
//! This test uses a minimized form of the `Arbitrary` derive macro that was
18+
//! found to still trigger the original bug. The bug could also be triggered
19+
//! by a bang proc-macro or an attribute proc-macro.
20+
21+
//@ edition: 2024
22+
//@ revisions: attr bang derive
23+
//@ proc-macro: try_in_macro_helper.rs
24+
25+
trait Arbitrary {
26+
fn try_size_hint() -> Option<usize>;
27+
}
28+
29+
// Expand via an attribute proc-macro.
30+
#[cfg_attr(attr, try_in_macro_helper::attr)]
31+
const _: () = ();
32+
33+
// Expand via a regular bang-style proc-macro.
34+
#[cfg(bang)]
35+
try_in_macro_helper::bang!();
36+
37+
// Expand via a derive proc-macro.
38+
#[cfg_attr(derive, derive(try_in_macro_helper::Arbitrary))]
39+
enum MyEnum {}
40+
41+
fn main() {
42+
MyEnum::try_size_hint();
43+
}

0 commit comments

Comments
 (0)