diff --git a/src/tools/run-make-support/src/env.rs b/src/tools/run-make-support/src/env.rs index f52524e7d54cd..e6460fb93d3e9 100644 --- a/src/tools/run-make-support/src/env.rs +++ b/src/tools/run-make-support/src/env.rs @@ -17,3 +17,10 @@ pub fn env_var_os(name: &str) -> OsString { None => panic!("failed to retrieve environment variable {name:?}"), } } + +/// Check if `NO_DEBUG_ASSERTIONS` is set (usually this may be set in CI jobs). +#[track_caller] +#[must_use] +pub fn no_debug_assertions() -> bool { + std::env::var_os("NO_DEBUG_ASSERTIONS").is_some() +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b85191970de62..72a29d9dd7f06 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -21,6 +21,7 @@ pub mod run; pub mod scoped_run; pub mod string; pub mod targets; +pub mod symbols; // Internally we call our fs-related support module as `fs`, but re-export its content as `rfs` // to tests to avoid colliding with commonly used `use std::fs;`. diff --git a/src/tools/run-make-support/src/symbols.rs b/src/tools/run-make-support/src/symbols.rs new file mode 100644 index 0000000000000..4e63dcb86e372 --- /dev/null +++ b/src/tools/run-make-support/src/symbols.rs @@ -0,0 +1,37 @@ +use object::{self, Object, ObjectSymbol, SymbolIterator}; +use std::fs; +use std::path::Path; + +/// iterate through the symbols in an object file. +/// +/// uses a callback because SymbolIterator does not own its data +pub fn with_symbol_iter(path: P, func: F) -> R +where + P: AsRef, + //I: Iterator + 'a, + F: FnOnce(&mut SymbolIterator<'_, '_>) -> R, +{ + let raw_bytes = fs::read(path).expect("unable to read file"); + let f = object::File::parse(raw_bytes.as_slice()).expect("unable to parse file"); + let mut iter = f.symbols(); + func(&mut iter) +} + +pub fn any_symbol_contains(path: impl AsRef, substrings: &[&str]) -> bool { + with_symbol_iter(path, |syms| { + for sym in syms { + for substring in substrings { + if sym + .name_bytes() + .unwrap() + .windows(substring.len()) + .any(|x| x == substring.as_bytes()) + { + eprintln!("{:?} contains {}", sym, substring); + return true; + } + } + } + false + }) +} diff --git a/tests/run-make/fmt-write-bloat/rmake_.rs b/tests/run-make/fmt-write-bloat/rmake_.rs new file mode 100644 index 0000000000000..34e98cfd934b9 --- /dev/null +++ b/tests/run-make/fmt-write-bloat/rmake_.rs @@ -0,0 +1,16 @@ +//@ ignore-windows +//@ ignore-cross-compile + +use run_make_support::{env::no_debug_assertions, rustc, symbols::any_symbol_contains}; + +fn main() { + rustc().input("main.rs").run(); + // panic machinery identifiers, these should not appear in the final binary + let mut panic_syms = vec!["panic_bounds_check", "Debug"]; + if no_debug_assertions() { + // if debug assertions are allowed, we need to allow these, + // otherwise, add them to the list of symbols to deny. + panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]); + } + assert!(!any_symbol_contains("main", &panic_syms)); +}