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

Reply via email to