https://gcc.gnu.org/g:5ac41dce35b947f5d1f904b39958ebf6f1b538cf

commit 5ac41dce35b947f5d1f904b39958ebf6f1b538cf
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Fri Apr 4 16:35:13 2025 +0100

    gccrs: Fix segv in unsafe chcker
    
    Trait constants were missing type resolution step, this adds that
    as if it was a normal constant. The unsafe checker was missing a
    null check.
    
    Fixes Rust-GCC#3612
    
    gcc/rust/ChangeLog:
    
            * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): add 
null check
            * hir/tree/rust-hir-item.h: add has_type helper
            * typecheck/rust-hir-trait-resolve.cc 
(TraitItemReference::resolve_item):
            add missing type checking
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-3612.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/checks/errors/rust-unsafe-checker.cc |  5 +++++
 gcc/rust/hir/tree/rust-hir-item.h             |  2 ++
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 21 ++++++++++++++++++++-
 gcc/testsuite/rust/compile/issue-3612.rs      |  7 +++++++
 4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index df775b24d361..41e851e2c190 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -481,9 +481,14 @@ UnsafeChecker::visit (MethodCallExpr &expr)
   TyTy::BaseType *method_type;
   context.lookup_type (expr.get_method_name ().get_mappings ().get_hirid (),
                       &method_type);
+  if (!method_type || !method_type->is<TyTy::FnType> ())
+    return;
 
   auto &fn = static_cast<TyTy::FnType &> (*method_type);
 
+  // FIXME
+  // should probably use the defid lookup instead
+  // tl::optional<HIR::Item *> lookup_defid (DefId id);
   auto method = mappings.lookup_hir_implitem (fn.get_ref ());
   if (!unsafe_context.is_in_context () && method)
     check_unsafe_call (static_cast<Function *> (method->first),
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index f45d743dceb6..41ba38c4f6d7 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2070,6 +2070,8 @@ public:
 
   Identifier get_name () const { return name; }
 
+  bool has_type () const { return expr != nullptr; }
+
   bool has_expr () const { return expr != nullptr; }
 
   Type &get_type ()
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 1492839ce9d3..637fa8a908a7 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -384,7 +384,26 @@ TraitItemReference::resolve_item (HIR::TraitItemType &type)
 void
 TraitItemReference::resolve_item (HIR::TraitItemConst &constant)
 {
-  // TODO
+  TyTy::BaseType *ty = nullptr;
+  if (constant.has_type ())
+    ty = TypeCheckType::Resolve (constant.get_type ());
+
+  TyTy::BaseType *expr = nullptr;
+  if (constant.has_expr ())
+    expr = TypeCheckExpr::Resolve (constant.get_expr ());
+
+  bool have_specified_ty = ty != nullptr && !ty->is<TyTy::ErrorType> ();
+  bool have_expr_ty = expr != nullptr && !expr->is<TyTy::ErrorType> ();
+
+  if (have_specified_ty && have_expr_ty)
+    {
+      coercion_site (constant.get_mappings ().get_hirid (),
+                    TyTy::TyWithLocation (ty,
+                                          constant.get_type ().get_locus ()),
+                    TyTy::TyWithLocation (expr,
+                                          constant.get_expr ().get_locus ()),
+                    constant.get_locus ());
+    }
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/issue-3612.rs 
b/gcc/testsuite/rust/compile/issue-3612.rs
new file mode 100644
index 000000000000..5256d0ad318b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3612.rs
@@ -0,0 +1,7 @@
+trait _St1 {
+    pub const UNDERFLOW: *const u16 = unsafe { [0u16; 
1].as_ptr().offset(isize::MIN) };
+    // { dg-error "no method named .as_ptr. found in the current scope 
.E0599." "" { target *-*-* } .-1 }
+    // { dg-error "failed to resolve receiver in MethodCallExpr" "" { target 
*-*-* } .-2 }
+}
+
+fn main() {}

Reply via email to