Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 43f868b

Browse files
pccantoyo
authored andcommitted
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 d1eb38f commit 43f868b

File tree

2 files changed

+6
-26
lines changed

2 files changed

+6
-26
lines changed

src/consts.rs

Lines changed: 6 additions & 19 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> {
@@ -216,7 +214,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
216214
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
217215
let sym = self.tcx.symbol_name(instance).name;
218216

219-
let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
217+
let global =
218+
if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
220219
let llty = self.layout_of(ty).gcc_type(self);
221220
if let Some(global) = self.get_declared_value(sym) {
222221
if self.val_ty(global) != self.type_ptr_to(llty) {
@@ -239,7 +238,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
239238

240239
global
241240
} else {
242-
check_and_apply_linkage(&self, &fn_attrs, ty, sym, self.tcx.def_span(def_id))
241+
check_and_apply_linkage(&self, &fn_attrs, ty, sym)
243242
};
244243

245244
if !def_id.is_local() {
@@ -337,24 +336,12 @@ pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id
337336
Ok((const_alloc_to_gcc(cx, alloc), alloc))
338337
}
339338

340-
fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str, span: Span) -> LValue<'gcc> {
339+
fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str) -> LValue<'gcc> {
341340
let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
342341
let llty = cx.layout_of(ty).gcc_type(cx);
343-
if let Some(linkage) = attrs.linkage {
344-
// If this is a static with a linkage specified, then we need to handle
345-
// it a little specially. The typesystem prevents things like &T and
346-
// extern "C" fn() from being non-null, so we can't just declare a
347-
// static and call it a day. Some linkages (like weak) will make it such
348-
// that the static actually has a null value.
349-
let llty2 =
350-
if let ty::RawPtr(ref mt) = ty.kind() {
351-
cx.layout_of(mt.ty).gcc_type(cx)
352-
}
353-
else {
354-
cx.sess().emit_fatal(LinkageConstOrMutType { span: span })
355-
};
342+
if let Some(linkage) = attrs.import_linkage {
356343
// Declare a symbol `foo` with the desired linkage.
357-
let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage));
344+
let global1 = cx.declare_global_with_linkage(&sym, cx.type_i8(), base::global_linkage_to_gcc(linkage));
358345

359346
// Declare an internal global `extern_with_linkage_foo` which
360347
// 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)