detect consts that reference extern statics
This commit is contained in:
parent
9c0623fe8f
commit
77f8c3caea
9 changed files with 97 additions and 51 deletions
|
@ -360,7 +360,7 @@ pub fn const_validate_mplace<'mir, 'tcx>(
|
|||
// Promoteds in statics are consts that re allowed to point to statics.
|
||||
CtfeValidationMode::Const {
|
||||
allow_immutable_unsafe_cell: false,
|
||||
allow_static_ptrs: true,
|
||||
allow_extern_static_ptrs: true,
|
||||
}
|
||||
}
|
||||
Some(mutbl) => CtfeValidationMode::Static { mutbl }, // a `static`
|
||||
|
@ -368,7 +368,10 @@ pub fn const_validate_mplace<'mir, 'tcx>(
|
|||
// In normal `const` (not promoted), the outermost allocation is always only copied,
|
||||
// so having `UnsafeCell` in there is okay despite them being in immutable memory.
|
||||
let allow_immutable_unsafe_cell = cid.promoted.is_none() && !inner;
|
||||
CtfeValidationMode::Const { allow_immutable_unsafe_cell, allow_static_ptrs: false }
|
||||
CtfeValidationMode::Const {
|
||||
allow_immutable_unsafe_cell,
|
||||
allow_extern_static_ptrs: false,
|
||||
}
|
||||
}
|
||||
};
|
||||
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)?;
|
||||
|
|
|
@ -612,6 +612,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
|
||||
PartialPointer => const_eval_validation_partial_pointer,
|
||||
ConstRefToMutable => const_eval_validation_const_ref_to_mutable,
|
||||
ConstRefToExtern => const_eval_validation_const_ref_to_extern,
|
||||
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
|
||||
MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
|
||||
NullFnPtr => const_eval_validation_null_fn_ptr,
|
||||
|
@ -767,6 +768,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
| PtrToStatic { .. }
|
||||
| MutableRefInConst
|
||||
| ConstRefToMutable
|
||||
| ConstRefToExtern
|
||||
| MutableRefToImmutable
|
||||
| NullFnPtr
|
||||
| NeverVal
|
||||
|
|
|
@ -133,7 +133,7 @@ pub enum CtfeValidationMode {
|
|||
/// `allow_immutable_unsafe_cell` says whether we allow `UnsafeCell` in immutable memory (which is the
|
||||
/// case for the top-level allocation of a `const`, where this is fine because the allocation will be
|
||||
/// copied at each use site).
|
||||
Const { allow_immutable_unsafe_cell: bool, allow_static_ptrs: bool },
|
||||
Const { allow_immutable_unsafe_cell: bool, allow_extern_static_ptrs: bool },
|
||||
}
|
||||
|
||||
impl CtfeValidationMode {
|
||||
|
@ -488,13 +488,23 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
// This could miss some UB, but that's fine.
|
||||
return Ok(());
|
||||
}
|
||||
Some(CtfeValidationMode::Const { .. }) => {
|
||||
Some(CtfeValidationMode::Const {
|
||||
allow_extern_static_ptrs, ..
|
||||
}) => {
|
||||
// For consts on the other hand we have to recursively check;
|
||||
// pattern matching assumes a valid value. However we better make
|
||||
// sure this is not mutable.
|
||||
if is_mut {
|
||||
throw_validation_failure!(self.path, ConstRefToMutable);
|
||||
}
|
||||
if self.ecx.tcx.is_foreign_item(did) {
|
||||
if !allow_extern_static_ptrs {
|
||||
throw_validation_failure!(self.path, ConstRefToExtern);
|
||||
} else {
|
||||
// We can't validate this...
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue