From: Lucas Ly Ba <[email protected]>
Warn on a double arithmetic negation such as `- -x`, which is likely a
mistake (Rust has no `--` operator).
gcc/rust/ChangeLog:
* 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/double-negations_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/d273e1b6a25261b49983fc58471da3245b96928f
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/4643
.../lints/unused/rust-unused-checker.cc | 31 +++++++++++++++++++
.../checks/lints/unused/rust-unused-checker.h | 1 +
.../rust/compile/double-negations_0.rs | 17 ++++++++++
3 files changed, 49 insertions(+)
create mode 100644 gcc/testsuite/rust/compile/double-negations_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 553a2f71e..1c128f519 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc
@@ -378,5 +378,36 @@ UnusedChecker::visit (HIR::BorrowExpr &expr)
walk (expr);
}
+namespace {
+// Probe whether an expression is itself an arithmetic negation, without
+// recursing (so it only inspects the node it is dispatched on). Used to detect
+// `- -x` for the double_negations lint, since gccrs builds with -fno-rtti and
+// HIR has no down-cast helper.
+class NegationProbe : public HIR::HIRFullVisitorBase
+{
+public:
+ bool is_negation = false;
+ using HIR::HIRFullVisitorBase::visit;
+ void visit (HIR::NegationExpr &expr) override
+ {
+ is_negation = expr.get_expr_type () == HIR::NegationExpr::ExprType::NEGATE;
+ }
+};
+} // namespace
+
+void
+UnusedChecker::visit (HIR::NegationExpr &expr)
+{
+ if (expr.get_expr_type () == HIR::NegationExpr::ExprType::NEGATE)
+ {
+ NegationProbe probe;
+ expr.get_expr ().accept_vis (probe);
+ if (probe.is_negation)
+ rust_warning_at (expr.get_locus (), OPT_Wunused,
+ "use of a double negation");
+ }
+ walk (expr);
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.h
b/gcc/rust/checks/lints/unused/rust-unused-checker.h
index 161f59b8a..659087a57 100644
--- a/gcc/rust/checks/lints/unused/rust-unused-checker.h
+++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h
@@ -53,6 +53,7 @@ private:
virtual void visit (HIR::ExternBlock &block) override;
virtual void visit (HIR::LetStmt &stmt) override;
virtual void visit (HIR::BorrowExpr &expr) override;
+ virtual void visit (HIR::NegationExpr &expr) override;
virtual void visit_loop_label (HIR::LoopLabel &label) override;
};
} // namespace Analysis
diff --git a/gcc/testsuite/rust/compile/double-negations_0.rs
b/gcc/testsuite/rust/compile/double-negations_0.rs
new file mode 100644
index 000000000..47854e963
--- /dev/null
+++ b/gcc/testsuite/rust/compile/double-negations_0.rs
@@ -0,0 +1,17 @@
+// { dg-additional-options "-frust-unused-check-2.0" }
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "neg"]
+pub trait Neg {
+ type Output;
+ fn neg(self) -> Self::Output;
+}
+
+pub fn f(x: i32) -> i32 {
+ - -x
+// { dg-warning "double negation" "" { target *-*-* } .-1 }
+}
base-commit: 840bac99462208bc849a44fd36bb36cf04f711a5
--
2.54.0