about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs17
-rw-r--r--src/tools/compiletest/src/runtest.rs1
-rw-r--r--src/tools/run-make-support/Cargo.toml1
-rw-r--r--src/tools/run-make-support/src/diff/mod.rs28
-rw-r--r--src/tools/run-make-support/src/diff/tests.rs22
-rw-r--r--src/tools/run-make-support/src/lib.rs1
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/assembly/manual-eq-efficient.rs22
-rw-r--r--tests/run-make/repr128-dwarf/Makefile16
-rw-r--r--tests/run-make/repr128-dwarf/main.rs (renamed from tests/run-make/repr128-dwarf/lib.rs)5
-rw-r--r--tests/run-make/repr128-dwarf/rmake.rs75
12 files changed, 164 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 656e9d40d30..ca69536855e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3318,6 +3318,7 @@ dependencies = [
 name = "run_make_support"
 version = "0.0.0"
 dependencies = [
+ "gimli",
  "object 0.34.0",
  "regex",
  "similar",
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 770a5cdb232..5bc9d7615e2 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -25,7 +25,7 @@ use crate::core::build_steps::llvm;
 use crate::core::build_steps::tool::{self, Tool};
 use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::TargetSelection;
-use crate::utils::channel;
+use crate::utils::channel::{self, Info};
 use crate::utils::helpers::{exe, is_dylib, output, t, target_supports_cranelift_backend, timeit};
 use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball};
 use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
@@ -991,10 +991,17 @@ impl Step for PlainSourceTarball {
 
         // Create the version file
         builder.create(&plain_dst_src.join("version"), &builder.rust_version());
-        if let Some(info) = builder.rust_info().info() {
-            channel::write_commit_hash_file(plain_dst_src, &info.sha);
-            channel::write_commit_info_file(plain_dst_src, info);
-        }
+
+        // Create the files containing git info, to ensure --version outputs the same.
+        let write_git_info = |info: Option<&Info>, path: &Path| {
+            if let Some(info) = info {
+                t!(std::fs::create_dir_all(path));
+                channel::write_commit_hash_file(path, &info.sha);
+                channel::write_commit_info_file(path, info);
+            }
+        };
+        write_git_info(builder.rust_info().info(), plain_dst_src);
+        write_git_info(builder.cargo_info.info(), &plain_dst_src.join("./src/tools/cargo"));
 
         // If we're building from git or tarball sources, we need to vendor
         // a complete distribution.
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index da51b33a9d6..0a861d62c37 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3825,6 +3825,7 @@ impl<'test> TestCx<'test> {
             .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
             .arg("--extern")
             .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
+            .arg("--edition=2021")
             .arg(&self.testpaths.file.join("rmake.rs"))
             .env("TARGET", &self.config.target)
             .env("PYTHON", &self.config.python)
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 61a24c97e77..cf4ae4b16cd 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -8,3 +8,4 @@ object = "0.34.0"
 similar = "2.5.0"
 wasmparser = "0.118.2"
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
+gimli = "0.28.1"
diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs
index 54532c6e35b..332126939c0 100644
--- a/src/tools/run-make-support/src/diff/mod.rs
+++ b/src/tools/run-make-support/src/diff/mod.rs
@@ -1,3 +1,4 @@
+use regex::Regex;
 use similar::TextDiff;
 use std::path::Path;
 
@@ -14,12 +15,19 @@ pub struct Diff {
     expected_name: Option<String>,
     actual: Option<String>,
     actual_name: Option<String>,
+    normalizers: Vec<(String, String)>,
 }
 
 impl Diff {
     /// Construct a bare `diff` invocation.
     pub fn new() -> Self {
-        Self { expected: None, expected_name: None, actual: None, actual_name: None }
+        Self {
+            expected: None,
+            expected_name: None,
+            actual: None,
+            actual_name: None,
+            normalizers: Vec::new(),
+        }
     }
 
     /// Specify the expected output for the diff from a file.
@@ -58,15 +66,29 @@ impl Diff {
         self
     }
 
+    /// Specify a regex that should replace text in the "actual" text that will be compared.
+    pub fn normalize<R: Into<String>, I: Into<String>>(
+        &mut self,
+        regex: R,
+        replacement: I,
+    ) -> &mut Self {
+        self.normalizers.push((regex.into(), replacement.into()));
+        self
+    }
+
     /// Executes the diff process, prints any differences to the standard error.
     #[track_caller]
     pub fn run(&self) {
         let expected = self.expected.as_ref().expect("expected text not set");
-        let actual = self.actual.as_ref().expect("actual text not set");
+        let mut actual = self.actual.as_ref().expect("actual text not set").to_string();
         let expected_name = self.expected_name.as_ref().unwrap();
         let actual_name = self.actual_name.as_ref().unwrap();
+        for (regex, replacement) in &self.normalizers {
+            let re = Regex::new(regex).expect("bad regex in custom normalization rule");
+            actual = re.replace_all(&actual, replacement).into_owned();
+        }
 
-        let output = TextDiff::from_lines(expected, actual)
+        let output = TextDiff::from_lines(expected, &actual)
             .unified_diff()
             .header(expected_name, actual_name)
             .to_string();
diff --git a/src/tools/run-make-support/src/diff/tests.rs b/src/tools/run-make-support/src/diff/tests.rs
index e6d72544b7e..286548bef61 100644
--- a/src/tools/run-make-support/src/diff/tests.rs
+++ b/src/tools/run-make-support/src/diff/tests.rs
@@ -36,4 +36,26 @@ test failed: `EXPECTED_TEXT` is different from `ACTUAL_TEXT`
 
         assert_eq!(output.downcast_ref::<String>().unwrap(), expected_output);
     }
+
+    #[test]
+    fn test_normalize() {
+        let expected = "
+running 2 tests
+..
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+";
+        let actual = "
+running 2 tests
+..
+
+test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
+";
+
+        diff()
+            .expected_text("EXPECTED_TEXT", expected)
+            .actual_text("ACTUAL_TEXT", actual)
+            .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME")
+            .run();
+    }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 76e8838d27c..a874c1313b5 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -15,6 +15,7 @@ use std::env;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output};
 
+pub use gimli;
 pub use object;
 pub use regex;
 pub use wasmparser;
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index a2179b895b3..69c6dda4b19 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -235,7 +235,6 @@ run-make/relocation-model/Makefile
 run-make/relro-levels/Makefile
 run-make/remap-path-prefix-dwarf/Makefile
 run-make/remap-path-prefix/Makefile
-run-make/repr128-dwarf/Makefile
 run-make/reproducible-build-2/Makefile
 run-make/reproducible-build/Makefile
 run-make/resolve-rename/Makefile
diff --git a/tests/assembly/manual-eq-efficient.rs b/tests/assembly/manual-eq-efficient.rs
new file mode 100644
index 00000000000..817ce94f476
--- /dev/null
+++ b/tests/assembly/manual-eq-efficient.rs
@@ -0,0 +1,22 @@
+// Regression test for #106269
+//@ assembly-output: emit-asm
+//@ compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
+//@ only-x86_64
+//@ ignore-sgx
+
+pub struct S {
+    a: u8,
+    b: u8,
+    c: u8,
+    d: u8,
+}
+
+// CHECK-LABEL: manual_eq:
+#[no_mangle]
+pub fn manual_eq(s1: &S, s2: &S) -> bool {
+    // CHECK: mov [[REG:[a-z0-9]+]], dword ptr [{{[a-z0-9]+}}]
+    // CHECK-NEXT: cmp [[REG]], dword ptr [{{[a-z0-9]+}}]
+    // CHECK-NEXT: sete al
+    // CHECK: ret
+    s1.a == s2.a && s1.b == s2.b && s1.c == s2.c && s1.d == s2.d
+}
diff --git a/tests/run-make/repr128-dwarf/Makefile b/tests/run-make/repr128-dwarf/Makefile
deleted file mode 100644
index 3f933042724..00000000000
--- a/tests/run-make/repr128-dwarf/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# ignore-windows
-# This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit
-# enums.
-
-include ../tools.mk
-
-all:
-	$(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )"
-	"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value	(<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )"
diff --git a/tests/run-make/repr128-dwarf/lib.rs b/tests/run-make/repr128-dwarf/main.rs
index 63675441d4b..57923a8386d 100644
--- a/tests/run-make/repr128-dwarf/lib.rs
+++ b/tests/run-make/repr128-dwarf/main.rs
@@ -1,4 +1,3 @@
-#![crate_type = "lib"]
 #![feature(repr128)]
 
 // Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian
@@ -21,3 +20,7 @@ pub enum I128Enum {
 }
 
 pub fn f(_: U128Enum, _: I128Enum) {}
+
+fn main() {
+    f(U128Enum::U128A, I128Enum::I128A);
+}
diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs
new file mode 100644
index 00000000000..f6375344f8f
--- /dev/null
+++ b/tests/run-make/repr128-dwarf/rmake.rs
@@ -0,0 +1,75 @@
+//@ ignore-windows
+// This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit enums.
+
+extern crate run_make_support;
+
+use gimli::{AttributeValue, Dwarf, EndianRcSlice, Reader, RunTimeEndian};
+use object::{Object, ObjectSection};
+use run_make_support::{gimli, object, rustc, tmp_dir};
+use std::borrow::Cow;
+use std::collections::HashMap;
+use std::rc::Rc;
+
+fn main() {
+    let output = tmp_dir().join("repr128");
+    rustc().input("main.rs").arg("-o").arg(&output).arg("-Cdebuginfo=2").run();
+    // Mach-O uses packed debug info
+    let dsym_location = output
+        .with_extension("dSYM")
+        .join("Contents")
+        .join("Resources")
+        .join("DWARF")
+        .join("repr128");
+    let output =
+        std::fs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output })
+            .unwrap();
+    let obj = object::File::parse(output.as_slice()).unwrap();
+    let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big };
+    let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> {
+        let data = obj.section_by_name(section.name()).map(|s| s.uncompressed_data().unwrap());
+        Ok(EndianRcSlice::new(Rc::from(data.unwrap_or_default().as_ref()), endian))
+    })
+    .unwrap();
+    let mut iter = dwarf.units();
+    let mut still_to_find = HashMap::from([
+        ("U128A", 0_u128),
+        ("U128B", 1_u128),
+        ("U128C", u64::MAX as u128 + 1),
+        ("U128D", u128::MAX),
+        ("I128A", 0_i128 as u128),
+        ("I128B", (-1_i128) as u128),
+        ("I128C", i128::MIN as u128),
+        ("I128D", i128::MAX as u128),
+    ]);
+    while let Some(header) = iter.next().unwrap() {
+        let unit = dwarf.unit(header).unwrap();
+        let mut cursor = unit.entries();
+        while let Some((_, entry)) = cursor.next_dfs().unwrap() {
+            if entry.tag() == gimli::constants::DW_TAG_enumerator {
+                let name = dwarf
+                    .attr_string(
+                        &unit,
+                        entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(),
+                    )
+                    .unwrap();
+                let name = name.to_string().unwrap();
+                if let Some(expected) = still_to_find.remove(name.as_ref()) {
+                    match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value()
+                    {
+                        AttributeValue::Block(value) => {
+                            assert_eq!(
+                                value.to_slice().unwrap(),
+                                expected.to_le_bytes().as_slice(),
+                                "{name}"
+                            );
+                        }
+                        value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"),
+                    }
+                }
+            }
+        }
+    }
+    if !still_to_find.is_empty() {
+        panic!("Didn't find debug entries for {still_to_find:?}");
+    }
+}