Skip to content

Commit 6181cb2

Browse files
committed
Move linkage type check to HIR analysis and fix semantics issues.
This ensures that the error is printed even for unused variables, as well as unifying the handling between the LLVM and GCC backends. This also fixes unusual behavior around exported Rust-defined variables with linkage attributes. With the previous behavior, it appears to be impossible to define such a variable such that it can actually be imported and used by another crate. This is because on the importing side, the variable is required to be a pointer, but on the exporting side, the type checker rejects static variables of pointer type because they do not implement `Sync`. Even if it were possible to import such a type, it appears that code generation on the importing side would add an unexpected additional level of pointer indirection, which would break type safety. This highlighted that the semantics of linkage on Rust-defined variables is different to linkage on foreign items. As such, we now model the difference with two different codegen attributes: linkage for Rust-defined variables, and import_linkage for foreign items. This change gives semantics to the test src/test/ui/linkage-attr/auxiliary/def_illtyped_external.rs which was previously expected to fail to compile. Therefore, convert it into a test that is expected to successfully compile. The update to the GCC backend is speculative and untested.
1 parent 12224e8 commit 6181cb2

File tree

2 files changed

+6
-28
lines changed

2 files changed

+6
-28
lines changed

src/consts.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ use rustc_middle::mir::mono::MonoItem;
88
use rustc_middle::ty::{self, Instance, Ty};
99
use rustc_middle::ty::layout::LayoutOf;
1010
use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint};
11-
use rustc_span::Span;
1211
use rustc_span::def_id::DefId;
1312
use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange};
1413

1514
use crate::base;
1615
use crate::context::CodegenCx;
17-
use crate::errors::LinkageConstOrMutType;
1816
use crate::type_of::LayoutGccExt;
1917

2018
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
@@ -239,12 +237,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
239237
}
240238

241239
Node::ForeignItem(&hir::ForeignItem {
242-
span,
240+
span: _,
243241
kind: hir::ForeignItemKind::Static(..),
244242
..
245243
}) => {
246244
let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
247-
check_and_apply_linkage(&self, &fn_attrs, ty, sym, span)
245+
check_and_apply_linkage(&self, &fn_attrs, ty, sym)
248246
}
249247

250248
item => bug!("get_static: expected static, found {:?}", item),
@@ -257,8 +255,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
257255
//debug!("get_static: sym={} item_attr={:?}", sym, self.tcx.item_attrs(def_id));
258256

259257
let attrs = self.tcx.codegen_fn_attrs(def_id);
260-
let span = self.tcx.def_span(def_id);
261-
let global = check_and_apply_linkage(&self, &attrs, ty, sym, span);
258+
let global = check_and_apply_linkage(&self, &attrs, ty, sym);
262259

263260
let needs_dll_storage_attr = false; // TODO(antoyo)
264261

@@ -355,24 +352,12 @@ pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id
355352
Ok((const_alloc_to_gcc(cx, alloc), alloc))
356353
}
357354

358-
fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str, span: Span) -> LValue<'gcc> {
355+
fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str) -> LValue<'gcc> {
359356
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
360357
let llty = cx.layout_of(ty).gcc_type(cx, true);
361-
if let Some(linkage) = attrs.linkage {
362-
// If this is a static with a linkage specified, then we need to handle
363-
// it a little specially. The typesystem prevents things like &T and
364-
// extern "C" fn() from being non-null, so we can't just declare a
365-
// static and call it a day. Some linkages (like weak) will make it such
366-
// that the static actually has a null value.
367-
let llty2 =
368-
if let ty::RawPtr(ref mt) = ty.kind() {
369-
cx.layout_of(mt.ty).gcc_type(cx, true)
370-
}
371-
else {
372-
cx.sess().emit_fatal(LinkageConstOrMutType { span: span })
373-
};
358+
if let Some(linkage) = attrs.import_linkage {
374359
// Declare a symbol `foo` with the desired linkage.
375-
let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage));
360+
let global1 = cx.declare_global_with_linkage(&sym, cx.type_i8(), base::global_linkage_to_gcc(linkage));
376361

377362
// Declare an internal global `extern_with_linkage_foo` which
378363
// is initialized with the address of `foo`. If `foo` is

src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,6 @@ pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
211211
pub in_elem: Ty<'a>,
212212
}
213213

214-
#[derive(Diagnostic)]
215-
#[diag(codegen_gcc_linkage_const_or_mut_type)]
216-
pub(crate) struct LinkageConstOrMutType {
217-
#[primary_span]
218-
pub span: Span,
219-
}
220-
221214
#[derive(Diagnostic)]
222215
#[diag(codegen_gcc_lto_not_supported)]
223216
pub(crate) struct LTONotSupported;

0 commit comments

Comments
 (0)