Skip to content

Commit

Permalink
Auto merge of rust-lang#105525 - matthiaskrgr:rollup-ricyw5s, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang#98391 (Reimplement std's thread parker on top of events on SGX)
 - rust-lang#104019 (Compute generator sizes with `-Zprint_type_sizes`)
 - rust-lang#104512 (Set `download-ci-llvm = "if-available"` by default when `channel = dev`)
 - rust-lang#104901 (Implement masking in FileType comparison on Unix)
 - rust-lang#105082 (Fix Async Generator ABI)
 - rust-lang#105109 (Add LLVM KCFI support to the Rust compiler)
 - rust-lang#105505 (Don't warn about unused parens when they are used by yeet expr)
 - rust-lang#105514 (Introduce `Span::is_visible`)
 - rust-lang#105516 (Update cargo)
 - rust-lang#105522 (Remove wrong note for short circuiting operators)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 10, 2022
2 parents cbc70ff + f6c2add commit b12b836
Show file tree
Hide file tree
Showing 58 changed files with 913 additions and 284 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4404,6 +4404,7 @@ dependencies = [
"rustc_span",
"rustc_target",
"tracing",
"twox-hash",
]

[[package]]
Expand Down Expand Up @@ -5394,6 +5395,17 @@ dependencies = [
"tracing-subscriber",
]

[[package]]
name = "twox-hash"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 1.0.0",
"rand 0.8.5",
"static_assertions",
]

[[package]]
name = "type-map"
version = "0.4.0"
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_gcc/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,8 @@ impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
// Unsupported.
self.context.new_rvalue_from_int(self.int_type, 0)
}

fn set_kcfi_type_metadata(&self, _function: RValue<'gcc>, _kcfi_typeid: u32) {
// Unsupported.
}
}
14 changes: 11 additions & 3 deletions compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ pub(crate) unsafe fn codegen(
callee,
args.as_ptr(),
args.len() as c_uint,
None,
[].as_ptr(),
0 as c_uint,
);
llvm::LLVMSetTailCall(ret, True);
if output.is_some() {
Expand Down Expand Up @@ -132,8 +133,15 @@ pub(crate) unsafe fn codegen(
.enumerate()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>();
let ret =
llvm::LLVMRustBuildCall(llbuilder, ty, callee, args.as_ptr(), args.len() as c_uint, None);
let ret = llvm::LLVMRustBuildCall(
llbuilder,
ty,
callee,
args.as_ptr(),
args.len() as c_uint,
[].as_ptr(),
0 as c_uint,
);
llvm::LLVMSetTailCall(ret, True);
llvm::LLVMBuildRetVoid(llbuilder);
llvm::LLVMDisposeBuilder(llbuilder);
Expand Down
50 changes: 43 additions & 7 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc_middle::ty::layout::{
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
use rustc_symbol_mangling::typeid::kcfi_typeid_for_fnabi;
use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
use rustc_target::spec::{HasTargetSpec, Target};
use std::borrow::Cow;
Expand Down Expand Up @@ -225,9 +226,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
debug!("invoke {:?} with args ({:?})", llfn, args);

let args = self.check_call("invoke", llty, llfn, args);
let bundle = funclet.map(|funclet| funclet.bundle());
let bundle = bundle.as_ref().map(|b| &*b.raw);
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
let mut bundles = vec![funclet_bundle];

// Set KCFI operand bundle
let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
let kcfi_bundle =
if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call {
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap());
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
} else {
None
};
if kcfi_bundle.is_some() {
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
bundles.push(kcfi_bundle);
}

bundles.retain(|bundle| bundle.is_some());
let invoke = unsafe {
llvm::LLVMRustBuildInvoke(
self.llbuilder,
Expand All @@ -237,7 +254,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
args.len() as c_uint,
then,
catch,
bundle,
bundles.as_ptr(),
bundles.len() as c_uint,
UNNAMED,
)
};
Expand Down Expand Up @@ -1143,7 +1161,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
None,
[].as_ptr(),
0 as c_uint,
);
}
}
Expand All @@ -1159,17 +1178,34 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
debug!("call {:?} with args ({:?})", llfn, args);

let args = self.check_call("call", llty, llfn, args);
let bundle = funclet.map(|funclet| funclet.bundle());
let bundle = bundle.as_ref().map(|b| &*b.raw);
let funclet_bundle = funclet.map(|funclet| funclet.bundle());
let funclet_bundle = funclet_bundle.as_ref().map(|b| &*b.raw);
let mut bundles = vec![funclet_bundle];

// Set KCFI operand bundle
let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
let kcfi_bundle =
if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call {
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap());
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
} else {
None
};
if kcfi_bundle.is_some() {
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
bundles.push(kcfi_bundle);
}

bundles.retain(|bundle| bundle.is_some());
let call = unsafe {
llvm::LLVMRustBuildCall(
self.llbuilder,
llty,
llfn,
args.as_ptr() as *const &llvm::Value,
args.len() as c_uint,
bundle,
bundles.as_ptr(),
bundles.len() as c_uint,
)
};
if let Some(fn_abi) = fn_abi {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ pub unsafe fn create_module<'ll>(
);
}

if sess.is_sanitizer_kcfi_enabled() {
let kcfi = "kcfi\0".as_ptr().cast();
llvm::LLVMRustAddModuleFlag(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
}

// Control Flow Guard is currently only supported by the MSVC linker on Windows.
if sess.target.is_like_msvc {
match sess.opts.cg.control_flow_guard {
Expand Down
68 changes: 1 addition & 67 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_fs_util::path_to_c_string;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::bug;
use rustc_middle::mir::{self, GeneratorLayout};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{
Expand Down Expand Up @@ -1026,33 +1024,6 @@ fn build_struct_type_di_node<'ll, 'tcx>(
// Tuples
//=-----------------------------------------------------------------------------

/// Returns names of captured upvars for closures and generators.
///
/// Here are some examples:
/// - `name__field1__field2` when the upvar is captured by value.
/// - `_ref__name__field` when the upvar is captured by reference.
///
/// For generators this only contains upvars that are shared by all states.
fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) -> SmallVec<String> {
let body = tcx.optimized_mir(def_id);

body.var_debug_info
.iter()
.filter_map(|var| {
let is_ref = match var.value {
mir::VarDebugInfoContents::Place(place) if place.local == mir::Local::new(1) => {
// The projection is either `[.., Field, Deref]` or `[.., Field]`. It
// implies whether the variable is captured by value or by reference.
matches!(place.projection.last().unwrap(), mir::ProjectionElem::Deref)
}
_ => return None,
};
let prefix = if is_ref { "_ref__" } else { "" };
Some(prefix.to_owned() + var.name.as_str())
})
.collect()
}

/// Builds the DW_TAG_member debuginfo nodes for the upvars of a closure or generator.
/// For a generator, this will handle upvars shared by all states.
fn build_upvar_field_di_nodes<'ll, 'tcx>(
Expand Down Expand Up @@ -1083,7 +1054,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
.all(|&t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
);

let capture_names = closure_saved_names_of_captured_variables(cx.tcx, def_id);
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_generator_ty);

up_var_tys
Expand Down Expand Up @@ -1229,43 +1200,6 @@ fn build_union_type_di_node<'ll, 'tcx>(
)
}

// FIXME(eddyb) maybe precompute this? Right now it's computed once
// per generator monomorphization, but it doesn't depend on substs.
fn generator_layout_and_saved_local_names<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
let body = tcx.optimized_mir(def_id);
let generator_layout = body.generator_layout().unwrap();
let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);

let state_arg = mir::Local::new(1);
for var in &body.var_debug_info {
let mir::VarDebugInfoContents::Place(place) = &var.value else { continue };
if place.local != state_arg {
continue;
}
match place.projection[..] {
[
// Deref of the `Pin<&mut Self>` state argument.
mir::ProjectionElem::Field(..),
mir::ProjectionElem::Deref,
// Field of a variant of the state.
mir::ProjectionElem::Downcast(_, variant),
mir::ProjectionElem::Field(field, _),
] => {
let name = &mut generator_saved_local_names
[generator_layout.variant_fields[variant][field]];
if name.is_none() {
name.replace(var.name);
}
}
_ => {}
}
}
(generator_layout, generator_saved_local_names)
}

/// Computes the type parameters for a type, if any, for the given metadata.
fn build_generic_type_param_di_nodes<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ use crate::{
common::CodegenCx,
debuginfo::{
metadata::{
build_field_di_node, closure_saved_names_of_captured_variables,
build_field_di_node,
enums::{tag_base_type, DiscrResult},
file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node,
file_metadata, size_and_align_of, type_di_node,
type_map::{self, Stub, UniqueTypeId},
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
UNKNOWN_LINE_NUMBER,
Expand Down Expand Up @@ -677,9 +677,9 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
};

let (generator_layout, state_specific_upvar_names) =
generator_layout_and_saved_local_names(cx.tcx, generator_def_id);
cx.tcx.generator_layout_and_saved_local_names(generator_def_id);

let common_upvar_names = closure_saved_names_of_captured_variables(cx.tcx, generator_def_id);
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);
let variant_range = generator_substs.variant_range(generator_def_id, cx.tcx);
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use crate::{
common::CodegenCx,
debuginfo::{
metadata::{
closure_saved_names_of_captured_variables,
enums::tag_base_type,
file_metadata, generator_layout_and_saved_local_names, size_and_align_of, type_di_node,
file_metadata, size_and_align_of, type_di_node,
type_map::{self, Stub, StubInfo, UniqueTypeId},
unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS,
UNKNOWN_LINE_NUMBER,
Expand Down Expand Up @@ -157,7 +156,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
),
|cx, generator_type_di_node| {
let (generator_layout, state_specific_upvar_names) =
generator_layout_and_saved_local_names(cx.tcx, generator_def_id);
cx.tcx.generator_layout_and_saved_local_names(generator_def_id);

let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = generator_type_and_layout.variants else {
bug!(
Expand All @@ -167,7 +166,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
};

let common_upvar_names =
closure_saved_names_of_captured_variables(cx.tcx, generator_def_id);
cx.tcx.closure_saved_names_of_captured_variables(generator_def_id);

// Build variant struct types
let variant_struct_type_di_nodes: SmallVec<_> = variants
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::type_::Type;
use crate::value::Value;
use rustc_codegen_ssa::traits::TypeMembershipMethods;
use rustc_middle::ty::Ty;
use rustc_symbol_mangling::typeid::typeid_for_fnabi;
use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi};
use smallvec::SmallVec;

/// Declare a function.
Expand Down Expand Up @@ -136,6 +136,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
self.set_type_metadata(llfn, typeid);
}

if self.tcx.sess.is_sanitizer_kcfi_enabled() {
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi);
self.set_kcfi_type_metadata(llfn, kcfi_typeid);
}

llfn
}

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ pub enum MetadataType {
MD_type = 19,
MD_vcall_visibility = 28,
MD_noundef = 29,
MD_kcfi_type = 36,
}

/// LLVMRustAsmDialect
Expand Down Expand Up @@ -1063,6 +1064,7 @@ extern "C" {
pub fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>;

// Operations on constants of any type
pub fn LLVMConstNull(Ty: &Type) -> &Value;
Expand Down Expand Up @@ -1273,7 +1275,8 @@ extern "C" {
NumArgs: c_uint,
Then: &'a BasicBlock,
Catch: &'a BasicBlock,
Bundle: Option<&OperandBundleDef<'a>>,
OpBundles: *const Option<&OperandBundleDef<'a>>,
NumOpBundles: c_uint,
Name: *const c_char,
) -> &'a Value;
pub fn LLVMBuildLandingPad<'a>(
Expand Down Expand Up @@ -1643,7 +1646,8 @@ extern "C" {
Fn: &'a Value,
Args: *const &'a Value,
NumArgs: c_uint,
Bundle: Option<&OperandBundleDef<'a>>,
OpBundles: *const Option<&OperandBundleDef<'a>>,
NumOpBundles: c_uint,
) -> &'a Value;
pub fn LLVMRustBuildMemCpy<'a>(
B: &Builder<'a>,
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_codegen_llvm/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,19 @@ impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> {
)
}
}

fn set_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) {
let kcfi_type_metadata = self.const_u32(kcfi_typeid);
unsafe {
llvm::LLVMGlobalSetMetadata(
function,
llvm::MD_kcfi_type as c_uint,
llvm::LLVMMDNodeInContext2(
self.llcx,
&llvm::LLVMValueAsMetadata(kcfi_type_metadata),
1,
),
)
}
}
}
Loading

0 comments on commit b12b836

Please sign in to comment.