Skip to content

Commit

Permalink
Auto merge of #125761 - matthiaskrgr:rollup-7u082og, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #125342 (Document platform-specifics for `Read` and `Write` of `File`)
 - #125711 (Make `body_owned_by` return the `Body` instead of just the `BodyId`)
 - #125739 (drop_in_place: weaken the claim of equivalence with drop(ptr.read()))
 - #125745 (Bump the stage0 compiler to beta.7 (2024-05-26))
 - #125746 (Fix copy-paste error in `Duration::from_weeks` panic message.)
 - #125753 (compiletest: Unify `cmd2procres` with `run_command_to_procres`)
 - #125754 (coverage: Rename MC/DC `conditions_num` to `num_conditions`)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 30, 2024
2 parents d43930d + 479d6ca commit f3ff2f1
Show file tree
Hide file tree
Showing 16 changed files with 576 additions and 492 deletions.
7 changes: 4 additions & 3 deletions compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub mod mcdc {
#[derive(Clone, Copy, Debug, Default)]
pub struct DecisionParameters {
bitmap_idx: u32,
conditions_num: u16,
num_conditions: u16,
}

// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
Expand Down Expand Up @@ -177,8 +177,9 @@ pub mod mcdc {
}

impl From<DecisionInfo> for DecisionParameters {
fn from(value: DecisionInfo) -> Self {
Self { bitmap_idx: value.bitmap_idx, conditions_num: value.conditions_num }
fn from(info: DecisionInfo) -> Self {
let DecisionInfo { bitmap_idx, num_conditions } = info;
Self { bitmap_idx, num_conditions }
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,14 +329,14 @@ pub struct MCDCBranchSpan {
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct DecisionInfo {
pub bitmap_idx: u32,
pub conditions_num: u16,
pub num_conditions: u16,
}

#[derive(Clone, Debug)]
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct MCDCDecisionSpan {
pub span: Span,
pub conditions_num: usize,
pub num_conditions: usize,
pub end_markers: Vec<BlockMarkerId>,
pub decision_depth: u16,
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,12 +512,12 @@ fn write_coverage_branch_info(
)?;
}

for coverage::MCDCDecisionSpan { span, conditions_num, end_markers, decision_depth } in
for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in
mcdc_decision_spans
{
writeln!(
w,
"{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
"{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}"
)?;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
.label = dereference of raw pointer
mir_build_exceeds_mcdc_condition_num_limit = Conditions number of the decision ({$conditions_num}) exceeds limit ({$max_conditions_num}). MCDC analysis will not count this expression.
mir_build_exceeds_mcdc_condition_limit = Number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}). MC/DC analysis will not count this expression.
mir_build_extern_static_requires_unsafe =
use of extern static is unsafe and requires unsafe block
Expand Down
26 changes: 13 additions & 13 deletions compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::Span;

use crate::build::Builder;
use crate::errors::MCDCExceedsConditionNumLimit;
use crate::errors::MCDCExceedsConditionLimit;

/// The MCDC bitmap scales exponentially (2^n) based on the number of conditions seen,
/// So llvm sets a maximum value prevents the bitmap footprint from growing too large without the user's knowledge.
/// This limit may be relaxed if the [upstream change](https://github.com/llvm/llvm-project/pull/82448) is merged.
const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
const MAX_CONDITIONS_IN_DECISION: usize = 6;

#[derive(Default)]
struct MCDCDecisionCtx {
Expand Down Expand Up @@ -100,22 +100,22 @@ impl MCDCState {
}
None => decision_ctx.processing_decision.insert(MCDCDecisionSpan {
span,
conditions_num: 0,
num_conditions: 0,
end_markers: vec![],
decision_depth,
}),
};

let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default();
let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
decision.conditions_num += 1;
ConditionId::from(decision.conditions_num)
decision.num_conditions += 1;
ConditionId::from(decision.num_conditions)
} else {
parent_condition.condition_id
};

decision.conditions_num += 1;
let rhs_condition_id = ConditionId::from(decision.conditions_num);
decision.num_conditions += 1;
let rhs_condition_id = ConditionId::from(decision.num_conditions);

let (lhs, rhs) = match op {
LogicalOp::And => {
Expand Down Expand Up @@ -208,28 +208,28 @@ impl MCDCInfoBuilder {
// is empty, i.e. when all the conditions of the decision were instrumented,
// and the decision is "complete".
if let Some(decision) = decision_result {
match decision.conditions_num {
match decision.num_conditions {
0 => {
unreachable!("Decision with no condition is not expected");
}
1..=MAX_CONDITIONS_NUM_IN_DECISION => {
1..=MAX_CONDITIONS_IN_DECISION => {
self.decision_spans.push(decision);
}
_ => {
// Do not generate mcdc mappings and statements for decisions with too many conditions.
// Therefore, first erase the condition info of the (N-1) previous branch spans.
let rebase_idx = self.branch_spans.len() - (decision.conditions_num - 1);
let rebase_idx = self.branch_spans.len() - (decision.num_conditions - 1);
for branch in &mut self.branch_spans[rebase_idx..] {
branch.condition_info = None;
}

// Then, erase this last branch span's info too, for a total of N.
condition_info = None;

tcx.dcx().emit_warn(MCDCExceedsConditionNumLimit {
tcx.dcx().emit_warn(MCDCExceedsConditionLimit {
span: decision.span,
conditions_num: decision.conditions_num,
max_conditions_num: MAX_CONDITIONS_NUM_IN_DECISION,
num_conditions: decision.num_conditions,
max_conditions: MAX_CONDITIONS_IN_DECISION,
});
}
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,12 +812,12 @@ pub struct NonEmptyNeverPattern<'tcx> {
}

#[derive(Diagnostic)]
#[diag(mir_build_exceeds_mcdc_condition_num_limit)]
pub(crate) struct MCDCExceedsConditionNumLimit {
#[diag(mir_build_exceeds_mcdc_condition_limit)]
pub(crate) struct MCDCExceedsConditionLimit {
#[primary_span]
pub span: Span,
pub conditions_num: usize,
pub max_conditions_num: usize,
pub num_conditions: usize,
pub max_conditions: usize,
}

#[derive(Diagnostic)]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/coverage/mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub(super) struct MCDCDecision {
pub(super) span: Span,
pub(super) end_bcbs: BTreeSet<BasicCoverageBlock>,
pub(super) bitmap_idx: u32,
pub(super) conditions_num: u16,
pub(super) num_conditions: u16,
pub(super) decision_depth: u16,
}

Expand Down Expand Up @@ -268,13 +268,13 @@ pub(super) fn extract_mcdc_mappings(
// the bitmap, rounded up to a whole number of bytes.
// The decision's "bitmap index" points to its first byte in the bitmap.
let bitmap_idx = *mcdc_bitmap_bytes;
*mcdc_bitmap_bytes += (1_u32 << decision.conditions_num).div_ceil(8);
*mcdc_bitmap_bytes += (1_u32 << decision.num_conditions).div_ceil(8);

Some(MCDCDecision {
span,
end_bcbs,
bitmap_idx,
conditions_num: decision.conditions_num as u16,
num_conditions: decision.num_conditions as u16,
decision_depth: decision.decision_depth,
})
},
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@ fn create_mappings<'tcx>(
));

mappings.extend(mcdc_decisions.iter().filter_map(
|&mappings::MCDCDecision { span, bitmap_idx, conditions_num, .. }| {
|&mappings::MCDCDecision { span, bitmap_idx, num_conditions, .. }| {
let code_region = region_for_span(span)?;
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num });
let kind = MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, num_conditions });
Some(Mapping { kind, code_region })
},
));
Expand Down Expand Up @@ -269,7 +269,7 @@ fn inject_mcdc_statements<'tcx>(
span: _,
ref end_bcbs,
bitmap_idx,
conditions_num: _,
num_conditions: _,
decision_depth,
} in &extracted_mappings.mcdc_decisions
{
Expand Down
7 changes: 6 additions & 1 deletion library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,13 @@ mod mut_ptr;

/// Executes the destructor (if any) of the pointed-to value.
///
/// This is semantically equivalent to calling [`ptr::read`] and discarding
/// This is almost the same as calling [`ptr::read`] and discarding
/// the result, but has the following advantages:
// FIXME: say something more useful than "almost the same"?
// There are open questions here: `read` requires the value to be fully valid, e.g. if `T` is a
// `bool` it must be 0 or 1, if it is a reference then it must be dereferenceable. `drop_in_place`
// only requires that `*to_drop` be "valid for dropping" and we have not defined what that means. In
// Miri it currently (May 2024) requires nothing at all for types without drop glue.
///
/// * It is *required* to use `drop_in_place` to drop unsized types like
/// trait objects, because they can't be read out onto the stack and
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ impl Duration {
#[inline]
pub const fn from_weeks(weeks: u64) -> Duration {
if weeks > u64::MAX / (SECS_PER_MINUTE * MINS_PER_HOUR * HOURS_PER_DAY * DAYS_PER_WEEK) {
panic!("overflow in Duration::from_days");
panic!("overflow in Duration::from_weeks");
}

Duration::from_secs(weeks * MINS_PER_HOUR * SECS_PER_MINUTE * HOURS_PER_DAY * DAYS_PER_WEEK)
Expand Down
76 changes: 76 additions & 0 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,11 +767,33 @@ fn buffer_capacity_required(mut file: &File) -> Option<usize> {

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for &File {
/// Read some bytes from the file.
///
/// See [`Read::read`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `read` function on Unix and
/// the `NtReadFile` function on Windows. Note that this [may change in
/// the future][changes].
///
/// [changes]: io#platform-specific-behavior
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}

/// Like `read`, except that it reads into a slice of buffers.
///
/// See [`Read::read_vectored`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `readv` function on Unix and
/// falls back to the `read` implementation on Windows. Note that this
/// [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
#[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
self.inner.read_vectored(bufs)
Expand All @@ -782,6 +804,16 @@ impl Read for &File {
self.inner.read_buf(cursor)
}

/// Determines if `File` has an efficient `read_vectored` implementation.
///
/// See [`Read::is_read_vectored`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently returns `true` on Unix an `false` on Windows.
/// Note that this [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
#[inline]
fn is_read_vectored(&self) -> bool {
self.inner.is_read_vectored()
Expand All @@ -803,19 +835,63 @@ impl Read for &File {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for &File {
/// Write some bytes from the file.
///
/// See [`Write::write`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `write` function on Unix and
/// the `NtWriteFile` function on Windows. Note that this [may change in
/// the future][changes].
///
/// [changes]: io#platform-specific-behavior
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}

/// Like `write`, except that it writes into a slice of buffers.
///
/// See [`Write::write_vectored`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently corresponds to the `writev` function on Unix
/// and falls back to the `write` implementation on Windows. Note that this
/// [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
self.inner.write_vectored(bufs)
}

/// Determines if `File` has an efficient `write_vectored` implementation.
///
/// See [`Write::is_write_vectored`] docs for more info.
///
/// # Platform-specific behavior
///
/// This function currently returns `true` on Unix an `false` on Windows.
/// Note that this [may change in the future][changes].
///
/// [changes]: io#platform-specific-behavior
#[inline]
fn is_write_vectored(&self) -> bool {
self.inner.is_write_vectored()
}

/// Flushes the file, ensuring that all intermediately buffered contents
/// reach their destination.
///
/// See [`Write::flush`] docs for more info.
///
/// # Platform-specific behavior
///
/// Since a `File` structure doesn't contain any buffers, this function is
/// currently a no-op on Unix and Windows. Note that this [may change in
/// the future][changes].
///
/// [changes]: io#platform-specific-behavior
#[inline]
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
Expand Down
Loading

0 comments on commit f3ff2f1

Please sign in to comment.