https://gcc.gnu.org/g:314090971a51037bb77e36b46c7a10652b9e6c3f

commit 314090971a51037bb77e36b46c7a10652b9e6c3f
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Thu Apr 3 15:39:58 2025 +0100

    gccrs: Fix ICE on raw reference
    
    This patch adds support for raw references which enforce the pointer
    type away from a reference type.
    
    Fixes Rust-GCC#3667
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-base.cc 
(HIRCompileBase::address_expression): allow optional type
            * backend/rust-compile-base.h: update prototype
            * backend/rust-compile-expr.cc (CompileExpr::visit): update borrow 
expr
            * backend/rust-compile-extern.h: remove unused debug
            * backend/rust-compile-resolve-path.cc 
(HIRCompileBase::query_compile): update usage
            * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): lower raw ref
            * hir/tree/rust-hir-expr.cc (BorrowExpr::BorrowExpr): add flag for 
raw ref
            * hir/tree/rust-hir-expr.h (class BorrowExpr): add new raw ref field
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): add 
handle for raw ref
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-3667.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/backend/rust-compile-base.cc          |  7 +++++--
 gcc/rust/backend/rust-compile-base.h           |  3 ++-
 gcc/rust/backend/rust-compile-expr.cc          |  3 ++-
 gcc/rust/backend/rust-compile-extern.h         |  6 ------
 gcc/rust/backend/rust-compile-resolve-path.cc  |  4 ++--
 gcc/rust/hir/rust-ast-lower-expr.cc            | 11 ++++-------
 gcc/rust/hir/tree/rust-hir-expr.cc             |  4 ++--
 gcc/rust/hir/tree/rust-hir-expr.h              |  4 +++-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  9 +++++++++
 gcc/testsuite/rust/compile/issue-3667.rs       | 24 ++++++++++++++++++++++++
 10 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index f8c5fa99f795..04e3e75ed7d0 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -549,7 +549,7 @@ HIRCompileBase::mark_addressable (tree exp, location_t 
locus)
 }
 
 tree
-HIRCompileBase::address_expression (tree expr, location_t location)
+HIRCompileBase::address_expression (tree expr, location_t location, tree ptrty)
 {
   if (expr == error_mark_node)
     return error_mark_node;
@@ -557,7 +557,10 @@ HIRCompileBase::address_expression (tree expr, location_t 
location)
   if (!mark_addressable (expr, location))
     return error_mark_node;
 
-  return build_fold_addr_expr_loc (location, expr);
+  if (ptrty == NULL || ptrty == error_mark_node)
+    ptrty = build_pointer_type (TREE_TYPE (expr));
+
+  return build_fold_addr_expr_with_type_loc (location, expr, ptrty);
 }
 
 tree
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 3ec1e2c6dffc..69f565cea2b4 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -29,7 +29,8 @@ class HIRCompileBase
 public:
   virtual ~HIRCompileBase () {}
 
-  static tree address_expression (tree expr, location_t locus);
+  static tree address_expression (tree expr, location_t locus,
+                                 tree ptrty = NULL_TREE);
 
   static tree compile_constant_expr (
     Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 47603484d06c..9dcec64f5b6a 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -905,7 +905,8 @@ CompileExpr::visit (HIR::BorrowExpr &expr)
                                       &tyty))
     return;
 
-  translated = address_expression (main_expr, expr.get_locus ());
+  tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
+  translated = address_expression (main_expr, expr.get_locus (), 
expected_type);
 }
 
 void
diff --git a/gcc/rust/backend/rust-compile-extern.h 
b/gcc/rust/backend/rust-compile-extern.h
index a26ff2fb134b..aa4a0c3d1bcc 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -34,16 +34,10 @@ class CompileExternItem : public HIRCompileBase,
 public:
   static tree compile (HIR::ExternalItem *item, Context *ctx,
                       TyTy::BaseType *concrete = nullptr,
-                      bool is_query_mode = false,
                       location_t ref_locus = UNDEF_LOCATION)
   {
     CompileExternItem compiler (ctx, concrete, ref_locus);
     item->accept_vis (compiler);
-
-    if (is_query_mode && compiler.reference == error_mark_node)
-      rust_internal_error_at (ref_locus, "failed to compile extern item: %s",
-                             item->as_string ().c_str ());
-
     return compiler.reference;
   }
 
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index c966cbf3942c..9783642343c7 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -261,10 +261,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
       HIR::ExternalItem *resolved_extern_item = hir_extern_item->first;
       if (!lookup->has_substitutions_defined ())
        return CompileExternItem::compile (resolved_extern_item, ctx, nullptr,
-                                          true, expr_locus);
+                                          expr_locus);
       else
        return CompileExternItem::compile (resolved_extern_item, ctx, lookup,
-                                          true, expr_locus);
+                                          expr_locus);
     }
   else
     {
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index d0d004e71bfb..575eea6b6248 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -633,9 +633,6 @@ ASTLoweringExpr::visit (AST::ContinueExpr &expr)
 void
 ASTLoweringExpr::visit (AST::BorrowExpr &expr)
 {
-  if (expr.is_raw_borrow ())
-    rust_unreachable ();
-
   HIR::Expr *borrow_lvalue
     = ASTLoweringExpr::translate (expr.get_borrowed_expr ());
 
@@ -646,8 +643,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
 
   auto *borrow_expr
     = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue),
-                          expr.get_mutability (), expr.get_outer_attrs (),
-                          expr.get_locus ());
+                          expr.get_mutability (), expr.is_raw_borrow (),
+                          expr.get_outer_attrs (), expr.get_locus ());
 
   if (expr.get_is_double_borrow ())
     {
@@ -659,8 +656,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr)
       borrow_expr
        = new HIR::BorrowExpr (mapping,
                               std::unique_ptr<HIR::Expr> (borrow_expr),
-                              expr.get_mutability (), expr.get_outer_attrs (),
-                              expr.get_locus ());
+                              expr.get_mutability (), expr.is_raw_borrow (),
+                              expr.get_outer_attrs (), expr.get_locus ());
     }
 
   translated = borrow_expr;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc 
b/gcc/rust/hir/tree/rust-hir-expr.cc
index 2ded789e60b1..bb7ebfbc617b 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -81,10 +81,10 @@ OperatorExpr::operator= (OperatorExpr const &other)
 
 BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings,
                        std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
-                       AST::AttrVec outer_attribs, location_t locus)
+                       bool raw, AST::AttrVec outer_attribs, location_t locus)
   : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
                  std::move (outer_attribs), locus),
-    mut (mut)
+    mut (mut), raw (raw)
 {}
 
 DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings,
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 46039270f729..bd2f9d410c06 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -199,12 +199,13 @@ public:
 class BorrowExpr : public OperatorExpr
 {
   Mutability mut;
+  bool raw;
 
 public:
   std::string as_string () const override;
 
   BorrowExpr (Analysis::NodeMapping mappings,
-             std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
+             std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw,
              AST::AttrVec outer_attribs, location_t locus);
 
   void accept_vis (HIRFullVisitor &vis) override;
@@ -212,6 +213,7 @@ public:
 
   Mutability get_mut () const { return mut; }
   bool is_mut () const { return mut == Mutability::Mut; }
+  bool is_raw_borrow () const { return raw; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 09f078a6001d..00e36ee48a26 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1463,6 +1463,15 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr)
        }
     }
 
+  if (expr.is_raw_borrow ())
+    {
+      infered = new TyTy::PointerType (expr.get_mappings ().get_hirid (),
+                                      TyTy::TyVar (resolved_base->get_ref ()),
+                                      expr.get_mut ());
+
+      return;
+    }
+
   infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
                                     TyTy::TyVar (resolved_base->get_ref ()),
                                     expr.get_mut ());
diff --git a/gcc/testsuite/rust/compile/issue-3667.rs 
b/gcc/testsuite/rust/compile/issue-3667.rs
new file mode 100644
index 000000000000..e72069cf6e4f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3667.rs
@@ -0,0 +1,24 @@
+// { dg-options "-w" }
+#![feature(raw_ref_op)]
+
+const pq1: () = {
+    let mut x = 2;
+    &raw mut x;
+}; //~ mutable reference
+
+static B: () = {
+    let mut x = 2;
+    &raw mut x;
+}; //~ mutable reference
+
+static mut C: () = {
+    let mut x = 2;
+    &raw mut x;
+}; //~ mutable reference
+
+const fn foo() {
+    let mut x = 0;
+    let y = &raw mut x; //~ mutable reference
+}
+
+fn main() {}

Reply via email to