aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Young <wenzhang5800@gmail.com>2021-07-01 15:40:49 +0800
committerThomas Young <wenzhang5800@gmail.com>2021-07-02 21:12:39 +0800
commitd882a0c97f82e9919d6ffe76183b78ed86db1793 (patch)
tree0a47a64c3df8feba4f52686bcc72a139f598a446 /gcc
parent6d7b87f9dd9223da0f3994be5bef5ea9458ebdff (diff)
downloadgcc-d882a0c97f82e9919d6ffe76183b78ed86db1793.zip
gcc-d882a0c97f82e9919d6ffe76183b78ed86db1793.tar.gz
gcc-d882a0c97f82e9919d6ffe76183b78ed86db1793.tar.bz2
detect unused struct field.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/lint/rust-lint-marklive.cc167
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h17
-rw-r--r--gcc/rust/lint/rust-lint-scan-deadcode.h42
-rw-r--r--gcc/testsuite/rust/compile/torture/forward_decl_3.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/generics10.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics13.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics14.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics4.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/generics6.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/generics7.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/impl_block3.rs4
-rw-r--r--gcc/testsuite/rust/compile/torture/methods1.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/methods2.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/methods3.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/nested_struct1.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_base_init_1.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init_3.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init_4.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init_5.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init_6.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/struct_init_7.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/type_infer1.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/type_infer5.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/unused_struct_field.rs9
25 files changed, 207 insertions, 63 deletions
diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
index 5cdb5d4..af871a5 100644
--- a/gcc/rust/lint/rust-lint-marklive.cc
+++ b/gcc/rust/lint/rust-lint-marklive.cc
@@ -92,89 +92,156 @@ void
MarkLive::visit (HIR::PathInExpression &expr)
{
expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
- NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- HirId ref;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- Resolver::Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (seg.get_locus (),
- "unknown reference for resolved name");
- return false;
- }
- ref_node_id = def.parent;
- }
- else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
- {
- return false;
- }
-
- if (!mappings->lookup_node_to_hir (seg.get_mappings ().get_crate_num (),
- ref_node_id, &ref))
- {
- rust_error_at (seg.get_locus (), "reverse lookup failure");
- return false;
- }
- if (scannedSymbols.find (ref) == scannedSymbols.end ())
- {
- worklist.push_back (ref);
- }
- liveSymbols.emplace (ref);
- return true;
+ return visit_path_segment (seg);
});
}
void
-MarkLive::visit (HIR::IdentifierExpr &expr)
+MarkLive::visit (HIR::MethodCallExpr &expr)
{
+ expr.get_receiver ()->accept_vis (*this);
+ visit_path_segment (expr.get_method_name ());
+ expr.iterate_params ([&] (HIR::Expr *param) -> bool {
+ param->accept_vis (*this);
+ return true;
+ });
+
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (),
+ expr.as_string ());
- // then lookup the reference_node_id
+ // node back to HIR
+ HirId ref;
+ node_id_to_hir_id (expr.get_mappings ().get_crate_num (), ref_node_id, ref,
+ expr.get_locus ());
+ mark_hir_id (ref);
+}
+
+bool
+MarkLive::visit_path_segment (HIR::PathExprSegment seg)
+{
+ NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
NodeId ref_node_id = UNKNOWN_NODEID;
if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
Resolver::Definition def;
if (!resolver->lookup_definition (ref_node_id, &def))
{
- rust_error_at (expr.get_locus (),
+ rust_error_at (seg.get_locus (),
"unknown reference for resolved name");
- return;
+ return false;
}
ref_node_id = def.parent;
}
else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
{
- rust_error_at (expr.get_locus (),
- "Failed to lookup type reference for node: %s",
- expr.as_string ().c_str ());
- return;
+ return false;
}
+ HirId ref;
+ node_id_to_hir_id (seg.get_mappings ().get_crate_num (), ref_node_id, ref,
+ seg.get_locus ());
+ mark_hir_id (ref);
+ return true;
+}
- if (ref_node_id == UNKNOWN_NODEID)
+void
+MarkLive::visit (HIR::FieldAccessExpr &expr)
+{
+ // visit receiver at first
+ expr.get_receiver_expr ()->accept_vis (*this);
+
+ // resolve the receiver back to ADT type
+ TyTy::BaseType *receiver = nullptr;
+ if (!tyctx->lookup_type (
+ expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
+ {
+ rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+ "unresolved type for receiver");
+ }
+ rust_assert (receiver->get_kind () == TyTy::TypeKind::ADT);
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (receiver);
+
+ // get the field index
+ size_t index = 0;
+ adt->get_field (expr.get_field_name (), &index);
+ if (index >= adt->num_fields ())
{
- rust_error_at (expr.get_locus (), "unresolved node: %s",
- expr.as_string ().c_str ());
+ rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+ "cannot access struct %s by index: %ld",
+ adt->get_name ().c_str (), index);
return;
}
+ // get the field hir id
+ HirId field_id = adt->get_field (index)->get_ref ();
+ mark_hir_id (field_id);
+}
+
+void
+MarkLive::visit (HIR::TupleIndexExpr &expr)
+{
+ // TODO: unused tuple field detection
+ expr.get_tuple_expr ()->accept_vis (*this);
+}
+
+void
+MarkLive::visit (HIR::IdentifierExpr &expr)
+{
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (),
+ expr.as_string ());
// node back to HIR
HirId ref;
- if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref))
+ node_id_to_hir_id (expr.get_mappings ().get_crate_num (), ref_node_id, ref,
+ expr.get_locus ());
+ mark_hir_id (ref);
+}
+
+void
+MarkLive::mark_hir_id (HirId id)
+{
+ if (scannedSymbols.find (id) == scannedSymbols.end ())
+ {
+ worklist.push_back (id);
+ }
+ liveSymbols.emplace (id);
+}
+
+void
+MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id,
+ Location locus, const std::string &node_name)
+{
+ if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- rust_error_at (expr.get_locus (), "reverse lookup failure");
+ // these ref_node_ids will resolve to a pattern declaration but we are
+ // interested in the definition that this refers to get the parent id
+ Resolver::Definition def;
+ if (!resolver->lookup_definition (ref_node_id, &def))
+ {
+ rust_error_at (locus, "unknown reference for resolved name");
+ return;
+ }
+ ref_node_id = def.parent;
+ }
+ else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+ {
+ rust_error_at (locus, "Failed to lookup type reference for node: %s",
+ node_name.c_str ());
return;
}
+}
- if (scannedSymbols.find (ref) == scannedSymbols.end ())
+void
+MarkLive::node_id_to_hir_id (CrateNum crateNum, NodeId ref_node_id, HirId &ref,
+ Location locus)
+{
+ if (!mappings->lookup_node_to_hir (crateNum, ref_node_id, &ref))
{
- worklist.push_back (ref);
+ rust_error_at (locus, "reverse lookup failure");
+ return;
}
- liveSymbols.emplace (ref);
}
} // namespace Analysis
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index 2db5294..72274d0 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -38,6 +38,9 @@ public:
void visit (HIR::PathInExpression &expr) override;
void visit (HIR::IdentifierExpr &expr) override;
+ void visit (HIR::FieldAccessExpr &expr) override;
+ void visit (HIR::TupleIndexExpr &expr) override;
+ void visit (HIR::MethodCallExpr &expr) override;
void visit (HIR::BorrowExpr &expr) override
{
@@ -156,6 +159,10 @@ public:
void visit (HIR::CallExpr &expr) override
{
expr.get_fnexpr ()->accept_vis (*this);
+ expr.iterate_params ([&] (HIR::Expr *expr) -> bool {
+ expr->accept_vis (*this);
+ return true;
+ });
}
void visit (HIR::ArithmeticOrLogicalExpr &expr) override
@@ -226,9 +233,17 @@ private:
std::set<HirId> scannedSymbols;
Analysis::Mappings *mappings;
Resolver::Resolver *resolver;
+ Resolver::TypeCheckContext *tyctx;
MarkLive (std::vector<HirId> worklist)
: worklist (worklist), mappings (Analysis::Mappings::get ()),
- resolver (Resolver::Resolver::get ()){};
+ resolver (Resolver::Resolver::get ()),
+ tyctx (Resolver::TypeCheckContext::get ()){};
+
+ void mark_hir_id (HirId);
+ bool visit_path_segment (HIR::PathExprSegment);
+ void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id,
+ Location locus, const std::string &node_name);
+ void node_id_to_hir_id (CrateNum, NodeId, HirId &, Location);
};
} // namespace Analysis
diff --git a/gcc/rust/lint/rust-lint-scan-deadcode.h b/gcc/rust/lint/rust-lint-scan-deadcode.h
index 1dee18a..ad48a47 100644
--- a/gcc/rust/lint/rust-lint-scan-deadcode.h
+++ b/gcc/rust/lint/rust-lint-scan-deadcode.h
@@ -46,15 +46,37 @@ public:
void visit (HIR::Function &function) override
{
HirId hirId = function.get_mappings ().get_hirid ();
- warning (hirId, function.get_locus (), "function",
- function.get_function_name (), "used");
+ if (should_warn (hirId))
+ {
+ rust_warning_at (function.get_locus (), 0, "%s is never %s: %<%s%>",
+ "function", "used",
+ function.get_function_name ().c_str ());
+ }
}
void visit (HIR::StructStruct &stct) override
{
HirId hirId = stct.get_mappings ().get_hirid ();
- warning (hirId, stct.get_locus (), "struct", stct.get_identifier (),
- "constructed");
+ if (should_warn (hirId))
+ {
+ rust_warning_at (stct.get_locus (), 0, "%s is never %s: %<%s%>",
+ "struct", "constructed",
+ stct.get_identifier ().c_str ());
+ }
+ else
+ {
+ // only warn the unused fields when in unwarned struct.
+ stct.iterate ([&] (HIR::StructField &field) -> bool {
+ HirId field_hir_id = field.get_mappings ().get_hirid ();
+ if (should_warn (field_hir_id))
+ {
+ rust_warning_at (field.get_locus (), 0, "%s is never %s: %<%s%>",
+ "field", "read",
+ field.get_field_name ().c_str ());
+ }
+ return true;
+ });
+ }
}
private:
@@ -64,15 +86,11 @@ private:
ScanDeadcode (std::set<HirId> &live_symbols)
: live_symbols (live_symbols), resolver (Resolver::Resolver::get ()){};
- void warning (HirId hirId, Location loc, const std::string &span,
- const std::string &name, const std::string &participle) const
+ bool should_warn (HirId hirId)
{
- if (live_symbols.find (hirId) == live_symbols.end ())
- {
- rust_warning_at (loc, 0, "%s is never %s: %<%s%>", span.c_str (),
- participle.c_str (), name.c_str ());
- return;
- }
+ // TODO: There are more condition to check if should warn, i.e visibility,
+ // attributes.
+ return live_symbols.find (hirId) == live_symbols.end ();
}
};
diff --git a/gcc/testsuite/rust/compile/torture/forward_decl_3.rs b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs
index 0028ca5..9256df5 100644
--- a/gcc/testsuite/rust/compile/torture/forward_decl_3.rs
+++ b/gcc/testsuite/rust/compile/torture/forward_decl_3.rs
@@ -5,5 +5,7 @@ fn main() {
struct Foo {
one: i32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
two: i32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
diff --git a/gcc/testsuite/rust/compile/torture/generics10.rs b/gcc/testsuite/rust/compile/torture/generics10.rs
index 9526149..8473d49 100644
--- a/gcc/testsuite/rust/compile/torture/generics10.rs
+++ b/gcc/testsuite/rust/compile/torture/generics10.rs
@@ -3,6 +3,7 @@ struct Foo<T>(T);
struct Bar<T> {
a: Foo<T>,
b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn test<T>(a: Bar<T>) -> Foo<T> {
diff --git a/gcc/testsuite/rust/compile/torture/generics13.rs b/gcc/testsuite/rust/compile/torture/generics13.rs
index 5c8795d..e924ab4 100644
--- a/gcc/testsuite/rust/compile/torture/generics13.rs
+++ b/gcc/testsuite/rust/compile/torture/generics13.rs
@@ -1,5 +1,6 @@
struct Foo<A> {
a: A,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
struct GenericStruct<T> {
diff --git a/gcc/testsuite/rust/compile/torture/generics14.rs b/gcc/testsuite/rust/compile/torture/generics14.rs
index aa8fbf2..0d2e390 100644
--- a/gcc/testsuite/rust/compile/torture/generics14.rs
+++ b/gcc/testsuite/rust/compile/torture/generics14.rs
@@ -1,5 +1,6 @@
struct Foo<A> {
a: A,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Foo<isize> {
diff --git a/gcc/testsuite/rust/compile/torture/generics4.rs b/gcc/testsuite/rust/compile/torture/generics4.rs
index 3ae3861..915cc49 100644
--- a/gcc/testsuite/rust/compile/torture/generics4.rs
+++ b/gcc/testsuite/rust/compile/torture/generics4.rs
@@ -1,6 +1,8 @@
struct Foo<T> {
a: T,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn test<T>(a: T) -> Foo<T> {
diff --git a/gcc/testsuite/rust/compile/torture/generics6.rs b/gcc/testsuite/rust/compile/torture/generics6.rs
index 283a118..5456b6d 100644
--- a/gcc/testsuite/rust/compile/torture/generics6.rs
+++ b/gcc/testsuite/rust/compile/torture/generics6.rs
@@ -3,6 +3,7 @@ struct Foo<T>(T);
struct Bar<T> {
a: Foo<T>,
b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/generics7.rs b/gcc/testsuite/rust/compile/torture/generics7.rs
index 2e89ce1..e8e5ca6 100644
--- a/gcc/testsuite/rust/compile/torture/generics7.rs
+++ b/gcc/testsuite/rust/compile/torture/generics7.rs
@@ -3,6 +3,7 @@ struct Foo<T>(T);
struct Bar {
a: Foo<i32>,
b: bool,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/impl_block3.rs b/gcc/testsuite/rust/compile/torture/impl_block3.rs
index 78ec459..22ce19f 100644
--- a/gcc/testsuite/rust/compile/torture/impl_block3.rs
+++ b/gcc/testsuite/rust/compile/torture/impl_block3.rs
@@ -1,6 +1,8 @@
struct Point {
x: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Point {
@@ -15,7 +17,9 @@ impl Point {
struct Rectangle {
p1: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
p2: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Rectangle {
diff --git a/gcc/testsuite/rust/compile/torture/methods1.rs b/gcc/testsuite/rust/compile/torture/methods1.rs
index df3663f..a8e384d 100644
--- a/gcc/testsuite/rust/compile/torture/methods1.rs
+++ b/gcc/testsuite/rust/compile/torture/methods1.rs
@@ -1,6 +1,7 @@
struct Point {
x: f64,
y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Point {
diff --git a/gcc/testsuite/rust/compile/torture/methods2.rs b/gcc/testsuite/rust/compile/torture/methods2.rs
index 72ba29c..d63211b 100644
--- a/gcc/testsuite/rust/compile/torture/methods2.rs
+++ b/gcc/testsuite/rust/compile/torture/methods2.rs
@@ -1,6 +1,7 @@
struct Point {
x: f64,
y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Point {
diff --git a/gcc/testsuite/rust/compile/torture/methods3.rs b/gcc/testsuite/rust/compile/torture/methods3.rs
index b0cb78f..55426f4 100644
--- a/gcc/testsuite/rust/compile/torture/methods3.rs
+++ b/gcc/testsuite/rust/compile/torture/methods3.rs
@@ -1,6 +1,7 @@
struct Point {
x: f64,
y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
impl Point {
diff --git a/gcc/testsuite/rust/compile/torture/nested_struct1.rs b/gcc/testsuite/rust/compile/torture/nested_struct1.rs
index 56ce053..2bd5ead 100644
--- a/gcc/testsuite/rust/compile/torture/nested_struct1.rs
+++ b/gcc/testsuite/rust/compile/torture/nested_struct1.rs
@@ -1,11 +1,13 @@
struct Point {
x: f64,
y: f64,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
struct Rectangle {
p1: Point,
p2: Point,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs
index 3c0b24a..39dc61a 100644
--- a/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_base_init_1.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn foo() -> Foo {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init.rs b/gcc/testsuite/rust/compile/torture/struct_init.rs
index be0b963..1926f73 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init.rs
@@ -1,6 +1,8 @@
struct Foo {
one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
two: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_3.rs b/gcc/testsuite/rust/compile/torture/struct_init_3.rs
index 5e52d09..1398f8e 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init_3.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init_3.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_4.rs b/gcc/testsuite/rust/compile/torture/struct_init_4.rs
index 57b6bd4..d4b2de8 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init_4.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init_4.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_5.rs b/gcc/testsuite/rust/compile/torture/struct_init_5.rs
index 891f645..e7f9d16 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init_5.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init_5.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_6.rs b/gcc/testsuite/rust/compile/torture/struct_init_6.rs
index e7f8a12..9a6241a 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init_6.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init_6.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/struct_init_7.rs b/gcc/testsuite/rust/compile/torture/struct_init_7.rs
index a8c8050..a73d642 100644
--- a/gcc/testsuite/rust/compile/torture/struct_init_7.rs
+++ b/gcc/testsuite/rust/compile/torture/struct_init_7.rs
@@ -1,6 +1,8 @@
struct Foo {
a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
b: f32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/type_infer1.rs b/gcc/testsuite/rust/compile/torture/type_infer1.rs
index b6502b5..3fee728 100644
--- a/gcc/testsuite/rust/compile/torture/type_infer1.rs
+++ b/gcc/testsuite/rust/compile/torture/type_infer1.rs
@@ -1,6 +1,8 @@
struct Foo {
one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
two: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn test(x: i32) -> i32 {
diff --git a/gcc/testsuite/rust/compile/torture/type_infer5.rs b/gcc/testsuite/rust/compile/torture/type_infer5.rs
index 1bccb4c..2c2602a 100644
--- a/gcc/testsuite/rust/compile/torture/type_infer5.rs
+++ b/gcc/testsuite/rust/compile/torture/type_infer5.rs
@@ -1,6 +1,7 @@
struct Foo {
a: i32,
b: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
}
fn main() {
diff --git a/gcc/testsuite/rust/compile/torture/unused_struct_field.rs b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs
new file mode 100644
index 0000000..429b303
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/unused_struct_field.rs
@@ -0,0 +1,9 @@
+struct Foo {
+ one: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+ two: i32
+}
+fn main() {
+ let _a = Foo {one: 1, two: 2};
+ let _b = _a.two;
+} \ No newline at end of file