Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use rustc_ast::expand::allocator::{
};
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{DebugInfo, OomStrategy};
use rustc_span::sym;
use rustc_symbol_mangling::mangle_internal_symbol;

use crate::attributes::llfn_attrs_from_instance;
Expand Down Expand Up @@ -59,7 +60,26 @@ pub(crate) unsafe fn codegen(
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));

create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false);
let alloc_attr_flag = match method.name {
sym::alloc => CodegenFnAttrFlags::ALLOCATOR,
sym::dealloc => CodegenFnAttrFlags::DEALLOCATOR,
sym::realloc => CodegenFnAttrFlags::REALLOCATOR,
sym::alloc_zeroed => CodegenFnAttrFlags::ALLOCATOR_ZEROED,
_ => unreachable!("Unknown allocator method!"),
};

let mut attrs = CodegenFnAttrs::new();
attrs.flags |= alloc_attr_flag;
create_wrapper_function(
tcx,
&cx,
&from_name,
Some(&to_name),
&args,
output,
false,
&attrs,
);
}
}

Expand All @@ -72,6 +92,7 @@ pub(crate) unsafe fn codegen(
&[usize, usize], // size, align
None,
true,
&CodegenFnAttrs::new(),
);

unsafe {
Expand All @@ -93,6 +114,7 @@ pub(crate) unsafe fn codegen(
&[],
None,
false,
&CodegenFnAttrs::new(),
);
}

Expand Down Expand Up @@ -139,6 +161,7 @@ fn create_wrapper_function(
args: &[&Type],
output: Option<&Type>,
no_return: bool,
attrs: &CodegenFnAttrs,
) {
let ty = cx.type_func(args, output.unwrap_or_else(|| cx.type_void()));
let llfn = declare_simple_fn(
Expand All @@ -150,8 +173,7 @@ fn create_wrapper_function(
ty,
);

let attrs = CodegenFnAttrs::new();
llfn_attrs_from_instance(cx, tcx, llfn, &attrs, None);
llfn_attrs_from_instance(cx, tcx, llfn, attrs, None);

let no_return = if no_return {
// -> ! DIFlagNoReturn
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_expand/src/mbe/macro_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,7 @@ pub(super) fn check_meta_variables(
guar.map_or(Ok(()), Err)
}

/// Checks `lhs` as part of the LHS of a macro definition, extends `binders` with new binders, and
/// sets `valid` to false in case of errors.
/// Checks `lhs` as part of the LHS of a macro definition.
///
/// Arguments:
/// - `psess` is used to emit diagnostics and lints
Expand Down Expand Up @@ -306,8 +305,7 @@ fn get_binder_info<'a>(
binders.get(&name).or_else(|| macros.find_map(|state| state.binders.get(&name)))
}

/// Checks `rhs` as part of the RHS of a macro definition and sets `valid` to false in case of
/// errors.
/// Checks `rhs` as part of the RHS of a macro definition.
///
/// Arguments:
/// - `psess` is used to emit diagnostics and lints
Expand Down Expand Up @@ -372,7 +370,7 @@ enum NestedMacroState {
}

/// Checks `tts` as part of the RHS of a macro definition, tries to recognize nested macro
/// definitions, and sets `valid` to false in case of errors.
/// definitions.
///
/// Arguments:
/// - `psess` is used to emit diagnostics and lints
Expand Down Expand Up @@ -491,8 +489,7 @@ fn check_nested_occurrences(
}
}

/// Checks the body of nested macro, returns where the check stopped, and sets `valid` to false in
/// case of errors.
/// Checks the body of nested macro, returns where the check stopped.
///
/// The token trees are checked as long as they look like a list of (LHS) => {RHS} token trees. This
/// check is a best-effort to detect a macro definition. It returns the position in `tts` where we
Expand Down
30 changes: 25 additions & 5 deletions compiler/rustc_mir_transform/src/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use tracing::debug;
/// once with `apply`. This is useful for MIR transformation passes.
pub(crate) struct MirPatch<'tcx> {
term_patch_map: FxHashMap<BasicBlock, TerminatorKind<'tcx>>,
/// Set of statements that should be replaced by `Nop`.
nop_statements: Vec<Location>,
new_blocks: Vec<BasicBlockData<'tcx>>,
new_statements: Vec<(Location, StatementKind<'tcx>)>,
new_locals: Vec<LocalDecl<'tcx>>,
Expand All @@ -33,6 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
pub(crate) fn new(body: &Body<'tcx>) -> Self {
let mut result = MirPatch {
term_patch_map: Default::default(),
nop_statements: vec![],
new_blocks: vec![],
new_statements: vec![],
new_locals: vec![],
Expand Down Expand Up @@ -212,6 +215,15 @@ impl<'tcx> MirPatch<'tcx> {
self.term_patch_map.insert(block, new);
}

/// Mark given statement to be replaced by a `Nop`.
///
/// This method only works on statements from the initial body, and cannot be used to remove
/// statements from `add_statement` or `add_assign`.
#[tracing::instrument(level = "debug", skip(self))]
pub(crate) fn nop_statement(&mut self, loc: Location) {
self.nop_statements.push(loc);
}

/// Queues the insertion of a statement at a given location. The statement
/// currently at that location, and all statements that follow, are shifted
/// down. If multiple statements are queued for addition at the same
Expand Down Expand Up @@ -257,11 +269,8 @@ impl<'tcx> MirPatch<'tcx> {
bbs.extend(self.new_blocks);
body.local_decls.extend(self.new_locals);

// The order in which we patch terminators does not change the result.
#[allow(rustc::potential_query_instability)]
for (src, patch) in self.term_patch_map {
debug!("MirPatch: patching block {:?}", src);
bbs[src].terminator_mut().kind = patch;
for loc in self.nop_statements {
bbs[loc.block].statements[loc.statement_index].make_nop();
}

let mut new_statements = self.new_statements;
Expand All @@ -285,6 +294,17 @@ impl<'tcx> MirPatch<'tcx> {
.insert(loc.statement_index, Statement::new(source_info, stmt));
delta += 1;
}

// The order in which we patch terminators does not change the result.
#[allow(rustc::potential_query_instability)]
for (src, patch) in self.term_patch_map {
debug!("MirPatch: patching block {:?}", src);
let bb = &mut bbs[src];
if let TerminatorKind::Unreachable = patch {
bb.statements.clear();
}
bb.terminator_mut().kind = patch;
}
}

fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo {
Expand Down
19 changes: 12 additions & 7 deletions compiler/rustc_mir_transform/src/simplify_branches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use tracing::trace;

use crate::patch::MirPatch;

pub(super) enum SimplifyConstCondition {
AfterConstProp,
Final,
Expand All @@ -19,26 +21,27 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("Running SimplifyConstCondition on {:?}", body.source);
let typing_env = body.typing_env(tcx);
'blocks: for block in body.basic_blocks_mut() {
for stmt in block.statements.iter_mut() {
let mut patch = MirPatch::new(body);

'blocks: for (bb, block) in body.basic_blocks.iter_enumerated() {
for (statement_index, stmt) in block.statements.iter().enumerate() {
// Simplify `assume` of a known value: either a NOP or unreachable.
if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
&& let NonDivergingIntrinsic::Assume(discr) = intrinsic
&& let Operand::Constant(c) = discr
&& let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
{
if constant {
stmt.make_nop();
patch.nop_statement(Location { block: bb, statement_index });
} else {
block.statements.clear();
block.terminator_mut().kind = TerminatorKind::Unreachable;
patch.patch_terminator(bb, TerminatorKind::Unreachable);
continue 'blocks;
}
}
}

let terminator = block.terminator_mut();
terminator.kind = match terminator.kind {
let terminator = block.terminator();
let terminator = match terminator.kind {
TerminatorKind::SwitchInt {
discr: Operand::Constant(ref c), ref targets, ..
} => {
Expand All @@ -58,7 +61,9 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
},
_ => continue,
};
patch.patch_terminator(bb, terminator);
}
patch.apply(body);
}

fn is_required(&self) -> bool {
Expand Down
22 changes: 22 additions & 0 deletions library/std/src/net/hostname.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::ffi::OsString;

/// Returns the system hostname.
///
/// This can error out in platform-specific error cases;
/// for example, uefi and wasm, where hostnames aren't
/// supported.
///
/// # Underlying system calls
///
/// | Platform | System call |
/// |----------|---------------------------------------------------------------------------------------------------------|
/// | UNIX | [`gethostname`](https://www.man7.org/linux/man-pages/man2/gethostname.2.html) |
/// | Windows | [`GetHostNameW`](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-gethostnamew) |
///
/// Note that platform-specific behavior [may change in the future][changes].
///
/// [changes]: crate::io#platform-specific-behavior
#[unstable(feature = "gethostname", issue = "135142")]
pub fn hostname() -> crate::io::Result<OsString> {
crate::sys::net::hostname()
}
6 changes: 5 additions & 1 deletion library/std/src/net/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Networking primitives for TCP/UDP communication.
//!
//! This module provides networking functionality for the Transmission Control and User
//! Datagram Protocols, as well as types for IP and socket addresses.
//! Datagram Protocols, as well as types for IP and socket addresses and functions related
//! to network properties.
//!
//! # Organization
//!
Expand All @@ -24,6 +25,8 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::net::AddrParseError;

#[unstable(feature = "gethostname", issue = "135142")]
pub use self::hostname::hostname;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -35,6 +38,7 @@ pub use self::tcp::{Incoming, TcpListener, TcpStream};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::udp::UdpSocket;

mod hostname;
mod ip_addr;
mod socket_addr;
mod tcp;
Expand Down
80 changes: 3 additions & 77 deletions library/std/src/sys/net/connection/socket/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
use crate::os::windows::io::{
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
use crate::sync::atomic::Atomic;
use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
use crate::sys::c;
use crate::sys::pal::winsock::last_error;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;
use crate::{cmp, mem, ptr, sys};
Expand Down Expand Up @@ -112,84 +111,11 @@ pub(super) mod netc {
}
}

pub use crate::sys::pal::winsock::{cleanup, cvt, cvt_gai, cvt_r, startup as init};

#[expect(missing_debug_implementations)]
pub struct Socket(OwnedSocket);

static WSA_INITIALIZED: Atomic<bool> = Atomic::<bool>::new(false);

/// Checks whether the Windows socket interface has been started already, and
/// if not, starts it.
#[inline]
pub fn init() {
if !WSA_INITIALIZED.load(Relaxed) {
wsa_startup();
}
}

#[cold]
fn wsa_startup() {
unsafe {
let mut data: c::WSADATA = mem::zeroed();
let ret = c::WSAStartup(
0x202, // version 2.2
&mut data,
);
assert_eq!(ret, 0);
if WSA_INITIALIZED.swap(true, AcqRel) {
// If another thread raced with us and called WSAStartup first then call
// WSACleanup so it's as though WSAStartup was only called once.
c::WSACleanup();
}
}
}

pub fn cleanup() {
// We don't need to call WSACleanup here because exiting the process will cause
// the OS to clean everything for us, which is faster than doing it manually.
// See #141799.
}

/// Returns the last error from the Windows socket interface.
fn last_error() -> io::Error {
io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
}

#[doc(hidden)]
pub trait IsMinusOne {
fn is_minus_one(&self) -> bool;
}

macro_rules! impl_is_minus_one {
($($t:ident)*) => ($(impl IsMinusOne for $t {
fn is_minus_one(&self) -> bool {
*self == -1
}
})*)
}

impl_is_minus_one! { i8 i16 i32 i64 isize }

/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
/// and if so, returns the last error from the Windows socket interface. This
/// function must be called before another call to the socket API is made.
pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
if t.is_minus_one() { Err(last_error()) } else { Ok(t) }
}

/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
pub fn cvt_gai(err: c_int) -> io::Result<()> {
if err == 0 { Ok(()) } else { Err(last_error()) }
}

/// Just to provide the same interface as sys/pal/unix/net.rs
pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
where
T: IsMinusOne,
F: FnMut() -> T,
{
cvt(f())
}

impl Socket {
pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
let family = match *addr {
Expand Down
14 changes: 14 additions & 0 deletions library/std/src/sys/net/hostname/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cfg_select! {
target_family = "unix" => {
mod unix;
pub use unix::hostname;
}
target_os = "windows" => {
mod windows;
pub use windows::hostname;
}
_ => {
mod unsupported;
pub use unsupported::hostname;
}
}
Loading
Loading