Skip to content

Commit a1f67ad

Browse files
author
Robin Kruppe
committed
Revert "Auto merge of #65134 - davidtwco:issue-19834-improper-ctypes-in-extern-C-fn, r=rkruppe"
This reverts commit 3f0e164, reversing changes made to 61a551b.
1 parent 374ad1b commit a1f67ad

File tree

18 files changed

+37
-521
lines changed

18 files changed

+37
-521
lines changed

src/libpanic_abort/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
// Rust's "try" function, but if we're aborting on panics we just call the
2222
// function as there's nothing else we need to do here.
2323
#[rustc_std_internal_symbol]
24-
#[allow(improper_ctypes)]
2524
pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
2625
data: *mut u8,
2726
_data_ptr: *mut usize,

src/libpanic_unwind/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ mod dwarf;
7272
// hairy and tightly coupled, for more information see the compiler's
7373
// implementation of this.
7474
#[no_mangle]
75-
#[allow(improper_ctypes)]
7675
pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
7776
data: *mut u8,
7877
data_ptr: *mut usize,

src/librustc_codegen_llvm/back/write.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
240240
}
241241
}
242242

243-
fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>, msg: &str, cookie: c_uint) {
243+
unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>,
244+
msg: &str,
245+
cookie: c_uint) {
244246
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
245247
}
246248

src/librustc_codegen_llvm/llvm/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ pub struct RustString {
8787
}
8888

8989
/// Appending to a Rust string -- used by RawRustStringOstream.
90-
#[allow(improper_ctypes)]
9190
#[no_mangle]
9291
pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString,
9392
ptr: *const c_char,

src/librustc_lint/types.rs

+33-69
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc::hir::{ExprKind, Node};
44
use crate::hir::def_id::DefId;
55
use rustc::hir::lowering::is_range_literal;
66
use rustc::ty::subst::SubstsRef;
7-
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
7+
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
88
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton};
99
use rustc::{lint, util};
1010
use rustc_index::vec::Idx;
@@ -837,13 +837,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
837837
ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),
838838

839839
ty::FnPtr(sig) => {
840-
if self.is_internal_abi(sig.abi()) {
841-
return FfiUnsafe {
842-
ty,
843-
reason: "this function pointer has Rust-specific calling convention",
844-
help: Some("consider using an `extern fn(...) -> ...` \
845-
function pointer instead"),
846-
};
840+
match sig.abi() {
841+
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
842+
return FfiUnsafe {
843+
ty,
844+
reason: "this function pointer has Rust-specific calling convention",
845+
help: Some("consider using an `extern fn(...) -> ...` \
846+
function pointer instead"),
847+
}
848+
}
849+
_ => {}
847850
}
848851

849852
let sig = cx.erase_late_bound_regions(&sig);
@@ -870,10 +873,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
870873

871874
ty::Foreign(..) => FfiSafe,
872875

873-
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
874-
// so they are currently ignored for the purposes of this lint, see #65134.
875-
ty::Param(..) | ty::Projection(..) => FfiSafe,
876-
876+
ty::Param(..) |
877877
ty::Infer(..) |
878878
ty::Bound(..) |
879879
ty::Error |
@@ -882,6 +882,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
882882
ty::GeneratorWitness(..) |
883883
ty::Placeholder(..) |
884884
ty::UnnormalizedProjection(..) |
885+
ty::Projection(..) |
885886
ty::Opaque(..) |
886887
ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
887888
}
@@ -893,16 +894,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
893894
sp: Span,
894895
note: &str,
895896
help: Option<&str>,
896-
is_foreign_item: bool,
897897
) {
898898
let mut diag = self.cx.struct_span_lint(
899899
IMPROPER_CTYPES,
900900
sp,
901-
&format!(
902-
"`extern` {} uses type `{}`, which is not FFI-safe",
903-
if is_foreign_item { "block" } else { "fn" },
904-
ty,
905-
),
901+
&format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
906902
);
907903
diag.span_label(sp, "not FFI-safe");
908904
if let Some(help) = help {
@@ -917,7 +913,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
917913
diag.emit();
918914
}
919915

920-
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>, is_foreign_item: bool) -> bool {
916+
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
917+
use crate::rustc::ty::TypeFoldable;
918+
921919
struct ProhibitOpaqueTypes<'tcx> {
922920
ty: Option<Ty<'tcx>>,
923921
};
@@ -941,81 +939,70 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
941939
sp,
942940
"opaque types have no C equivalent",
943941
None,
944-
is_foreign_item,
945942
);
946943
true
947944
} else {
948945
false
949946
}
950947
}
951948

952-
fn check_type_for_ffi_and_report_errors(
953-
&mut self,
954-
sp: Span,
955-
ty: Ty<'tcx>,
956-
is_foreign_item: bool,
957-
) {
949+
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
958950
// We have to check for opaque types before `normalize_erasing_regions`,
959951
// which will replace opaque types with their underlying concrete type.
960-
if self.check_for_opaque_ty(sp, ty, is_foreign_item) {
952+
if self.check_for_opaque_ty(sp, ty) {
961953
// We've already emitted an error due to an opaque type.
962954
return;
963955
}
964956

965-
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
957+
// it is only OK to use this function because extern fns cannot have
958+
// any generic types right now:
959+
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
960+
966961
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
967962
FfiResult::FfiSafe => {}
968963
FfiResult::FfiPhantom(ty) => {
969-
self.emit_ffi_unsafe_type_lint(
970-
ty, sp, "composed only of `PhantomData`", None, is_foreign_item);
964+
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
971965
}
972966
FfiResult::FfiUnsafe { ty, reason, help } => {
973-
self.emit_ffi_unsafe_type_lint(
974-
ty, sp, reason, help, is_foreign_item);
967+
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
975968
}
976969
}
977970
}
978971

979-
fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl, is_foreign_item: bool) {
972+
fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
980973
let def_id = self.cx.tcx.hir().local_def_id(id);
981974
let sig = self.cx.tcx.fn_sig(def_id);
982975
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
983976

984977
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
985-
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, is_foreign_item);
978+
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
986979
}
987980

988981
if let hir::Return(ref ret_hir) = decl.output {
989982
let ret_ty = sig.output();
990983
if !ret_ty.is_unit() {
991-
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, is_foreign_item);
984+
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
992985
}
993986
}
994987
}
995988

996989
fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
997990
let def_id = self.cx.tcx.hir().local_def_id(id);
998991
let ty = self.cx.tcx.type_of(def_id);
999-
self.check_type_for_ffi_and_report_errors(span, ty, true);
1000-
}
1001-
1002-
fn is_internal_abi(&self, abi: Abi) -> bool {
1003-
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1004-
true
1005-
} else {
1006-
false
1007-
}
992+
self.check_type_for_ffi_and_report_errors(span, ty);
1008993
}
1009994
}
1010995

1011996
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
1012997
fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
1013998
let mut vis = ImproperCTypesVisitor { cx };
1014999
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
1015-
if !vis.is_internal_abi(abi) {
1000+
if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
1001+
// Don't worry about types in internal ABIs.
1002+
} else {
10161003
match it.kind {
10171004
hir::ForeignItemKind::Fn(ref decl, _, _) => {
1018-
vis.check_foreign_fn(it.hir_id, decl, true);
1005+
vis.check_foreign_fn(it.hir_id, decl);
10191006
}
10201007
hir::ForeignItemKind::Static(ref ty, _) => {
10211008
vis.check_foreign_static(it.hir_id, ty.span);
@@ -1024,29 +1011,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10241011
}
10251012
}
10261013
}
1027-
1028-
fn check_fn(
1029-
&mut self,
1030-
cx: &LateContext<'a, 'tcx>,
1031-
kind: hir::intravisit::FnKind<'tcx>,
1032-
decl: &'tcx hir::FnDecl,
1033-
_: &'tcx hir::Body,
1034-
_: Span,
1035-
hir_id: hir::HirId,
1036-
) {
1037-
use hir::intravisit::FnKind;
1038-
1039-
let abi = match kind {
1040-
FnKind::ItemFn(_, _, header, ..) => (header.abi),
1041-
FnKind::Method(_, sig, ..) => (sig.header.abi),
1042-
_ => return,
1043-
};
1044-
1045-
let mut vis = ImproperCTypesVisitor { cx };
1046-
if !vis.is_internal_abi(abi) {
1047-
vis.check_foreign_fn(hir_id, decl, false);
1048-
}
1049-
}
10501014
}
10511015

10521016
declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);

src/libstd/sys/sgx/abi/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
5353
// (main function exists). If this is a library, the crate author should be
5454
// able to specify this
5555
#[cfg(not(test))]
56-
#[allow(improper_ctypes)]
5756
#[no_mangle]
5857
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
5958
// FIXME: how to support TLS in library mode?

src/libstd/sys/sgx/rwlock.rs

-3
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ const EINVAL: i32 = 22;
172172

173173
#[cfg(not(test))]
174174
#[no_mangle]
175-
#[allow(improper_ctypes)]
176175
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
177176
if p.is_null() {
178177
return EINVAL;
@@ -182,7 +181,6 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
182181
}
183182

184183
#[cfg(not(test))]
185-
#[allow(improper_ctypes)]
186184
#[no_mangle]
187185
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
188186
if p.is_null() {
@@ -192,7 +190,6 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
192190
return 0;
193191
}
194192
#[cfg(not(test))]
195-
#[allow(improper_ctypes)]
196193
#[no_mangle]
197194
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
198195
if p.is_null() {

src/test/ui/abi/abi-sysv64-register-usage.rs

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
3333

3434
// this struct contains 8 i64's, while only 6 can be passed in registers.
3535
#[cfg(target_arch = "x86_64")]
36-
#[repr(C)]
3736
#[derive(PartialEq, Eq, Debug)]
3837
pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
3938

src/test/ui/align-with-extern-c-fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#![feature(repr_align)]
99

10-
#[repr(align(16), C)]
10+
#[repr(align(16))]
1111
pub struct A(i64);
1212

1313
pub extern "C" fn foo(x: A) {}

src/test/ui/issues/issue-16441.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
struct Empty;
66

77
// This used to cause an ICE
8-
#[allow(improper_ctypes)]
98
extern "C" fn ice(_a: Empty) {}
109

1110
fn main() {

src/test/ui/issues/issue-26997.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub struct Foo {
66
}
77

88
impl Foo {
9-
#[allow(improper_ctypes)]
109
pub extern fn foo_new() -> Foo {
1110
Foo { x: 21, y: 33 }
1211
}

src/test/ui/issues/issue-28600.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
struct Test;
55

66
impl Test {
7-
#[allow(improper_ctypes)]
87
#[allow(dead_code)]
98
#[allow(unused_variables)]
109
pub extern fn test(val: &str) {

src/test/ui/issues/issue-38763.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#[repr(C)]
55
pub struct Foo(i128);
66

7-
#[allow(improper_ctypes)]
87
#[no_mangle]
98
pub extern "C" fn foo(x: Foo) -> Foo { x }
109

src/test/ui/issues/issue-51907.rs

-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ trait Foo {
66

77
struct Bar;
88
impl Foo for Bar {
9-
#[allow(improper_ctypes)]
109
extern fn borrow(&self) {}
11-
#[allow(improper_ctypes)]
1210
extern fn take(self: Box<Self>) {}
1311
}
1412

0 commit comments

Comments
 (0)