From: Wesley Lewis <[email protected]>
structs with Derive CoercePointee need to have minimum 1 field. On error we
return a E0802.
Fixes Rust-GCC/gccrs#4916
gcc/rust/ChangeLog:
* expand/rust-derive-coerce-pointee.cc
(DeriveCoercePointee::validate_number_of_fields): New.
(DeriveCoercePointee::go): Call validate_number_of_fields.
* expand/rust-derive-coerce-pointee.h
(DeriveCoercePointee::validate_number_of_fields): Declare.
gcc/testsuite/ChangeLog:
* rust/compile/derive-coerce-pointee5.rs: New test.
Signed-off-by: Wesley Lewis <[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/d4af266c8c7c4d049fce2fb69201f8f60057782d
The commit has been mentioned in the following issue(s):
- Rust-GCC/gccrs#4916: https://github.com/Rust-GCC/gccrs/issues/4916
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4950
gcc/rust/expand/rust-derive-coerce-pointee.cc | 36 +++++++++++++++++--
gcc/rust/expand/rust-derive-coerce-pointee.h | 1 +
.../rust/compile/derive-coerce-pointee5.rs | 23 ++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/derive-coerce-pointee5.rs
diff --git a/gcc/rust/expand/rust-derive-coerce-pointee.cc
b/gcc/rust/expand/rust-derive-coerce-pointee.cc
index 50386b48f..b2c71d2c8 100644
--- a/gcc/rust/expand/rust-derive-coerce-pointee.cc
+++ b/gcc/rust/expand/rust-derive-coerce-pointee.cc
@@ -18,9 +18,10 @@
#include "rust-attribute-values.h"
#include "rust-derive-coerce-pointee.h"
-#include "rust-session-manager.h"
-#include "rust-feature.h"
+#include "rust-diagnostics.h"
#include "rust-feature-store.h"
+#include "rust-feature.h"
+#include "rust-session-manager.h"
namespace Rust {
namespace AST {
@@ -34,6 +35,7 @@ std::unique_ptr<AST::Item>
DeriveCoercePointee::go (Item &item)
{
validate_repr_transparent (item);
+ validate_number_of_fields (item);
Features::EarlyFeatureGateStore::get ().add (
Feature::Name::DERIVE_COERCE_POINTEE,
Error (loc, "use of unstable library feature %<derive_coerce_pointee%>"));
@@ -103,5 +105,35 @@ DeriveCoercePointee::validate_repr_transparent (const Item
&item)
"repr(transparent) layout");
return false;
}
+
+// Structs or Tuples with CoercePointee must have minimum of one field else
+// compile time error
+bool
+DeriveCoercePointee::validate_number_of_fields (const Item &item)
+{
+ size_t field_count = 0;
+
+ if (item.get_item_kind () == Item::Kind::Struct)
+ {
+ auto *struct_item = static_cast<const StructStruct *> (&item);
+ field_count = struct_item->get_fields ().size ();
+ }
+ else
+ {
+ rust_error_at (item.get_locus (), ErrorCode::E0802,
+ "%<CoercePointee%> can only be derived on structs with "
+ "#[repr(transparent)]");
+ return false;
+ }
+
+ if (field_count == 0)
+ {
+ rust_error_at (item.get_locus (), ErrorCode::E0802,
+ "%<CoercePointee%> can only be derived on a struct "
+ "with at least one field");
+ return false;
+ }
+ return true;
+}
} // namespace AST
} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-coerce-pointee.h
b/gcc/rust/expand/rust-derive-coerce-pointee.h
index b18704782..b3f4e5239 100644
--- a/gcc/rust/expand/rust-derive-coerce-pointee.h
+++ b/gcc/rust/expand/rust-derive-coerce-pointee.h
@@ -32,6 +32,7 @@ public:
std::unique_ptr<Item> go (Item &item);
bool validate_repr_transparent (const Item &item);
+ bool validate_number_of_fields (const Item &item);
private:
virtual void visit_struct (StructStruct &item) override {}
virtual void visit_tuple (TupleStruct &item) override {}
diff --git a/gcc/testsuite/rust/compile/derive-coerce-pointee5.rs
b/gcc/testsuite/rust/compile/derive-coerce-pointee5.rs
new file mode 100644
index 000000000..5010ad0a8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-coerce-pointee5.rs
@@ -0,0 +1,23 @@
+// { dg-additional-options "-frust-compat-version=1.84" }
+
+// check for validating structs with derive CoercePointee having minimum 1
field.
+
+#![feature(no_core)]
+#![feature(lang_items)]
+#![feature(derive_coerce_pointee)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[repr(transparent)]
+#[derive(CoercePointee)] // { dg-warning "no effect" }
+// { dg-error "only be derived on a struct with at least one field" "" {
target *-*-* } .+1 }
+struct Bad<T: ?Sized> {}
+
+#[repr(transparent)]
+#[derive(CoercePointee)] // { dg-warning "no effect" }
+// { dg-error "only be derived on structs with .*repr.*transparent" "" {
target *-*-* } .+1 }
+enum SomeEnum<T: ?Sized> {
+ A(*const T),
+}
--
2.56.0