Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #73654

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b97487b
Add check for doc alias attribute format
GuillaumeGomez May 30, 2020
2d6267a
Add test for doc alias attribute validation
GuillaumeGomez May 30, 2020
8fc2eeb
Use newtype to map from `Local` to `GeneratorSavedLocal`
ecstatic-morse Jun 10, 2020
c178e64
Look for stores between non-conflicting generator saved locals
ecstatic-morse Jun 10, 2020
b2ec645
Incorporate review suggestions
ecstatic-morse Jun 19, 2020
95f8daa
Fix -Z unpretty=everybody_loops
jyn514 Jun 20, 2020
f05c6db
lints: add `improper_ctypes_definitions`
davidtwco May 28, 2020
08be0e8
improper_ctypes: allow pointers to sized types
davidtwco May 28, 2020
3e94136
improper_ctypes: only allow params in defns mode
davidtwco Jun 21, 2020
7930f9a
Change heuristic for determining range literal
ayazhafiz Jun 23, 2020
bb882d7
Add test for issue-44861
JohnTitor Jun 23, 2020
43ef554
Add test for issue-51506
JohnTitor Jun 23, 2020
e817cd2
Add test for issue-59435
JohnTitor Jun 23, 2020
814782b
Add test for issue-69840
JohnTitor Jun 23, 2020
24c460f
Rollup merge of #72700 - davidtwco:issue-66220-improper-ctypes-declar…
Dylan-DPC Jun 23, 2020
ff618e5
Rollup merge of #72780 - GuillaumeGomez:enforce-doc-alias-check, r=ol…
Dylan-DPC Jun 23, 2020
9d4b416
Rollup merge of #73244 - ecstatic-morse:validate-generator-mir, r=tma…
Dylan-DPC Jun 23, 2020
fd0bd25
Rollup merge of #73523 - jyn514:everybody_loops, r=ecstatic-morse
Dylan-DPC Jun 23, 2020
6c929e4
Rollup merge of #73639 - ayazhafiz:i/73553, r=davidtwco
Dylan-DPC Jun 23, 2020
ec8af88
Rollup merge of #73646 - JohnTitor:add-tests, r=Dylan-DPC
Dylan-DPC Jun 23, 2020
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
2 changes: 2 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@
//! pub struct Foo;
//!
//! #[no_mangle]
//! #[allow(improper_ctypes_definitions)]
//! pub extern "C" fn foo_new() -> Box<Foo> {
//! Box::new(Foo)
//! }
//!
//! #[no_mangle]
//! #[allow(improper_ctypes_definitions)]
//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
//! ```
//!
Expand Down
1 change: 1 addition & 0 deletions src/libpanic_abort/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use core::any::Any;

#[rustc_std_internal_symbol]
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Send + 'static) {
unreachable!()
}
Expand Down
1 change: 1 addition & 0 deletions src/libpanic_unwind/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ extern "C" {
mod dwarf;

#[rustc_std_internal_symbol]
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static) {
Box::into_raw(imp::cleanup(payload))
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ pub fn run_compiler(
compiler.output_file().as_ref().map(|p| &**p),
);
}
trace!("finished pretty-printing");
return early_exit();
}

Expand Down
8 changes: 1 addition & 7 deletions src/librustc_hir/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,13 +1511,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
// Check whether a span corresponding to a range expression is a
// range literal, rather than an explicit struct or `new()` call.
fn is_lit(sm: &SourceMap, span: &Span) -> bool {
let end_point = sm.end_point(*span);

if let Ok(end_string) = sm.span_to_snippet(end_point) {
!(end_string.ends_with('}') || end_string.ends_with(')'))
} else {
false
}
sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false)
};

match expr.kind {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub fn run_compiler_in_existing_thread_pool<R>(
}

pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
log::trace!("run_compiler");
let stderr = config.stderr.take();
util::spawn_thread_pool(
config.opts.edition,
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub fn configure_and_expand(
krate: ast::Crate,
crate_name: &str,
) -> Result<(ast::Crate, BoxedResolver)> {
log::trace!("configure_and_expand");
// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
// item, much like we do for macro expansion. In other words, the hash reflects not just
Expand Down Expand Up @@ -230,6 +231,7 @@ fn configure_and_expand_inner<'a>(
resolver_arenas: &'a ResolverArenas<'a>,
metadata_loader: &'a MetadataLoaderDyn,
) -> Result<(ast::Crate, Resolver<'a>)> {
log::trace!("configure_and_expand_inner");
pre_expansion_lint(sess, lint_store, &krate);

let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas);
Expand Down Expand Up @@ -357,6 +359,7 @@ fn configure_and_expand_inner<'a>(
should_loop |= true;
}
if should_loop {
log::debug!("replacing bodies with loop {{}}");
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_interface/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl<'tcx> Queries<'tcx> {
pub fn expansion(
&self,
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
log::trace!("expansion");
self.expansion.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let (krate, lint_store) = self.register_plugins()?.take();
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ macro_rules! late_lint_mod_passes {
$args,
[
HardwiredLints: HardwiredLints,
ImproperCTypes: ImproperCTypes,
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
VariantSizeDifferences: VariantSizeDifferences,
BoxPointers: BoxPointers,
PathStatements: PathStatements,
Expand Down
120 changes: 95 additions & 25 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_span::source_map;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
use rustc_target::spec::abi::Abi;

Expand Down Expand Up @@ -498,10 +498,24 @@ declare_lint! {
"proper use of libc types in foreign modules"
}

declare_lint_pass!(ImproperCTypes => [IMPROPER_CTYPES]);
declare_lint_pass!(ImproperCTypesDeclarations => [IMPROPER_CTYPES]);

declare_lint! {
IMPROPER_CTYPES_DEFINITIONS,
Warn,
"proper use of libc types in foreign item definitions"
}

declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);

enum ImproperCTypesMode {
Declarations,
Definitions,
}

struct ImproperCTypesVisitor<'a, 'tcx> {
cx: &'a LateContext<'a, 'tcx>,
mode: ImproperCTypesMode,
}

enum FfiResult<'tcx> {
Expand Down Expand Up @@ -804,27 +818,32 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
help: Some("consider using a struct instead".into()),
},

ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
if {
matches!(self.mode, ImproperCTypesMode::Definitions)
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
} =>
{
FfiSafe
}

ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
self.check_type_for_ffi(cache, ty)
}

ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),

ty::FnPtr(sig) => {
match sig.abi() {
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
return FfiUnsafe {
ty,
reason: "this function pointer has Rust-specific calling convention"
if self.is_internal_abi(sig.abi()) {
return FfiUnsafe {
ty,
reason: "this function pointer has Rust-specific calling convention".into(),
help: Some(
"consider using an `extern fn(...) -> ...` \
function pointer instead"
.into(),
help: Some(
"consider using an `extern fn(...) -> ...` \
function pointer instead"
.into(),
),
};
}
_ => {}
),
};
}

let sig = cx.erase_late_bound_regions(&sig);
Expand Down Expand Up @@ -857,15 +876,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
FfiUnsafe { ty, reason: "opaque types have no C equivalent".into(), help: None }
}

// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
// so they are currently ignored for the purposes of this lint.
ty::Param(..) | ty::Projection(..)
if matches!(self.mode, ImproperCTypesMode::Definitions) =>
{
FfiSafe
}

ty::Param(..)
| ty::Projection(..)
| ty::Infer(..)
| ty::Bound(..)
| ty::Error(_)
| ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::Placeholder(..)
| ty::Projection(..)
| ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
}
}
Expand All @@ -877,9 +904,20 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
note: &str,
help: Option<&str>,
) {
self.cx.struct_span_lint(IMPROPER_CTYPES, sp, |lint| {
let mut diag =
lint.build(&format!("`extern` block uses type `{}`, which is not FFI-safe", ty));
let lint = match self.mode {
ImproperCTypesMode::Declarations => IMPROPER_CTYPES,
ImproperCTypesMode::Definitions => IMPROPER_CTYPES_DEFINITIONS,
};

self.cx.struct_span_lint(lint, sp, |lint| {
let item_description = match self.mode {
ImproperCTypesMode::Declarations => "block",
ImproperCTypesMode::Definitions => "fn",
};
let mut diag = lint.build(&format!(
"`extern` {} uses type `{}`, which is not FFI-safe",
item_description, ty
));
diag.span_label(sp, "not FFI-safe");
if let Some(help) = help {
diag.help(help);
Expand Down Expand Up @@ -947,7 +985,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

// it is only OK to use this function because extern fns cannot have
// any generic types right now:
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);

// C doesn't really support passing arrays by value - the only way to pass an array by value
// is through a struct. So, first test that the top level isn't an array, and then
Expand Down Expand Up @@ -997,15 +1035,22 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let ty = self.cx.tcx.type_of(def_id);
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
}

fn is_internal_abi(&self, abi: Abi) -> bool {
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
true
} else {
false
}
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDeclarations {
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem<'_>) {
let mut vis = ImproperCTypesVisitor { cx };
let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Declarations };
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
// Don't worry about types in internal ABIs.
} else {

if !vis.is_internal_abi(abi) {
match it.kind {
hir::ForeignItemKind::Fn(ref decl, _, _) => {
vis.check_foreign_fn(it.hir_id, decl);
Expand All @@ -1019,6 +1064,31 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypesDefinitions {
fn check_fn(
&mut self,
cx: &LateContext<'a, 'tcx>,
kind: hir::intravisit::FnKind<'tcx>,
decl: &'tcx hir::FnDecl<'_>,
_: &'tcx hir::Body<'_>,
_: Span,
hir_id: hir::HirId,
) {
use hir::intravisit::FnKind;

let abi = match kind {
FnKind::ItemFn(_, _, header, ..) => header.abi,
FnKind::Method(_, sig, ..) => sig.header.abi,
_ => return,
};

let mut vis = ImproperCTypesVisitor { cx, mode: ImproperCTypesMode::Definitions };
if !vis.is_internal_abi(abi) {
vis.check_foreign_fn(hir_id, decl);
}
}
}

declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct RustString {

/// Appending to a Rust string -- used by RawRustStringOstream.
#[no_mangle]
#[cfg_attr(not(bootstrap), allow(improper_ctypes_definitions))]
pub unsafe extern "C" fn LLVMRustStringWriteImpl(
sr: &RustString,
ptr: *const c_char,
Expand Down
Loading