From: Lucas Ly Ba <[email protected]>
Warn on an `extern` block written without an explicit ABI string, such as
a bare `extern { ... }`, which silently defaults to the C ABI. Rust
deprecates this in favour of spelling the ABI out, e.g. `extern "C"`.
The HIR `ExternBlock` only stored the resolved ABI enum, which always
collapses a missing ABI to the C default, so it could not tell a bare
`extern` from `extern "C"`. Carry the AST's `has_abi` flag through
lowering so the lint can distinguish the two.
gcc/rust/ChangeLog:
* hir/tree/rust-hir-item.h (ExternBlock): Track whether the ABI
was explicit and expose it through has_abi.
* hir/tree/rust-hir-item.cc (ExternBlock::ExternBlock): Likewise.
(ExternBlock::operator=): Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_extern_block):
Forward the AST has_abi flag to the HIR node.
* checks/lints/unused/rust-unused-checker.cc (UnusedChecker::visit):
New.
* checks/lints/unused/rust-unused-checker.h (UnusedChecker::visit):
New.
gcc/testsuite/ChangeLog:
* rust/compile/missing-abi_0.rs: New test.
Signed-off-by: Lucas Ly Ba <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/520f9e075285ee1759f99f88a0fa3b3506e95615
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4649
gcc/rust/checks/lints/unused/rust-unused-checker.cc | 10 ++++++++++
gcc/rust/checks/lints/unused/rust-unused-checker.h | 1 +
gcc/rust/hir/rust-ast-lower-base.cc | 5 +++--
gcc/rust/hir/tree/rust-hir-item.cc | 8 +++++---
gcc/rust/hir/tree/rust-hir-item.h | 6 +++++-
gcc/testsuite/rust/compile/missing-abi_0.rs | 12 ++++++++++++
6 files changed, 36 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/missing-abi_0.rs
diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
index 30fb37cfb..643d262d2 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -188,6 +188,16 @@ UnusedChecker::visit (HIR::LifetimeParam &lft)
walk (lft);
}
+void
+UnusedChecker::visit (HIR::ExternBlock &block)
+{
+ if (!block.has_abi ())
+ rust_warning_at (block.get_locus (), OPT_Wunused_variable,
+ "extern declarations without an explicit ABI are "
+ "deprecated");
+ walk (block);
+}
+
void
UnusedChecker::visit_loop_label (HIR::LoopLabel &label)
{
diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.h
b/gcc/rust/checks/lints/unused/rust-unused-checker.h
index c8a272041..2f2557ce3 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h
@@ -50,6 +50,7 @@ private:
virtual void visit (HIR::LifetimeParam &lft) override;
virtual void visit (HIR::StructPatternFieldIdentPat &field) override;
virtual void visit (HIR::MatchExpr &expr) override;
+ virtual void visit (HIR::ExternBlock &block) override;
virtual void visit_loop_label (HIR::LoopLabel &label) override;
};
} // namespace Analysis
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc
b/gcc/rust/hir/rust-ast-lower-base.cc
index a1f84c9f0..ffa7a0f39 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -1071,8 +1071,9 @@ ASTLoweringBase::lower_extern_block (AST::ExternBlock
&extern_block)
}
HIR::ExternBlock *hir_extern_block
- = new HIR::ExternBlock (mapping, abi, std::move (extern_items),
- std::move (vis), extern_block.get_inner_attrs (),
+ = new HIR::ExternBlock (mapping, abi, extern_block.has_abi (),
+ std::move (extern_items), std::move (vis),
+ extern_block.get_inner_attrs (),
extern_block.get_outer_attrs (),
extern_block.get_locus ());
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc
b/gcc/rust/hir/tree/rust-hir-item.cc
index 309118cff..d5c9ad154 100644
--- a/gcc/rust/hir/tree/rust-hir-item.cc
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -1001,17 +1001,18 @@ ExternalTypeItem::ExternalTypeItem (ExternalTypeItem
const &other)
{}
ExternBlock::ExternBlock (
- Analysis::NodeMapping mappings, ABI abi,
+ Analysis::NodeMapping mappings, ABI abi, bool explicit_abi,
std::vector<std::unique_ptr<ExternalItem>> extern_items, Visibility vis,
AST::AttrVec inner_attrs, AST::AttrVec outer_attrs, location_t locus)
: VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
WithInnerAttrs (std::move (inner_attrs)), abi (abi),
- extern_items (std::move (extern_items)), locus (locus)
+ explicit_abi (explicit_abi), extern_items (std::move (extern_items)),
+ locus (locus)
{}
ExternBlock::ExternBlock (ExternBlock const &other)
: VisItem (other), WithInnerAttrs (other.inner_attrs), abi (other.abi),
- locus (other.locus)
+ explicit_abi (other.explicit_abi), locus (other.locus)
{
extern_items.reserve (other.extern_items.size ());
for (const auto &e : other.extern_items)
@@ -1023,6 +1024,7 @@ ExternBlock::operator= (ExternBlock const &other)
{
VisItem::operator= (other);
abi = other.abi;
+ explicit_abi = other.explicit_abi;
inner_attrs = other.inner_attrs;
locus = other.locus;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h
b/gcc/rust/hir/tree/rust-hir-item.h
index 588cf5f90..a956e0b53 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2638,6 +2638,7 @@ protected:
class ExternBlock : public VisItem, public WithInnerAttrs
{
ABI abi;
+ bool explicit_abi;
std::vector<std::unique_ptr<ExternalItem>> extern_items;
location_t locus;
@@ -2647,9 +2648,12 @@ public:
// Returns whether extern block has extern items.
bool has_extern_items () const { return !extern_items.empty (); }
+ // Returns whether the extern block was given an explicit ABI string.
+ bool has_abi () const { return explicit_abi; }
+
ABI get_abi () const { return abi; }
- ExternBlock (Analysis::NodeMapping mappings, ABI abi,
+ ExternBlock (Analysis::NodeMapping mappings, ABI abi, bool explicit_abi,
std::vector<std::unique_ptr<ExternalItem>> extern_items,
Visibility vis, AST::AttrVec inner_attrs,
AST::AttrVec outer_attrs, location_t locus);
diff --git a/gcc/testsuite/rust/compile/missing-abi_0.rs
b/gcc/testsuite/rust/compile/missing-abi_0.rs
new file mode 100644
index 000000000..e8c130bd9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/missing-abi_0.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-frust-unused-check-2.0" }
+#![feature(no_core)]
+#![no_core]
+
+extern {
+// { dg-warning "extern declarations without an explicit ABI are deprecated"
"" { target *-*-* } .-1 }
+ fn foo();
+}
+
+extern "C" {
+ fn bar();
+}
base-commit: b63444666d45969e518b67677f522a85cbcaa22e
--
2.54.0