https://gcc.gnu.org/g:2c109a2e8a97980b293edb7dc3609556473c7f3d

commit 2c109a2e8a97980b293edb7dc3609556473c7f3d
Author: Zhi Heng <yapz...@gmail.com>
Date:   Thu Apr 3 20:23:46 2025 +0800

    gccrs: Implement typecheck for zero-variant enums
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-tyty.h: Add new `ReprKind` enum to
            `ReprOptions`.
            * typecheck/rust-hir-type-check-base.cc: Handle setting of
            `repr_kind`.
            * typecheck/rust-hir-type-check-item.cc: New check for
            zero-variant enums.
    
    Signed-off-by: Yap Zhi Heng <yapz...@gmail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 34 +++++++++++++++++++++++---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 12 +++++++++
 gcc/rust/typecheck/rust-tyty.h                 | 17 ++++++++++---
 gcc/testsuite/rust/compile/issue-3530-1.rs     |  2 ++
 gcc/testsuite/rust/compile/issue-3530-2.rs     |  2 ++
 5 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index f2310216424c..f066ddc4fd31 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -353,13 +353,27 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
          // manually parsing the string "packed(2)" here.
 
          size_t oparen = inline_option.find ('(', 0);
-         bool is_pack = false, is_align = false;
+         bool is_pack = false, is_align = false, is_c = false,
+              is_integer = false;
          unsigned char value = 1;
 
          if (oparen == std::string::npos)
            {
              is_pack = inline_option.compare ("packed") == 0;
              is_align = inline_option.compare ("align") == 0;
+             is_c = inline_option.compare ("C") == 0;
+             is_integer = (inline_option.compare ("isize") == 0
+                           || inline_option.compare ("i8") == 0
+                           || inline_option.compare ("i16") == 0
+                           || inline_option.compare ("i32") == 0
+                           || inline_option.compare ("i64") == 0
+                           || inline_option.compare ("i128") == 0
+                           || inline_option.compare ("usize") == 0
+                           || inline_option.compare ("u8") == 0
+                           || inline_option.compare ("u16") == 0
+                           || inline_option.compare ("u32") == 0
+                           || inline_option.compare ("u64") == 0
+                           || inline_option.compare ("u128") == 0);
            }
 
          else
@@ -379,9 +393,23 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
            }
 
          if (is_pack)
-           repr.pack = value;
+           {
+             repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
+             repr.pack = value;
+           }
          else if (is_align)
-           repr.align = value;
+           {
+             repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
+             repr.align = value;
+           }
+         else if (is_c)
+           {
+             repr.repr_kind = TyTy::ADTType::ReprKind::C;
+           }
+         else if (is_integer)
+           {
+             repr.repr_kind = TyTy::ADTType::ReprKind::INT;
+           }
 
          delete meta_items;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index f13e3a960d98..7491cb47f5a7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -355,6 +355,18 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
       variants.push_back (field_type);
     }
 
+  // Check for zero-variant enum compatibility before processing repr attribute
+  if (enum_decl.is_zero_variant ())
+    {
+      if (repr.repr_kind == TyTy::ADTType::ReprKind::INT
+         || repr.repr_kind == TyTy::ADTType::ReprKind::C)
+       {
+         rust_error_at (enum_decl.get_locus (),
+                        "unsupported representation for zero-variant enum");
+         return;
+       }
+    }
+
   // get the path
   tl::optional<CanonicalPath> canonical_path;
 
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index dc30d7dd0686..cd7bf24585ee 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -711,12 +711,23 @@ public:
     ENUM
   };
 
+  enum ReprKind
+  {
+    RUST,
+    C,
+    INT,
+    ALIGN,
+    PACKED,
+    // TRANSPARENT,
+    // PACKED,
+    // SIMD,
+    // ...
+  };
+
   // Representation options, specified via attributes e.g. #[repr(packed)]
   struct ReprOptions
   {
-    // bool is_c;
-    // bool is_transparent;
-    //...
+    ReprKind repr_kind = ReprKind::RUST;
 
     // For align and pack: 0 = unspecified. Nonzero = byte alignment.
     // It is an error for both to be nonzero, this should be caught when
diff --git a/gcc/testsuite/rust/compile/issue-3530-1.rs 
b/gcc/testsuite/rust/compile/issue-3530-1.rs
new file mode 100644
index 000000000000..b38b5cd1f3f2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3530-1.rs
@@ -0,0 +1,2 @@
+#[repr(i32)]
+enum NightsWatch {} // { dg-error "unsupported representation for zero-variant 
enum" }
diff --git a/gcc/testsuite/rust/compile/issue-3530-2.rs 
b/gcc/testsuite/rust/compile/issue-3530-2.rs
new file mode 100644
index 000000000000..74327307141f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3530-2.rs
@@ -0,0 +1,2 @@
+#[repr(C)]
+enum NightsWatch {} // { dg-error "unsupported representation for zero-variant 
enum" }

Reply via email to