summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa')
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml15
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl313
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs169
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs91
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs17
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs41
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs33
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/coverageinfo/map.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs71
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs153
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs18
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs63
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs95
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs12
27 files changed, 864 insertions, 433 deletions
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index c55991e00..0ac12d32b 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -7,15 +7,14 @@ edition = "2021"
test = false
[dependencies]
-ar_archive_writer = "0.1.1"
+ar_archive_writer = "0.1.3"
bitflags = "1.2.1"
cc = "1.0.69"
itertools = "0.10.1"
tracing = "0.1"
-libc = "0.2.50"
jobserver = "0.1.22"
tempfile = "3.2"
-thorin-dwp = "0.4"
+thorin-dwp = "0.6"
pathdiff = "0.2.0"
serde_json = "1.0.59"
snap = "1"
@@ -29,6 +28,7 @@ rustc_span = { path = "../rustc_span" }
rustc_middle = { path = "../rustc_middle" }
rustc_type_ir = { path = "../rustc_type_ir" }
rustc_attr = { path = "../rustc_attr" }
+rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
@@ -42,7 +42,14 @@ rustc_query_system = { path = "../rustc_query_system" }
rustc_target = { path = "../rustc_target" }
rustc_session = { path = "../rustc_session" }
+[target.'cfg(unix)'.dependencies]
+libc = "0.2.50"
+
[dependencies.object]
-version = "0.30.1"
+version = "0.31.1"
default-features = false
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]
+
+[target.'cfg(windows)'.dependencies.windows]
+version = "0.48.0"
+features = ["Win32_Globalization"]
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 243be0e1f..9aa2b2e2b 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -1,293 +1,306 @@
-codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error}
-
-codegen_ssa_version_script_write_failure = failed to write version script: {$error}
+codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender
-codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error}
+codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
-codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64
+codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
-codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
+codegen_ssa_archive_build_failure =
+ failed to build archive: {$error}
-codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender
+codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
-codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
+codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error}
+codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
+
+codegen_ssa_erroneous_constant = erroneous constant encountered
+
+codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
+
+codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
+
+codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
+
+codegen_ssa_failed_to_write = failed to write {$path}: {$error}
+
codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
-codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
+codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
+ .note = an unsuffixed integer value, e.g., `1`, is expected
codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
-
-codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
+codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
-codegen_ssa_rlib_missing_format = could not find formats for rlibs
+codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
+ .note = the attribute requires exactly one argument
-codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file
+codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`
-codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}`
+codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
-codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)
+codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
-codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
+codegen_ssa_invalid_monomorphization_cast_fat_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast fat pointer `{$ty}`
-codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
+codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`
-codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
+codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`
-codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
+codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`
-codegen_ssa_thorin_read_input_failure = failed to read input file
+codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`
-codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind
+codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type
-codegen_ssa_thorin_parse_input_object_file = failed to parse input object file
+codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}`
-codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file
+codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type
-codegen_ssa_thorin_parse_archive_member = failed to parse archive member
+codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}`
-codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object
+codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
-codegen_ssa_thorin_decompress_data = failed to decompress compressed section
+codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
-codegen_ssa_thorin_section_without_name = section without name at offset {$offset}
+codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
-codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset}
+codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
-codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset}
+codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
-codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset}
+codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
-codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id})
+codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
-codegen_ssa_thorin_no_compilation_units = input object has no compilation units
+codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
-codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit
+codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
-codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit
+codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
-codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}`
+codegen_ssa_invalid_monomorphization_shuffle_index_not_constant = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is not a constant
-codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations
+codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is out of bounds (limit {$total_len})
-codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute
+codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_parse_unit_header = failed to parse unit header
+codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_parse_unit = failed to parse unit
+codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format}
+codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section
+codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section
+codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
-codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section
+codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
-codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index
+codegen_ssa_invalid_monomorphization_third_arg_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of third argument `{$third_arg}` to be a signed integer type
-codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index
+codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
-codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index
+codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
-codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data
+codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
-codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections
+codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
-codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package
+codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`
-codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier)
+codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
-codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit})
+codegen_ssa_invalid_monomorphization_vector_argument = invalid monomorphization of `{$name}` intrinsic: vector argument `{$in_ty}`'s element type `{$in_elem}`, expected integer element type
-codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found
+codegen_ssa_invalid_no_sanitize = invalid argument for `no_sanitize`
+ .note = expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
-codegen_ssa_thorin_not_output_object_created = no output object was created from inputs
+codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed
-codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings
+codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64
-codegen_ssa_thorin_io = {$error}
-codegen_ssa_thorin_object_read = {$error}
-codegen_ssa_thorin_object_write = {$error}
-codegen_ssa_thorin_gimli_read = {$error}
-codegen_ssa_thorin_gimli_write = {$error}
+codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error}
codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error
-codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer
-
-codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
+codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
-codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
+codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}
-codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
+codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
.note = {$error}
-codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}`
- .note = {$error}
- .command_note = {$command_formatted}
+codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
-codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
+codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
-codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
+codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error}
-codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
+codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
-codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
- .note = {$output}
+codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
-codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error}
+codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
-codegen_ssa_stripping_debu_info_failed = stripping debug info with `{$util}` failed: {$status}
- .note = {$output}
+codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
-codegen_ssa_unable_to_run = unable to run `{$util}`: {$error}
+codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
+ .help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead
-codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
+codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
-codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
+codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
-codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
+codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
-codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}
+codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
+ .note = {$output}
-codegen_ssa_failed_to_write = failed to write {$path}: {$error}
+codegen_ssa_read_file = failed to read file: {$message}
-codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error}
+codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer
codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error}
-codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
+codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)
-codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error}
-codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
+codegen_ssa_rlib_missing_format = could not find formats for rlibs
-codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
+codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}`
-codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
+codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file
-codegen_ssa_read_file = failed to read file: {$message}
+codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
-codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
+codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
-codegen_ssa_archive_build_failure =
- failed to build archive: {$error}
+codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
-codegen_ssa_unknown_archive_kind =
- Don't know how to build archive of type: {$kind}
+codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
-codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
+codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status}
+ .note = {$output}
-codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
- .help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead
+codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error}
-codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error}
+codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method
+ .label = cannot be applied to safe trait method
+ .label_def = not an `unsafe` function
-codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed
+codegen_ssa_thorin_decompress_data = failed to decompress compressed section
-codegen_ssa_erroneous_constant = erroneous constant encountered
+codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit})
-codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
+codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data
-codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering
+codegen_ssa_thorin_gimli_read = {$error}
+codegen_ssa_thorin_gimli_write = {$error}
-codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic
+codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format}
-codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
+codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object
-codegen_ssa_unknown_atomic_operation = unknown atomic operation
+codegen_ssa_thorin_io = {$error}
+codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id})
-codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
+codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found
-codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`
+codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}`
-codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}`
+codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings
-codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}`
+codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections
-codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type
+codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package
-codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
+codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset}
-codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_no_compilation_units = input object has no compilation units
-codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit
-codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_not_output_object_created = no output object was created from inputs
-codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier)
-codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_object_read = {$error}
+codegen_ssa_thorin_object_write = {$error}
+codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section
-codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`
+codegen_ssa_thorin_parse_archive_member = failed to parse archive member
-codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
+codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section
-codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
+codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file
-codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
+codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind
-codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
+codegen_ssa_thorin_parse_input_object_file = failed to parse input object file
-codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
+codegen_ssa_thorin_parse_unit = failed to parse unit
-codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
+codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations
-codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
+codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute
-codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
+codegen_ssa_thorin_parse_unit_header = failed to parse unit header
-codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
+codegen_ssa_thorin_read_input_failure = failed to read input file
-codegen_ssa_invalid_monomorphization_shuffle_index_not_constant = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is not a constant
+codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset}
-codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is out of bounds (limit {$total_len})
+codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index
-codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
+codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index
-codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
+codegen_ssa_thorin_section_without_name = section without name at offset {$offset}
-codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`
+codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section
-codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
+codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit
-codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
+codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index
-codegen_ssa_invalid_monomorphization_vector_argument = invalid monomorphization of `{$name}` intrinsic: vector argument `{$in_ty}`'s element type `{$in_elem}`, expected integer element type
+codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset}
-codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
+codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}`
+ .note = {$error}
+ .command_note = {$command_formatted}
-codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`
+codegen_ssa_unable_to_run = unable to run `{$util}`: {$error}
-codegen_ssa_invalid_monomorphization_third_arg_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of third argument `{$third_arg}` to be a signed integer type
+codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error}
-codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
+codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error}
-codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`
+codegen_ssa_unknown_archive_kind =
+ Don't know how to build archive of type: {$kind}
-codegen_ssa_invalid_monomorphization_cast_fat_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast fat pointer `{$ty}`
+codegen_ssa_unknown_atomic_operation = unknown atomic operation
-codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`
+codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic
-codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`
+codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
-codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
+codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
-codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
+codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
-codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type
+codegen_ssa_version_script_write_failure = failed to write version script: {$error}
+
+codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 66ec8f5f5..1c464b3ec 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -233,6 +233,7 @@ impl<'a> ArArchiveBuilder<'a> {
"bsd" => ArchiveKind::Bsd,
"darwin" => ArchiveKind::Darwin,
"coff" => ArchiveKind::Coff,
+ "aix_big" => ArchiveKind::AixBig,
kind => {
self.sess.emit_fatal(UnknownArchiveKind { kind });
}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index eecfe13bb..8a00c42a0 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -9,6 +9,7 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
+use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
@@ -21,7 +22,6 @@ use rustc_session::utils::NativeLibKind;
/// need out of the shared crate context before we get rid of it.
use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
-use rustc_span::DebuggerVisualizerFile;
use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy};
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
@@ -40,7 +40,6 @@ use regex::Regex;
use tempfile::Builder as TempFileBuilder;
use itertools::Itertools;
-use std::borrow::Borrow;
use std::cell::OnceCell;
use std::collections::BTreeSet;
use std::ffi::OsString;
@@ -54,7 +53,7 @@ use std::{env, fmt, fs, io, mem, str};
pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
if let Err(e) = fs::remove_file(path) {
if e.kind() != io::ErrorKind::NotFound {
- diag_handler.err(&format!("failed to remove {}: {}", path.display(), e));
+ diag_handler.err(format!("failed to remove {}: {}", path.display(), e));
}
}
}
@@ -547,12 +546,40 @@ fn link_staticlib<'a>(
ab.build(out_filename);
- if !all_native_libs.is_empty() {
- if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
- print_native_static_libs(sess, &all_native_libs);
+ let crates = codegen_results.crate_info.used_crates.iter();
+
+ let fmts = codegen_results
+ .crate_info
+ .dependency_formats
+ .iter()
+ .find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None })
+ .expect("no dependency formats for staticlib");
+
+ let mut all_rust_dylibs = vec![];
+ for &cnum in crates {
+ match fmts.get(cnum.as_usize() - 1) {
+ Some(&Linkage::Dynamic) => {}
+ _ => continue,
+ }
+ let crate_name = codegen_results.crate_info.crate_name[&cnum];
+ let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum];
+ if let Some((path, _)) = &used_crate_source.dylib {
+ all_rust_dylibs.push(&**path);
+ } else {
+ if used_crate_source.rmeta.is_some() {
+ sess.emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name });
+ } else {
+ sess.emit_fatal(errors::LinkRlibError::NotFound { crate_name });
+ }
}
}
+ all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries);
+
+ if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
+ print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs);
+ }
+
Ok(())
}
@@ -576,17 +603,17 @@ fn link_dwarf_object<'a>(
impl<Relocations> ThorinSession<Relocations> {
fn alloc_mmap(&self, data: Mmap) -> &Mmap {
- (*self.arena_mmap.alloc(data)).borrow()
+ &*self.arena_mmap.alloc(data)
}
}
impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> {
fn alloc_data(&self, data: Vec<u8>) -> &[u8] {
- (*self.arena_data.alloc(data)).borrow()
+ &*self.arena_data.alloc(data)
}
fn alloc_relocation(&self, data: Relocations) -> &Relocations {
- (*self.arena_relocations.alloc(data)).borrow()
+ &*self.arena_relocations.alloc(data)
}
fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> {
@@ -860,7 +887,7 @@ fn link_natively<'a>(
if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
- let escaped_output = escape_string(&output);
+ let escaped_output = escape_linker_output(&output, flavor);
// FIXME: Add UI tests for this error.
let err = errors::LinkingFailed {
linker_path: &linker_path,
@@ -1052,6 +1079,83 @@ fn escape_string(s: &[u8]) -> String {
}
}
+#[cfg(not(windows))]
+fn escape_linker_output(s: &[u8], _flavour: LinkerFlavor) -> String {
+ escape_string(s)
+}
+
+/// If the output of the msvc linker is not UTF-8 and the host is Windows,
+/// then try to convert the string from the OEM encoding.
+#[cfg(windows)]
+fn escape_linker_output(s: &[u8], flavour: LinkerFlavor) -> String {
+ // This only applies to the actual MSVC linker.
+ if flavour != LinkerFlavor::Msvc(Lld::No) {
+ return escape_string(s);
+ }
+ match str::from_utf8(s) {
+ Ok(s) => return s.to_owned(),
+ Err(_) => match win::locale_byte_str_to_string(s, win::oem_code_page()) {
+ Some(s) => s,
+ // The string is not UTF-8 and isn't valid for the OEM code page
+ None => format!("Non-UTF-8 output: {}", s.escape_ascii()),
+ },
+ }
+}
+
+/// Wrappers around the Windows API.
+#[cfg(windows)]
+mod win {
+ use windows::Win32::Globalization::{
+ GetLocaleInfoEx, MultiByteToWideChar, CP_OEMCP, LOCALE_IUSEUTF8LEGACYOEMCP,
+ LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_RETURN_NUMBER, MB_ERR_INVALID_CHARS,
+ };
+
+ /// Get the Windows system OEM code page. This is most notably the code page
+ /// used for link.exe's output.
+ pub fn oem_code_page() -> u32 {
+ unsafe {
+ let mut cp: u32 = 0;
+ // We're using the `LOCALE_RETURN_NUMBER` flag to return a u32.
+ // But the API requires us to pass the data as though it's a [u16] string.
+ let len = std::mem::size_of::<u32>() / std::mem::size_of::<u16>();
+ let data = std::slice::from_raw_parts_mut(&mut cp as *mut u32 as *mut u16, len);
+ let len_written = GetLocaleInfoEx(
+ LOCALE_NAME_SYSTEM_DEFAULT,
+ LOCALE_IUSEUTF8LEGACYOEMCP | LOCALE_RETURN_NUMBER,
+ Some(data),
+ );
+ if len_written as usize == len { cp } else { CP_OEMCP }
+ }
+ }
+ /// Try to convert a multi-byte string to a UTF-8 string using the given code page
+ /// The string does not need to be null terminated.
+ ///
+ /// This is implemented as a wrapper around `MultiByteToWideChar`.
+ /// See <https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar>
+ ///
+ /// It will fail if the multi-byte string is longer than `i32::MAX` or if it contains
+ /// any invalid bytes for the expected encoding.
+ pub fn locale_byte_str_to_string(s: &[u8], code_page: u32) -> Option<String> {
+ // `MultiByteToWideChar` requires a length to be a "positive integer".
+ if s.len() > isize::MAX as usize {
+ return None;
+ }
+ // Error if the string is not valid for the expected code page.
+ let flags = MB_ERR_INVALID_CHARS;
+ // Call MultiByteToWideChar twice.
+ // First to calculate the length then to convert the string.
+ let mut len = unsafe { MultiByteToWideChar(code_page, flags, s, None) };
+ if len > 0 {
+ let mut utf16 = vec![0; len as usize];
+ len = unsafe { MultiByteToWideChar(code_page, flags, s, Some(&mut utf16)) };
+ if len > 0 {
+ return utf16.get(..len as usize).map(String::from_utf16_lossy);
+ }
+ }
+ None
+ }
+}
+
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
// On macOS the runtimes are distributed as dylibs which should be linked to
// both executables and dynamic shared objects. Everywhere else the runtimes
@@ -1294,8 +1398,12 @@ enum RlibFlavor {
StaticlibBase,
}
-fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
- let lib_args: Vec<_> = all_native_libs
+fn print_native_static_libs(
+ sess: &Session,
+ all_native_libs: &[NativeLib],
+ all_rust_dylibs: &[&Path],
+) {
+ let mut lib_args: Vec<_> = all_native_libs
.iter()
.filter(|l| relevant_lib(sess, l))
.filter_map(|lib| {
@@ -1325,11 +1433,46 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
}
})
.collect();
+ for path in all_rust_dylibs {
+ // FIXME deduplicate with add_dynamic_crate
+
+ // Just need to tell the linker about where the library lives and
+ // what its name is
+ let parent = path.parent();
+ if let Some(dir) = parent {
+ let dir = fix_windows_verbatim_for_gcc(dir);
+ if sess.target.is_like_msvc {
+ let mut arg = String::from("/LIBPATH:");
+ arg.push_str(&dir.display().to_string());
+ lib_args.push(arg);
+ } else {
+ lib_args.push("-L".to_owned());
+ lib_args.push(dir.display().to_string());
+ }
+ }
+ let stem = path.file_stem().unwrap().to_str().unwrap();
+ // Convert library file-stem into a cc -l argument.
+ let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
+ let lib = &stem[prefix..];
+ let path = parent.unwrap_or_else(|| Path::new(""));
+ if sess.target.is_like_msvc {
+ // When producing a dll, the MSVC linker may not actually emit a
+ // `foo.lib` file if the dll doesn't actually export any symbols, so we
+ // check to see if the file is there and just omit linking to it if it's
+ // not present.
+ let name = format!("{}.dll.lib", lib);
+ if path.join(&name).exists() {
+ lib_args.push(name);
+ }
+ } else {
+ lib_args.push(format!("-l{}", lib));
+ }
+ }
if !lib_args.is_empty() {
sess.emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability
// Note: This must not be translated as tools are allowed to depend on this exact string.
- sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
+ sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
}
}
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 65dfc325a..cd56f85cc 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -144,7 +144,7 @@ pub fn get_linker<'a>(
cmd,
sess,
target_cpu,
- hinted_static: false,
+ hinted_static: None,
is_ld: cc == Cc::No,
is_gnu: flavor.is_gnu(),
}) as Box<dyn Linker>,
@@ -214,7 +214,7 @@ pub struct GccLinker<'a> {
cmd: Command,
sess: &'a Session,
target_cpu: &'a str,
- hinted_static: bool, // Keeps track of the current hinting mode.
+ hinted_static: Option<bool>, // Keeps track of the current hinting mode.
// Link as ld
is_ld: bool,
is_gnu: bool,
@@ -275,9 +275,9 @@ impl<'a> GccLinker<'a> {
if !self.takes_hints() {
return;
}
- if !self.hinted_static {
+ if self.hinted_static != Some(true) {
self.linker_arg("-Bstatic");
- self.hinted_static = true;
+ self.hinted_static = Some(true);
}
}
@@ -285,9 +285,9 @@ impl<'a> GccLinker<'a> {
if !self.takes_hints() {
return;
}
- if self.hinted_static {
+ if self.hinted_static != Some(false) {
self.linker_arg("-Bdynamic");
- self.hinted_static = false;
+ self.hinted_static = Some(false);
}
}
@@ -1484,25 +1484,25 @@ impl<'a> L4Bender<'a> {
pub struct AixLinker<'a> {
cmd: Command,
sess: &'a Session,
- hinted_static: bool,
+ hinted_static: Option<bool>,
}
impl<'a> AixLinker<'a> {
pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
- AixLinker { cmd: cmd, sess: sess, hinted_static: false }
+ AixLinker { cmd: cmd, sess: sess, hinted_static: None }
}
fn hint_static(&mut self) {
- if !self.hinted_static {
+ if self.hinted_static != Some(true) {
self.cmd.arg("-bstatic");
- self.hinted_static = true;
+ self.hinted_static = Some(true);
}
}
fn hint_dynamic(&mut self) {
- if self.hinted_static {
+ if self.hinted_static != Some(false) {
self.cmd.arg("-bdynamic");
- self.hinted_static = false;
+ self.hinted_static = Some(false);
}
}
@@ -1631,7 +1631,7 @@ impl<'a> Linker for AixLinker<'a> {
}
};
if let Err(e) = res {
- self.sess.fatal(&format!("failed to write export file: {}", e));
+ self.sess.fatal(format!("failed to write export file: {}", e));
}
self.cmd.arg(format!("-bE:{}", path.to_str().unwrap()));
}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d5d843702..ad27b854d 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,9 +12,9 @@ use object::{
use snap::write::FrameEncoder;
+use object::elf::NT_GNU_PROPERTY_TYPE_0;
use rustc_data_structures::memmap::Mmap;
-use rustc_data_structures::owned_slice::try_slice_owned;
-use rustc_data_structures::sync::MetadataRef;
+use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
use rustc_metadata::fs::METADATA_FILENAME;
use rustc_metadata::EncodedMetadata;
use rustc_session::cstore::MetadataLoader;
@@ -38,7 +38,7 @@ pub struct DefaultMetadataLoader;
fn load_metadata_with(
path: &Path,
f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
-) -> Result<MetadataRef, String> {
+) -> Result<OwnedSlice, String> {
let file =
File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?;
@@ -48,7 +48,7 @@ fn load_metadata_with(
}
impl MetadataLoader for DefaultMetadataLoader {
- fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
+ fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
load_metadata_with(path, |data| {
let archive = object::read::archive::ArchiveFile::parse(&*data)
.map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?;
@@ -68,7 +68,7 @@ impl MetadataLoader for DefaultMetadataLoader {
})
}
- fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
+ fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
}
}
@@ -93,6 +93,54 @@ pub(super) fn search_for_section<'a>(
.map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e))
}
+fn add_gnu_property_note(
+ file: &mut write::Object<'static>,
+ architecture: Architecture,
+ binary_format: BinaryFormat,
+ endianness: Endianness,
+) {
+ // check bti protection
+ if binary_format != BinaryFormat::Elf
+ || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64)
+ {
+ return;
+ }
+
+ let section = file.add_section(
+ file.segment_name(StandardSegment::Data).to_vec(),
+ b".note.gnu.property".to_vec(),
+ SectionKind::Note,
+ );
+ let mut data: Vec<u8> = Vec::new();
+ let n_namsz: u32 = 4; // Size of the n_name field
+ let n_descsz: u32 = 16; // Size of the n_desc field
+ let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor
+ let header_values = [n_namsz, n_descsz, n_type];
+ header_values.iter().for_each(|v| {
+ data.extend_from_slice(&match endianness {
+ Endianness::Little => v.to_le_bytes(),
+ Endianness::Big => v.to_be_bytes(),
+ })
+ });
+ data.extend_from_slice(b"GNU\0"); // Owner of the program property note
+ let pr_type: u32 = match architecture {
+ Architecture::X86_64 => 0xc0000002,
+ Architecture::Aarch64 => 0xc0000000,
+ _ => unreachable!(),
+ };
+ let pr_datasz: u32 = 4; //size of the pr_data field
+ let pr_data: u32 = 3; //program property descriptor
+ let pr_padding: u32 = 0;
+ let property_values = [pr_type, pr_datasz, pr_data, pr_padding];
+ property_values.iter().for_each(|v| {
+ data.extend_from_slice(&match endianness {
+ Endianness::Little => v.to_le_bytes(),
+ Endianness::Big => v.to_be_bytes(),
+ })
+ });
+ file.append_section_data(section, &data, 8);
+}
+
pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
let endianness = match sess.target.options.endian {
Endian::Little => Endianness::Little,
@@ -140,6 +188,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
};
let mut file = write::Object::new(binary_format, architecture, endianness);
+ if sess.target.is_like_osx {
+ if let Some(build_version) = macho_object_build_version_for_target(&sess.target) {
+ file.set_macho_build_version(build_version)
+ }
+ }
let e_flags = match architecture {
Architecture::Mips => {
let arch = match sess.target.options.cpu.as_ref() {
@@ -205,10 +258,38 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
_ => elf::ELFOSABI_NONE,
};
let abi_version = 0;
+ add_gnu_property_note(&mut file, architecture, binary_format, endianness);
file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
Some(file)
}
+/// Apple's LD, when linking for Mac Catalyst, requires object files to
+/// contain information about what they were built for (LC_BUILD_VERSION):
+/// the platform (macOS/watchOS etc), minimum OS version, and SDK version.
+/// This returns a `MachOBuildVersion` if necessary for the target.
+fn macho_object_build_version_for_target(
+ target: &Target,
+) -> Option<object::write::MachOBuildVersion> {
+ if !target.llvm_target.ends_with("-macabi") {
+ return None;
+ }
+ /// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
+ /// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
+ fn pack_version((major, minor): (u32, u32)) -> u32 {
+ (major << 16) | (minor << 8)
+ }
+
+ let platform = object::macho::PLATFORM_MACCATALYST;
+ let min_os = (14, 0);
+ let sdk = (16, 2);
+
+ let mut build_version = object::write::MachOBuildVersion::default();
+ build_version.platform = platform;
+ build_version.minos = pack_version(min_os);
+ build_version.sdk = pack_version(sdk);
+ Some(build_version)
+}
+
pub enum MetadataPosition {
First,
Last,
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index d0fd3cd76..a8b6030ac 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -2,7 +2,7 @@ use crate::base::allocator_kind_for_codegen;
use std::collections::hash_map::Entry::*;
-use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
+use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
@@ -11,7 +11,7 @@ use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
};
use rustc_middle::query::LocalCrate;
-use rustc_middle::ty::query::{ExternProviders, Providers};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, SymbolName, TyCtxt};
@@ -241,6 +241,17 @@ fn exported_symbols_provider_local(
used: false,
},
));
+
+ let exported_symbol =
+ ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE));
+ symbols.push((
+ exported_symbol,
+ SymbolExportInfo {
+ level: SymbolExportLevel::Rust,
+ kind: SymbolExportKind::Data,
+ used: false,
+ },
+ ))
}
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
@@ -333,7 +344,7 @@ fn exported_symbols_provider_local(
match *mono_item {
MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => {
if substs.non_erasable_generics().next().is_some() {
- let symbol = ExportedSymbol::Generic(def.did, substs);
+ let symbol = ExportedSymbol::Generic(def, substs);
symbols.push((
symbol,
SymbolExportInfo {
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 2dda4cd16..c323372bd 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -872,7 +872,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| {
let source_file = in_incr_comp_dir(&incr_comp_session_dir, saved_path);
debug!(
- "copying pre-existing module `{}` from {:?} to {}",
+ "copying preexisting module `{}` from {:?} to {}",
module.name,
source_file,
output_path.display()
@@ -1821,9 +1821,15 @@ impl SharedEmitterMain {
let source = sess
.source_map()
.new_source_file(FileName::inline_asm_source_code(&buffer), buffer);
- let source_span = Span::with_root_ctxt(source.start_pos, source.end_pos);
- let spans: Vec<_> =
- spans.iter().map(|sp| source_span.from_inner(*sp)).collect();
+ let spans: Vec<_> = spans
+ .iter()
+ .map(|sp| {
+ Span::with_root_ctxt(
+ source.normalized_byte_pos(sp.start as u32),
+ source.normalized_byte_pos(sp.end as u32),
+ )
+ })
+ .collect();
err.span_note(spans, "instantiated into assembly here");
}
@@ -1833,7 +1839,7 @@ impl SharedEmitterMain {
sess.abort_if_errors();
}
Ok(SharedEmitterMessage::Fatal(msg)) => {
- sess.fatal(&msg);
+ sess.fatal(msg);
}
Err(_) => {
break;
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index c5ca7936a..ab7dd1ba8 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -13,32 +13,29 @@ use crate::mir::place::PlaceRef;
use crate::traits::*;
use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind};
-use rustc_ast::expand::allocator::AllocatorKind;
+use rustc_ast::expand::allocator::{global_fn_name, AllocatorKind, ALLOCATOR_METHODS};
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
-
-use rustc_data_structures::sync::par_iter;
-#[cfg(parallel_compiler)]
-use rustc_data_structures::sync::ParallelIterator;
+use rustc_data_structures::sync::par_map;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_metadata::EncodedMetadata;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
+use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_middle::middle::exported_symbols;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::middle::lang_items;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem};
+use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Symbol;
-use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
use rustc_target::abi::{Align, FIRST_VARIANT};
use std::collections::BTreeSet;
@@ -494,7 +491,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(rust_main, start_ty, vec![arg_argc, arg_argv])
};
- let result = bx.call(start_ty, None, start_fn, &args, None);
+ let result = bx.call(start_ty, None, None, start_fn, &args, None);
let cast = bx.intcast(result, cx.type_int(), true);
bx.ret(cast);
@@ -689,7 +686,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// This likely is a temporary measure. Once we don't have to support the
// non-parallel compiler anymore, we can compile CGUs end-to-end in
// parallel and get rid of the complicated scheduling logic.
- let mut pre_compiled_cgus = if cfg!(parallel_compiler) {
+ let mut pre_compiled_cgus = if tcx.sess.threads() > 1 {
tcx.sess.time("compile_first_CGU_batch", || {
// Try to find one CGU to compile per thread.
let cgus: Vec<_> = cgu_reuse
@@ -702,12 +699,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// Compile the found CGUs in parallel.
let start_time = Instant::now();
- let pre_compiled_cgus = par_iter(cgus)
- .map(|(i, _)| {
- let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
- (i, module)
- })
- .collect();
+ let pre_compiled_cgus = par_map(cgus, |(i, _)| {
+ let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
+ (i, module)
+ });
total_codegen_time += start_time.elapsed();
@@ -914,7 +909,21 @@ impl CrateInfo {
missing_weak_lang_items
.iter()
.map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)),
- )
+ );
+ if tcx.allocator_kind(()).is_some() {
+ // At least one crate needs a global allocator. This crate may be placed
+ // after the crate that defines it in the linker order, in which case some
+ // linkers return an error. By adding the global allocator shim methods to
+ // the linked_symbols list, linking the generated symbols.o will ensure that
+ // circular dependencies involving the global allocator don't lead to linker
+ // errors.
+ linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
+ (
+ format!("{prefix}{}", global_fn_name(method.name).as_str()),
+ SymbolExportKind::Text,
+ )
+ }));
+ }
});
}
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 8542bab68..d6c230127 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -7,13 +7,14 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem};
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self as ty, TyCtxt};
use rustc_session::{lint, parse::feature_err};
use rustc_span::symbol::Ident;
use rustc_span::{sym, Span};
use rustc_target::spec::{abi, SanitizerSet};
+use crate::errors;
use crate::target_features::from_target_feature;
use crate::{errors::ExpectedUsedSymbol, target_features::check_target_feature_trait_unsafe};
@@ -156,7 +157,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
None => {
// Unfortunately, unconditionally using `llvm.used` causes
// issues in handling `.init_array` with the gold linker,
- // but using `llvm.compiler.used` caused a nontrival amount
+ // but using `llvm.compiler.used` caused a nontrivial amount
// of unintentional ecosystem breakage -- particularly on
// Mach-O targets.
//
@@ -300,7 +301,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if let Some(val) = attr.value_str() {
if val.as_str().bytes().any(|b| b == 0) {
let msg = format!("illegal null byte in link_section value: `{}`", &val);
- tcx.sess.span_err(attr.span, &msg);
+ tcx.sess.span_err(attr.span, msg);
} else {
codegen_fn_attrs.link_section = Some(val);
}
@@ -334,10 +335,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS
}
_ => {
- tcx.sess
- .struct_span_err(item.span(), "invalid argument for `no_sanitize`")
- .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`")
- .emit();
+ tcx.sess.emit_err(errors::InvalidNoSanitize { span: item.span() });
}
}
}
@@ -594,24 +592,12 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
- if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" {
- feature_err(
- &tcx.sess.parse_sess,
- sym::raw_dylib,
- attr.span,
- "`#[link_ordinal]` is unstable on x86",
- )
- .emit();
- }
let meta_item_list = attr.meta_item_list();
let meta_item_list = meta_item_list.as_deref();
let sole_meta_list = match meta_item_list {
Some([item]) => item.lit(),
Some(_) => {
- tcx.sess
- .struct_span_err(attr.span, "incorrect number of arguments to `#[link_ordinal]`")
- .note("the attribute requires exactly one argument")
- .emit();
+ tcx.sess.emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
return None;
}
_ => None,
@@ -636,16 +622,13 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
} else {
let msg = format!("ordinal value in `link_ordinal` is too large: `{}`", &ordinal);
tcx.sess
- .struct_span_err(attr.span, &msg)
+ .struct_span_err(attr.span, msg)
.note("the value may not exceed `u16::MAX`")
.emit();
None
}
} else {
- tcx.sess
- .struct_span_err(attr.span, "illegal ordinal format in `link_ordinal`")
- .note("an unsuffixed integer value, e.g., `1`, is expected")
- .emit();
+ tcx.sess.emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span });
None
}
}
diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
index e288760a0..1791ce4b3 100644
--- a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs
@@ -1,6 +1,6 @@
use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
-/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95)
+/// Must match the layout of `LLVMRustCounterKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum CounterKind {
@@ -17,8 +17,10 @@ pub enum CounterKind {
/// `instrprof.increment()`)
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
/// counter expressions.
-/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103)
-/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
+///
+/// Corresponds to struct `llvm::coverage::Counter`.
+///
+/// Must match the layout of `LLVMRustCounter`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct Counter {
@@ -59,7 +61,9 @@ impl Counter {
}
}
-/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150)
+/// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`.
+///
+/// Must match the layout of `LLVMRustCounterExprKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ExprKind {
@@ -67,9 +71,9 @@ pub enum ExprKind {
Add = 1,
}
-/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152)
-/// Important: The Rust struct layout (order and types of fields) must match its C++
-/// counterpart.
+/// Corresponds to struct `llvm::coverage::CounterExpression`.
+///
+/// Must match the layout of `LLVMRustCounterExpression`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct CounterExpression {
diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs
index 1ea130400..e4da3b8de 100644
--- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs
+++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs
@@ -1,6 +1,6 @@
pub use super::ffi::*;
-use rustc_index::vec::{IndexSlice, IndexVec};
+use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::coverage::{
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId,
InjectedExpressionIndex, MappedExpressionIndex, Op,
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index f2469fde3..6297f9134 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -12,7 +12,7 @@
// * `"` is treated as the start of a string.
use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
@@ -94,7 +94,7 @@ fn push_debuginfo_type_name<'tcx>(
// Computing the layout can still fail here, e.g. if the target architecture
// cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
// FIXME: migrate once `rustc_middle::mir::interpret::InterpError` is translatable.
- tcx.sess.fatal(&format!("{}", e));
+ tcx.sess.fatal(format!("{}", e));
}
}
} else {
@@ -675,8 +675,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
hcx.while_hashing_spans(false, |hcx| {
ct.to_valtree().hash_stable(hcx, &mut hasher)
});
- let hash: u64 = hasher.finish();
- hash
+ hasher.finish::<Hash64>()
});
if cpp_like_debuginfo(tcx) {
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 66e7e314f..cf4893b82 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -424,7 +424,7 @@ pub struct UnableToRunDsymutil {
}
#[derive(Diagnostic)]
-#[diag(codegen_ssa_stripping_debu_info_failed)]
+#[diag(codegen_ssa_stripping_debug_info_failed)]
#[note]
pub struct StrippingDebugInfoFailed<'a> {
pub util: &'a str,
@@ -981,3 +981,37 @@ impl IntoDiagnosticArg for ExpectedPointerMutability {
}
}
}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_invalid_no_sanitize)]
+#[note]
+pub struct InvalidNoSanitize {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_invalid_link_ordinal_nargs)]
+#[note]
+pub struct InvalidLinkOrdinalNargs {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_illegal_link_ordinal_format)]
+#[note]
+pub struct InvalidLinkOrdinalFormat {
+ #[primary_span]
+ pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_target_feature_safe_trait)]
+pub struct TargetFeatureSafeTrait {
+ #[primary_span]
+ #[label]
+ pub span: Span,
+ #[label(codegen_ssa_label_def)]
+ pub def: Span,
+}
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 0ab12314b..31854c7f4 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -25,20 +25,22 @@ use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_fluent_macro::fluent_messages;
use rustc_hir::def_id::CrateNum;
-use rustc_macros::fluent_messages;
use rustc_middle::dep_graph::WorkProduct;
+use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
-use rustc_middle::ty::query::{ExternProviders, Providers};
-use rustc_serialize::opaque::{MemDecoder, MemEncoder};
+use rustc_middle::query::{ExternProviders, Providers};
+use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT};
use rustc_session::cstore::{self, CrateSource};
use rustc_session::utils::NativeLibKind;
+use rustc_session::Session;
use rustc_span::symbol::Symbol;
-use rustc_span::DebuggerVisualizerFile;
use std::collections::BTreeSet;
+use std::io;
use std::path::{Path, PathBuf};
pub mod back;
@@ -174,11 +176,11 @@ pub struct CodegenResults {
pub crate_info: CrateInfo,
}
-pub enum CodegenErrors<'a> {
+pub enum CodegenErrors {
WrongFileType,
EmptyVersionNumber,
EncodingVersionMismatch { version_array: String, rlink_version: u32 },
- RustcVersionMismatch { rustc_version: String, current_version: &'a str },
+ RustcVersionMismatch { rustc_version: String },
}
pub fn provide(providers: &mut Providers) {
@@ -212,21 +214,23 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool {
const RLINK_VERSION: u32 = 1;
const RLINK_MAGIC: &[u8] = b"rustlink";
-const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
-
impl CodegenResults {
- pub fn serialize_rlink(codegen_results: &CodegenResults) -> Vec<u8> {
- let mut encoder = MemEncoder::new();
+ pub fn serialize_rlink(
+ sess: &Session,
+ rlink_file: &Path,
+ codegen_results: &CodegenResults,
+ ) -> Result<usize, io::Error> {
+ let mut encoder = FileEncoder::new(rlink_file)?;
encoder.emit_raw_bytes(RLINK_MAGIC);
// `emit_raw_bytes` is used to make sure that the version representation does not depend on
// Encoder's inner representation of `u32`.
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
- encoder.emit_str(RUSTC_VERSION.unwrap());
+ encoder.emit_str(sess.cfg_version);
Encodable::encode(codegen_results, &mut encoder);
encoder.finish()
}
- pub fn deserialize_rlink<'a>(data: Vec<u8>) -> Result<Self, CodegenErrors<'a>> {
+ pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> {
// The Decodable machinery is not used here because it panics if the input data is invalid
// and because its internal representation may change.
if !data.starts_with(RLINK_MAGIC) {
@@ -248,11 +252,9 @@ impl CodegenResults {
let mut decoder = MemDecoder::new(&data[4..], 0);
let rustc_version = decoder.read_str();
- let current_version = RUSTC_VERSION.unwrap();
- if rustc_version != current_version {
+ if rustc_version != sess.cfg_version {
return Err(CodegenErrors::RustcVersionMismatch {
rustc_version: rustc_version.to_string(),
- current_version,
});
}
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 2421acab4..a8b935bd6 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -28,8 +28,9 @@ impl<'a, 'tcx> VirtualIndex {
if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
&& bx.cx().sess().lto() == Lto::Fat
{
- let typeid =
- bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)));
+ let typeid = bx
+ .typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)))
+ .unwrap();
let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes();
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
bx.pointercast(func, llty)
@@ -67,10 +68,10 @@ impl<'a, 'tcx> VirtualIndex {
/// ref of the type.
fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
for arg in ty.peel_refs().walk() {
- if let GenericArgKind::Type(ty) = arg.unpack() {
- if let ty::Dynamic(data, _, _) = ty.kind() {
- return data.principal().expect("expected principal trait object");
- }
+ if let GenericArgKind::Type(ty) = arg.unpack()
+ && let ty::Dynamic(data, _, _) = ty.kind()
+ {
+ return data.principal().expect("expected principal trait object");
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index f43f1d64a..22c1f0597 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -5,7 +5,7 @@ use super::FunctionCx;
use crate::traits::*;
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::{IndexSlice, IndexVec};
+use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::traversal;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{self, Location, TerminatorKind};
@@ -84,7 +84,7 @@ impl DefLocation {
struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
fx: &'mir FunctionCx<'a, 'tcx, Bx>,
- dominators: Dominators<mir::BasicBlock>,
+ dominators: &'mir Dominators<mir::BasicBlock>,
locals: IndexVec<mir::Local, LocalKind>,
}
@@ -203,7 +203,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
self.assign(local, DefLocation::Body(location));
}
- PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
+ PlaceContext::NonUse(_)
+ | PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention)
+ | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {}
PlaceContext::NonMutatingUse(
NonMutatingUseContext::Copy | NonMutatingUseContext::Move,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index dd8697781..3f0b64b11 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -12,7 +12,6 @@ use crate::MemFlags;
use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem;
-use rustc_index::vec::Idx;
use rustc_middle::mir::{self, AssertKind, SwitchTargets};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
@@ -20,7 +19,6 @@ use rustc_middle::ty::{self, Instance, Ty};
use rustc_session::config::OptLevel;
use rustc_span::source_map::Span;
use rustc_span::{sym, Symbol};
-use rustc_symbol_mangling::typeid::typeid_for_fnabi;
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
use rustc_target::spec::abi::Abi;
@@ -164,6 +162,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
// do an invoke, otherwise do a call.
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
+ let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() {
+ Some(bx.tcx().codegen_fn_attrs(fx.instance.def_id()))
+ } else {
+ None
+ };
+
if !fn_abi.can_unwind {
unwind = mir::UnwindAction::Unreachable;
}
@@ -191,6 +195,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
};
let invokeret = bx.invoke(
fn_ty,
+ fn_attrs,
Some(&fn_abi),
fn_ptr,
&llargs,
@@ -212,7 +217,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
}
MergingSucc::False
} else {
- let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
+ let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
if fx.mir[self.bb].is_cleanup {
// Cleanup is always the cold path. Don't inline
// drop glue. Also, when there is a deeply-nested
@@ -369,7 +374,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if self.fn_abi.c_variadic {
// The `VaList` "spoofed" argument is just after all the real arguments.
let va_list_arg_idx = self.fn_abi.args.len();
- match self.locals[mir::Local::new(1 + va_list_arg_idx)] {
+ match self.locals[mir::Local::from_usize(1 + va_list_arg_idx)] {
LocalRef::Place(va_list) => {
bx.va_end(va_list.llval);
}
@@ -1026,7 +1031,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
});
let needs_location =
- instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx()));
+ instance.is_some_and(|i| i.def.requires_caller_location(self.cx.tcx()));
if needs_location {
let mir_args = if let Some(num_untupled) = num_untupled {
first_args.len() + num_untupled
@@ -1052,48 +1057,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_argument(bx, location, &mut llargs, last_arg);
}
- let (is_indirect_call, fn_ptr) = match (llfn, instance) {
- (Some(llfn), _) => (true, llfn),
- (None, Some(instance)) => (false, bx.get_fn_addr(instance)),
- _ => span_bug!(span, "no llfn for call"),
+ let fn_ptr = match (instance, llfn) {
+ (Some(instance), None) => bx.get_fn_addr(instance),
+ (_, Some(llfn)) => llfn,
+ _ => span_bug!(span, "no instance or llfn for call"),
};
- // For backends that support CFI using type membership (i.e., testing whether a given
- // pointer is associated with a type identifier).
- if bx.tcx().sess.is_sanitizer_cfi_enabled() && is_indirect_call {
- // Emit type metadata and checks.
- // FIXME(rcvalle): Add support for generalized identifiers.
- // FIXME(rcvalle): Create distinct unnamed MDNodes for internal identifiers.
- let typeid = typeid_for_fnabi(bx.tcx(), fn_abi);
- let typeid_metadata = self.cx.typeid_metadata(typeid);
-
- // Test whether the function pointer is associated with the type identifier.
- let cond = bx.type_test(fn_ptr, typeid_metadata);
- let bb_pass = bx.append_sibling_block("type_test.pass");
- let bb_fail = bx.append_sibling_block("type_test.fail");
- bx.cond_br(cond, bb_pass, bb_fail);
-
- bx.switch_to_block(bb_pass);
- let merging_succ = helper.do_call(
- self,
- bx,
- fn_abi,
- fn_ptr,
- &llargs,
- target.as_ref().map(|&target| (ret_dest, target)),
- unwind,
- &copied_constant_arguments,
- false,
- );
- assert_eq!(merging_succ, MergingSucc::False);
-
- bx.switch_to_block(bb_fail);
- bx.abort();
- bx.unreachable();
-
- return MergingSucc::False;
- }
-
helper.do_call(
self,
bx,
@@ -1287,7 +1256,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
MergingSucc::False
}
- mir::TerminatorKind::Drop { place, target, unwind } => {
+ mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => {
self.codegen_drop_terminator(helper, bx, place, target, unwind, mergeable_succ())
}
@@ -1481,11 +1450,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> OperandRef<'tcx, Bx::Value> {
let tcx = bx.tcx();
- let mut span_to_caller_location = |mut span: Span| {
- // Remove `Inlined` marks as they pollute `expansion_cause`.
- while span.is_inlined() {
- span.remove_mark();
- }
+ let mut span_to_caller_location = |span: Span| {
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
let const_loc = tcx.const_caller_location((
@@ -1631,7 +1596,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx = Bx::build(self.cx, llbb);
let llpersonality = self.cx.eh_personality();
- bx.cleanup_landing_pad(llpersonality);
+ bx.filter_landing_pad(llpersonality);
funclet = None;
}
@@ -1641,7 +1606,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
- let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
+ let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
bx.do_not_inline(llret);
bx.unreachable();
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index d049bafb8..bba2800fb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,5 +1,5 @@
use crate::traits::*;
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir;
use rustc_middle::ty;
@@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_session::config::DebugInfo;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::{BytePos, Span};
-use rustc_target::abi::{Abi, FieldIdx, Size, VariantIdx};
+use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx};
use super::operand::{OperandRef, OperandValue};
use super::place::PlaceRef;
@@ -41,6 +41,9 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
/// `.place.projection` from `mir::VarDebugInfo`.
pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>,
+
+ /// `references` from `mir::VarDebugInfo`.
+ pub references: u8,
}
#[derive(Clone, Copy, Debug)]
@@ -80,6 +83,7 @@ trait DebugInfoOffsetLocation<'tcx, Bx> {
fn deref(&self, bx: &mut Bx) -> Self;
fn layout(&self) -> TyAndLayout<'tcx>;
fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self;
+ fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self;
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self;
}
@@ -98,6 +102,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
PlaceRef::project_field(*self, bx, field.index())
}
+ fn project_constant_index(&self, bx: &mut Bx, offset: u64) -> Self {
+ let lloffset = bx.cx().const_usize(offset);
+ self.project_index(bx, lloffset)
+ }
+
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
self.project_downcast(bx, variant)
}
@@ -120,6 +129,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx>
self.field(bx.cx(), field.index())
}
+ fn project_constant_index(&self, bx: &mut Bx, index: u64) -> Self {
+ self.field(bx.cx(), index as usize)
+ }
+
fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self {
self.for_variant(bx.cx(), variant)
}
@@ -165,6 +178,18 @@ fn calculate_debuginfo_offset<
mir::ProjectionElem::Downcast(_, variant) => {
place = place.downcast(bx, variant);
}
+ mir::ProjectionElem::ConstantIndex {
+ offset: index,
+ min_length: _,
+ from_end: false,
+ } => {
+ let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
+ let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
+ span_bug!(var.source_info.span, "ConstantIndex on non-array type {:?}", place.layout())
+ };
+ *offset += stride * index;
+ place = place.project_constant_index(bx, index);
+ }
_ => {
// Sanity check for `can_use_in_debuginfo`.
debug_assert!(!elem.can_use_in_debuginfo());
@@ -293,6 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
dbg_var,
fragment: None,
projection: ty::List::empty(),
+ references: 0,
})
}
} else {
@@ -358,55 +384,74 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let vars = vars.iter().cloned().chain(fallback_var);
for var in vars {
- let Some(dbg_var) = var.dbg_var else { continue };
- let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
-
- let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
- calculate_debuginfo_offset(bx, local, &var, base.layout);
-
- // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
- // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
- // not DWARF and LLVM doesn't support translating the resulting
- // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
- // Creating extra allocas on the stack makes the resulting debug info simple enough
- // that LLVM can generate correct CodeView records and thus the values appear in the
- // debugger. (#83709)
- let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
- && self.mir.local_kind(local) == mir::LocalKind::Arg
- // LLVM can handle simple things but anything more complex than just a direct
- // offset or one indirect offset of 0 is too complex for it to generate CV records
- // correctly.
- && (direct_offset != Size::ZERO
- || !matches!(&indirect_offsets[..], [Size::ZERO] | []));
-
- if should_create_individual_allocas {
- let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
- calculate_debuginfo_offset(bx, local, &var, base);
-
- // Create a variable which will be a pointer to the actual value
- let ptr_ty = bx
- .tcx()
- .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
- let ptr_layout = bx.layout_of(ptr_ty);
- let alloca = PlaceRef::alloca(bx, ptr_layout);
- bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill"));
-
- // Write the pointer to the variable
- bx.store(place.llval, alloca.llval, alloca.align);
-
- // Point the debug info to `*alloca` for the current variable
- bx.dbg_var_addr(dbg_var, dbg_loc, alloca.llval, Size::ZERO, &[Size::ZERO], None);
- } else {
- bx.dbg_var_addr(
- dbg_var,
- dbg_loc,
- base.llval,
- direct_offset,
- &indirect_offsets,
- None,
- );
+ self.debug_introduce_local_as_var(bx, local, base, var);
+ }
+ }
+
+ fn debug_introduce_local_as_var(
+ &self,
+ bx: &mut Bx,
+ local: mir::Local,
+ mut base: PlaceRef<'tcx, Bx::Value>,
+ var: PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+ ) {
+ let Some(dbg_var) = var.dbg_var else { return };
+ let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
+
+ let DebugInfoOffset { mut direct_offset, indirect_offsets, result: _ } =
+ calculate_debuginfo_offset(bx, local, &var, base.layout);
+ let mut indirect_offsets = &indirect_offsets[..];
+
+ // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
+ // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
+ // not DWARF and LLVM doesn't support translating the resulting
+ // [DW_OP_deref, DW_OP_plus_uconst, offset, DW_OP_deref] debug info to CodeView.
+ // Creating extra allocas on the stack makes the resulting debug info simple enough
+ // that LLVM can generate correct CodeView records and thus the values appear in the
+ // debugger. (#83709)
+ let should_create_individual_allocas = bx.cx().sess().target.is_like_msvc
+ && self.mir.local_kind(local) == mir::LocalKind::Arg
+ // LLVM can handle simple things but anything more complex than just a direct
+ // offset or one indirect offset of 0 is too complex for it to generate CV records
+ // correctly.
+ && (direct_offset != Size::ZERO || !matches!(indirect_offsets, [Size::ZERO] | []));
+
+ let create_alloca = |bx: &mut Bx, place: PlaceRef<'tcx, Bx::Value>, refcount| {
+ // Create a variable which will be a pointer to the actual value
+ let ptr_ty = bx
+ .tcx()
+ .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty });
+ let ptr_layout = bx.layout_of(ptr_ty);
+ let alloca = PlaceRef::alloca(bx, ptr_layout);
+ bx.set_var_name(alloca.llval, &format!("{}.ref{}.dbg.spill", var.name, refcount));
+
+ // Write the pointer to the variable
+ bx.store(place.llval, alloca.llval, alloca.align);
+
+ // Point the debug info to `*alloca` for the current variable
+ alloca
+ };
+
+ if var.references > 0 {
+ base = calculate_debuginfo_offset(bx, local, &var, base).result;
+
+ // Point the debug info to `&...&base == alloca` for the current variable
+ for refcount in 0..var.references {
+ base = create_alloca(bx, base, refcount);
}
+
+ direct_offset = Size::ZERO;
+ indirect_offsets = &[];
+ } else if should_create_individual_allocas {
+ let place = calculate_debuginfo_offset(bx, local, &var, base).result;
+
+ // Point the debug info to `*alloca` for the current variable
+ base = create_alloca(bx, place, 0);
+ direct_offset = Size::ZERO;
+ indirect_offsets = &[Size::ZERO];
}
+
+ bx.dbg_var_addr(dbg_var, dbg_loc, base.llval, direct_offset, indirect_offsets, None);
}
pub fn debug_introduce_locals(&self, bx: &mut Bx) {
@@ -439,7 +484,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
let dbg_var = dbg_scope_and_span.map(|(dbg_scope, _, span)| {
- let (var_ty, var_kind) = match var.value {
+ let (mut var_ty, var_kind) = match var.value {
mir::VarDebugInfoContents::Place(place) => {
let var_ty = self.monomorphized_place_ty(place.as_ref());
let var_kind = if let Some(arg_index) = var.argument_index
@@ -476,6 +521,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
};
+ for _ in 0..var.references {
+ var_ty =
+ bx.tcx().mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: var_ty });
+ }
+
self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
});
@@ -487,6 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
dbg_var,
fragment: None,
projection: place.projection,
+ references: var.references,
});
}
mir::VarDebugInfoContents::Const(c) => {
@@ -494,6 +545,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) {
+ self.set_debug_loc(bx, var.source_info);
let base = Self::spill_operand_to_stack(
&operand,
Some(var.name.to_string()),
@@ -539,6 +591,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Some(fragment_start..fragment_start + fragment_layout.size)
},
projection: place.projection,
+ references: var.references,
});
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 7af7fc92d..1479242f2 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -135,13 +135,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
.unwrap();
OperandRef::from_const(bx, value, ret_ty).immediate_or_packed_pair(bx)
}
- sym::offset => {
- let ty = substs.type_at(0);
- let layout = bx.layout_of(ty);
- let ptr = args[0].immediate();
- let offset = args[1].immediate();
- bx.inbounds_gep(bx.backend_type(layout), ptr, &[offset])
- }
sym::arith_offset => {
let ty = substs.type_at(0);
let layout = bx.layout_of(ty);
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 3dadb33c9..1204c99e5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -9,7 +9,7 @@ use rustc_target::abi::call::{FnAbi, PassMode};
use std::iter;
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo};
use self::place::PlaceRef;
@@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
- value,
+ ty::EarlyBinder(value),
)
}
}
@@ -152,7 +152,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
instance: Instance<'tcx>,
) {
- assert!(!instance.substs.needs_infer());
+ assert!(!instance.substs.has_infer());
let llfn = cx.get_fn(instance);
@@ -304,7 +304,17 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bug!("spread argument isn't a tuple?!");
};
- let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
+ let layout = bx.layout_of(arg_ty);
+
+ // FIXME: support unsized params in "rust-call" ABI
+ if layout.is_unsized() {
+ span_bug!(
+ arg_decl.source_info.span,
+ "\"rust-call\" ABI does not support unsized params",
+ );
+ }
+
+ let place = PlaceRef::alloca(bx, layout);
for i in 0..tupled_arg_tys.len() {
let arg = &fx.fn_abi.args[idx];
idx += 1;
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index b37797fef..2301c3ef1 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -2,6 +2,7 @@ use super::place::PlaceRef;
use super::{FunctionCx, LocalRef};
use crate::base;
+use crate::common::TypeKind;
use crate::glue;
use crate::traits::*;
use crate::MemFlags;
@@ -236,19 +237,47 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
};
match (&mut val, field.abi) {
- (OperandValue::Immediate(llval), _) => {
+ (
+ OperandValue::Immediate(llval),
+ Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. },
+ ) => {
// Bools in union fields needs to be truncated.
*llval = bx.to_immediate(*llval, field);
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
- *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field));
+ let ty = bx.cx().immediate_backend_type(field);
+ if bx.type_kind(ty) == TypeKind::Pointer {
+ *llval = bx.pointercast(*llval, ty);
+ }
}
(OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => {
// Bools in union fields needs to be truncated.
*a = bx.to_immediate_scalar(*a, a_abi);
*b = bx.to_immediate_scalar(*b, b_abi);
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
- *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
- *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
+ let a_ty = bx.cx().scalar_pair_element_backend_type(field, 0, true);
+ let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true);
+ if bx.type_kind(a_ty) == TypeKind::Pointer {
+ *a = bx.pointercast(*a, a_ty);
+ }
+ if bx.type_kind(b_ty) == TypeKind::Pointer {
+ *b = bx.pointercast(*b, b_ty);
+ }
+ }
+ // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
+ (OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => {
+ assert!(matches!(self.layout.abi, Abi::Vector { .. }));
+
+ let llty = bx.cx().backend_type(self.layout);
+ let llfield_ty = bx.cx().backend_type(field);
+
+ // Can't bitcast an aggregate, so round trip through memory.
+ let lltemp = bx.alloca(llfield_ty, field.align.abi);
+ let llptr = bx.pointercast(lltemp, bx.cx().type_ptr_to(llty));
+ bx.store(*llval, llptr, field.align.abi);
+ *llval = bx.load(llfield_ty, lltemp, field.align.abi);
+ }
+ (OperandValue::Immediate(_), Abi::Uninhabited | Abi::Aggregate { sized: false }) => {
+ bug!()
}
(OperandValue::Pair(..), _) => bug!(),
(OperandValue::Ref(..), _) => bug!(),
@@ -373,8 +402,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
indirect_dest: PlaceRef<'tcx, V>,
) {
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
- let flags = MemFlags::empty();
-
// `indirect_dest` must have `*mut T` type. We extract `T` out of it.
let unsized_ty = indirect_dest
.layout
@@ -387,17 +414,23 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
bug!("store_unsized called with a sized value")
};
- // FIXME: choose an appropriate alignment, or use dynamic align somehow
- let max_align = Align::from_bits(128).unwrap();
- let min_align = Align::from_bits(8).unwrap();
-
- // Allocate an appropriate region on the stack, and copy the value into it
- let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
- let lldst = bx.byte_array_alloca(llsize, max_align);
- bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
+ // Allocate an appropriate region on the stack, and copy the value into it. Since alloca
+ // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
+ // pointer manually.
+ let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
+ let one = bx.const_usize(1);
+ let align_minus_1 = bx.sub(align, one);
+ let size_extra = bx.add(size, align_minus_1);
+ let min_align = Align::ONE;
+ let alloca = bx.byte_array_alloca(size_extra, min_align);
+ let address = bx.ptrtoint(alloca, bx.type_isize());
+ let neg_address = bx.neg(address);
+ let offset = bx.and(neg_address, align_minus_1);
+ let dst = bx.inbounds_gep(bx.type_i8(), alloca, &[offset]);
+ bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty());
// Store the allocated region and the extra to the indirect place.
- let indirect_operand = OperandValue::Pair(lldst, llextra);
+ let indirect_operand = OperandValue::Pair(dst, llextra);
indirect_operand.store(bx, indirect_dest);
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d88226f5d..6e7065713 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -12,6 +12,7 @@ use rustc_middle::mir::Operand;
use rustc_middle::ty::cast::{CastTy, IntTy};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
+use rustc_session::config::OptLevel;
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_target::abi::{self, FIRST_VARIANT};
@@ -231,10 +232,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
(ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar))
if in_scalar.size(self.cx) == out_scalar.size(self.cx) =>
{
+ let operand_bty = bx.backend_type(operand.layout);
let cast_bty = bx.backend_type(cast);
- Some(OperandValue::Immediate(
- self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty),
- ))
+ Some(OperandValue::Immediate(self.transmute_immediate(
+ bx,
+ imm,
+ in_scalar,
+ operand_bty,
+ out_scalar,
+ cast_bty,
+ )))
}
_ => None,
}
@@ -250,11 +257,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&& in_a.size(self.cx) == out_a.size(self.cx)
&& in_b.size(self.cx) == out_b.size(self.cx)
{
+ let in_a_ibty = bx.scalar_pair_element_backend_type(operand.layout, 0, false);
+ let in_b_ibty = bx.scalar_pair_element_backend_type(operand.layout, 1, false);
let out_a_ibty = bx.scalar_pair_element_backend_type(cast, 0, false);
let out_b_ibty = bx.scalar_pair_element_backend_type(cast, 1, false);
Some(OperandValue::Pair(
- self.transmute_immediate(bx, imm_a, in_a, out_a, out_a_ibty),
- self.transmute_immediate(bx, imm_b, in_b, out_b, out_b_ibty),
+ self.transmute_immediate(bx, imm_a, in_a, in_a_ibty, out_a, out_a_ibty),
+ self.transmute_immediate(bx, imm_b, in_b, in_b_ibty, out_b, out_b_ibty),
))
} else {
None
@@ -273,6 +282,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx: &mut Bx,
mut imm: Bx::Value,
from_scalar: abi::Scalar,
+ from_backend_ty: Bx::Type,
to_scalar: abi::Scalar,
to_backend_ty: Bx::Type,
) -> Bx::Value {
@@ -280,6 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
use abi::Primitive::*;
imm = bx.from_immediate(imm);
+
+ // When scalars are passed by value, there's no metadata recording their
+ // valid ranges. For example, `char`s are passed as just `i32`, with no
+ // way for LLVM to know that they're 0x10FFFF at most. Thus we assume
+ // the range of the input value too, not just the output range.
+ self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
(Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
@@ -294,10 +311,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.bitcast(int_imm, to_backend_ty)
}
};
+ self.assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
imm = bx.to_immediate_scalar(imm, to_scalar);
imm
}
+ fn assume_scalar_range(
+ &self,
+ bx: &mut Bx,
+ imm: Bx::Value,
+ scalar: abi::Scalar,
+ backend_ty: Bx::Type,
+ ) {
+ if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less)
+ // For now, the critical niches are all over `Int`eger values.
+ // Should floating-point values or pointers ever get more complex
+ // niches, then this code will probably want to handle them too.
+ || !matches!(scalar.primitive(), abi::Primitive::Int(..))
+ || scalar.is_always_valid(self.cx)
+ {
+ return;
+ }
+
+ let abi::WrappingRange { start, end } = scalar.valid_range(self.cx);
+
+ if start <= end {
+ if start > 0 {
+ let low = bx.const_uint_big(backend_ty, start);
+ let cmp = bx.icmp(IntPredicate::IntUGE, imm, low);
+ bx.assume(cmp);
+ }
+
+ let type_max = scalar.size(self.cx).unsigned_int_max();
+ if end < type_max {
+ let high = bx.const_uint_big(backend_ty, end);
+ let cmp = bx.icmp(IntPredicate::IntULE, imm, high);
+ bx.assume(cmp);
+ }
+ } else {
+ let low = bx.const_uint_big(backend_ty, start);
+ let cmp_low = bx.icmp(IntPredicate::IntUGE, imm, low);
+
+ let high = bx.const_uint_big(backend_ty, end);
+ let cmp_high = bx.icmp(IntPredicate::IntULE, imm, high);
+
+ let or = bx.or(cmp_low, cmp_high);
+ bx.assume(or);
+ }
+ }
+
pub fn codegen_rvalue_unsized(
&mut self,
bx: &mut Bx,
@@ -604,13 +666,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
- mir::Rvalue::NullaryOp(null_op, ty) => {
+ mir::Rvalue::NullaryOp(ref null_op, ty) => {
let ty = self.monomorphize(ty);
assert!(bx.cx().type_is_sized(ty));
let layout = bx.cx().layout_of(ty);
let val = match null_op {
mir::NullOp::SizeOf => layout.size.bytes(),
mir::NullOp::AlignOf => layout.align.abi.bytes(),
+ mir::NullOp::OffsetOf(fields) => {
+ layout.offset_of_subfield(bx.cx(), fields.iter().map(|f| f.index())).bytes()
+ }
};
let val = bx.cx().const_usize(val);
let tcx = self.cx.tcx();
@@ -632,7 +697,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let fn_ptr = bx.get_fn_addr(instance);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
- bx.call(fn_ty, Some(fn_abi), fn_ptr, &[], None)
+ let fn_attrs = if bx.tcx().def_kind(instance.def_id()).has_codegen_attrs() {
+ Some(bx.tcx().codegen_fn_attrs(instance.def_id()))
+ } else {
+ None
+ };
+ bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None)
} else {
bx.get_static(def_id)
};
@@ -754,8 +824,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
.builtin_deref(true)
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", input_ty))
.ty;
- let llty = bx.cx().backend_type(bx.cx().layout_of(pointee_type));
- bx.inbounds_gep(llty, lhs, &[rhs])
+ let pointee_layout = bx.cx().layout_of(pointee_type);
+ if pointee_layout.is_zst() {
+ // `Offset` works in terms of the size of pointee,
+ // so offsetting a pointer to ZST is a noop.
+ lhs
+ } else {
+ let llty = bx.cx().backend_type(pointee_layout);
+ bx.inbounds_gep(llty, lhs, &[rhs])
+ }
}
mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs),
mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs),
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 611dd3d1c..c5976a654 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -1,3 +1,4 @@
+use crate::errors;
use rustc_ast::ast;
use rustc_attr::InstructionSetAttr;
use rustc_data_structures::fx::FxHashMap;
@@ -7,7 +8,7 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_middle::ty::query::Providers;
+use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::parse::feature_err;
use rustc_session::Session;
@@ -172,16 +173,13 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("avx512dq", Some(sym::avx512_target_feature)),
("avx512er", Some(sym::avx512_target_feature)),
("avx512f", Some(sym::avx512_target_feature)),
- ("avx512gfni", Some(sym::avx512_target_feature)),
("avx512ifma", Some(sym::avx512_target_feature)),
("avx512pf", Some(sym::avx512_target_feature)),
- ("avx512vaes", Some(sym::avx512_target_feature)),
("avx512vbmi", Some(sym::avx512_target_feature)),
("avx512vbmi2", Some(sym::avx512_target_feature)),
("avx512vl", Some(sym::avx512_target_feature)),
("avx512vnni", Some(sym::avx512_target_feature)),
("avx512vp2intersect", Some(sym::avx512_target_feature)),
- ("avx512vpclmulqdq", Some(sym::avx512_target_feature)),
("avx512vpopcntdq", Some(sym::avx512_target_feature)),
("bmi1", None),
("bmi2", None),
@@ -252,6 +250,7 @@ const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("f", Some(sym::riscv_target_feature)),
("m", Some(sym::riscv_target_feature)),
("relax", Some(sym::riscv_target_feature)),
+ ("unaligned-scalar-mem", Some(sym::riscv_target_feature)),
("v", Some(sym::riscv_target_feature)),
("zba", Some(sym::riscv_target_feature)),
("zbb", Some(sym::riscv_target_feature)),
@@ -369,7 +368,7 @@ pub fn from_target_feature(
let Some(feature_gate) = supported_target_features.get(feature) else {
let msg =
format!("the feature named `{}` is not valid for this target", feature);
- let mut err = tcx.sess.struct_span_err(item.span(), &msg);
+ let mut err = tcx.sess.struct_span_err(item.span(), msg);
err.span_label(
item.span(),
format!("`{}` is not valid for this target", feature),
@@ -407,7 +406,7 @@ pub fn from_target_feature(
&tcx.sess.parse_sess,
feature_gate.unwrap(),
item.span(),
- &format!("the target feature `{}` is currently unstable", feature),
+ format!("the target feature `{}` is currently unstable", feature),
)
.emit();
}
@@ -443,14 +442,10 @@ pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_s
if let DefKind::AssocFn = tcx.def_kind(id) {
let parent_id = tcx.local_parent(id);
if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
- tcx.sess
- .struct_span_err(
- attr_span,
- "`#[target_feature(..)]` cannot be applied to safe trait method",
- )
- .span_label(attr_span, "cannot be applied to safe trait method")
- .span_label(tcx.def_span(id), "not an `unsafe` function")
- .emit();
+ tcx.sess.emit_err(errors::TargetFeatureSafeTrait {
+ span: attr_span,
+ def: tcx.def_span(id),
+ });
}
}
}
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 64bebe50d..d83bfc740 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -1,3 +1,5 @@
+use std::any::Any;
+
use super::write::WriteBackendMethods;
use super::CodegenObject;
use crate::back::write::TargetMachineFactoryFn;
@@ -5,11 +7,12 @@ use crate::{CodegenResults, ModuleCodegen};
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::ErrorGuaranteed;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::{
config::{self, OutputFilenames, PrintRequest},
@@ -20,10 +23,6 @@ use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use rustc_target::spec::Target;
-pub use rustc_data_structures::sync::MetadataRef;
-
-use std::any::Any;
-
pub trait BackendTypes {
type Value: CodegenObject;
type Function: CodegenObject;
@@ -117,7 +116,9 @@ pub trait CodegenBackend {
) -> Result<(), ErrorGuaranteed>;
}
-pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
+pub trait ExtraBackendMethods:
+ CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
+{
fn codegen_allocator<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 194768d94..853c6934c 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -14,6 +14,7 @@ use crate::mir::operand::OperandRef;
use crate::mir::place::PlaceRef;
use crate::MemFlags;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
use rustc_middle::ty::Ty;
use rustc_span::Span;
@@ -72,6 +73,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn invoke(
&mut self,
llty: Self::Type,
+ fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
llfn: Self::Value,
args: &[Self::Value],
@@ -272,6 +274,7 @@ pub trait BuilderMethods<'a, 'tcx>:
// These are used by everyone except msvc
fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
+ fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
// These are used only by msvc
@@ -321,6 +324,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn call(
&mut self,
llty: Self::Type,
+ fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
llfn: Self::Value,
args: &[Self::Value],
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 32905b079..36d986422 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -128,12 +128,16 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
) -> Self::Type;
}
-// For backends that support CFI using type membership (i.e., testing whether a given pointer is
+// For backends that support CFI using type membership (i.e., testing whether a given pointer is
// associated with a type identifier).
pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> {
- fn set_type_metadata(&self, function: Self::Function, typeid: String);
- fn typeid_metadata(&self, typeid: String) -> Self::Value;
- fn set_kcfi_type_metadata(&self, function: Self::Function, typeid: u32);
+ fn add_type_metadata(&self, _function: Self::Function, _typeid: String) {}
+ fn set_type_metadata(&self, _function: Self::Function, _typeid: String) {}
+ fn typeid_metadata(&self, _typeid: String) -> Option<Self::Value> {
+ None
+ }
+ fn add_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
+ fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
}
pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> {