[COMMITTED 043/141] gccrs: lang-items: Add structural_{peq, teq}

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

These lang items are used when deriving Eq and PartialEq, and will be checked 
when compiling pattern matching.

gcc/rust/ChangeLog:

* util/rust-lang-item.cc: New items.
* util/rust-lang-item.h: Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/structural-eq-peq.rs: New test.
---
 gcc/rust/util/rust-lang-item.cc | 3 +++
 gcc/rust/util/rust-lang-item.h  | 3 +++
 gcc/testsuite/rust/compile/structural-eq-peq.rs | 9 +
 3 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/structural-eq-peq.rs

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 145054ff9d7..92a76613b61 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -112,6 +112,9 @@ const BiMap 
Rust::LangItem::lang_items = {{
   {"from_ok", Kind::TRY_FROM_OK},
 
   {"from", Kind::FROM_FROM},
+
+  {"structural_peq", Kind::STRUCTURAL_PEQ},
+  {"structural_teq", Kind::STRUCTURAL_TEQ},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index f30b93609b5..29b972702bd 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -144,6 +144,9 @@ public:
 
 // NOTE: This is not a lang item in later versions of Rust
 FROM_FROM,
+
+STRUCTURAL_PEQ,
+STRUCTURAL_TEQ,
   };
 
   static const BiMap lang_items;
diff --git a/gcc/testsuite/rust/compile/structural-eq-peq.rs 
b/gcc/testsuite/rust/compile/structural-eq-peq.rs
new file mode 100644
index 000..d04c295037f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/structural-eq-peq.rs
@@ -0,0 +1,9 @@
+#[lang = "structural_peq"]
+pub trait StructuralPartialEq {
+// Empty.
+}
+
+#[lang = "structural_teq"]
+pub trait StructuralEq {
+// Empty.
+}
-- 
2.45.2



[COMMITTED 109/141] gccrs: ast: Add base for desugaring try expressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* Make-lang.in: Compile it.
* ast/rust-desugar-question-mark.cc: New file.
* ast/rust-desugar-question-mark.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/try-expr1.rs: New test.
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/ast/rust-desugar-question-mark.cc | 167 +
 gcc/rust/ast/rust-desugar-question-mark.h  |  79 ++
 gcc/testsuite/rust/compile/try-expr1.rs|  84 +++
 4 files changed, 331 insertions(+)
 create mode 100644 gcc/rust/ast/rust-desugar-question-mark.cc
 create mode 100644 gcc/rust/ast/rust-desugar-question-mark.h
 create mode 100644 gcc/testsuite/rust/compile/try-expr1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 3e44b12c3d1..749c1123e05 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -239,6 +239,7 @@ GRS_OBJS = \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
rust/rust-desugar-for-loops.o \
+   rust/rust-desugar-question-mark.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc 
b/gcc/rust/ast/rust-desugar-question-mark.cc
new file mode 100644
index 000..4d2933b1bee
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -0,0 +1,167 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-desugar-question-mark.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace AST {
+
+DesugarQuestionMark::DesugarQuestionMark () {}
+
+void
+DesugarQuestionMark::go (AST::Crate &crate)
+{
+  DesugarQuestionMark::visit (crate);
+}
+
+void
+DesugarQuestionMark::visit (ExprStmt &stmt)
+{
+  if (stmt.get_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
+desugar_and_replace (stmt.get_expr_ptr ());
+
+  DefaultASTVisitor::visit (stmt);
+}
+
+void
+DesugarQuestionMark::visit (CallExpr &call)
+{
+  if (call.get_function_expr ().get_expr_kind ()
+  == Expr::Kind::ErrorPropagation)
+desugar_and_replace (call.get_function_expr_ptr ());
+
+  for (auto &arg : call.get_params ())
+if (arg->get_expr_kind () == Expr::Kind::ErrorPropagation)
+  desugar_and_replace (arg);
+
+  DefaultASTVisitor::visit (call);
+}
+
+void
+DesugarQuestionMark::visit (LetStmt &stmt)
+{
+  if (stmt.has_init_expr ()
+  && stmt.get_init_expr ().get_expr_kind () == 
Expr::Kind::ErrorPropagation)
+desugar_and_replace (stmt.get_init_expr_ptr ());
+
+  DefaultASTVisitor::visit (stmt);
+}
+
+MatchArm
+make_match_arm (std::unique_ptr &&pattern)
+{
+  auto loc = pattern->get_locus ();
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (pattern));
+
+  return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+ok_case (Builder &builder)
+{
+  auto val = builder.identifier_pattern ("val");
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (val));
+
+  auto pattern_item = std::unique_ptr (
+new TupleStructItemsNoRange (std::move (patterns)));
+  auto pattern = std::unique_ptr (new TupleStructPattern (
+builder.path_in_expression (LangItem::Kind::RESULT_OK),
+std::move (pattern_item)));
+
+  auto arm = make_match_arm (std::move (pattern));
+
+  auto ret_val = builder.identifier ("val");
+
+  return MatchCase (std::move (arm), std::move (ret_val));
+}
+
+MatchCase
+err_case (Builder &builder)
+{
+  auto val = builder.identifier_pattern ("err");
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (val));
+
+  auto pattern_item = std::unique_ptr (
+new TupleStructItemsNoRange (std::move (patterns)));
+  auto pattern = std::unique_ptr (new TupleStructPattern (
+builder.path_in_expression (LangItem::Kind::RESULT_ERR),
+std::move (pattern_item)));
+
+  auto arm = make_match_arm (std::move (pattern));
+
+  auto try_from_err = std::make_unique (
+builder.path_in_expression (LangItem::Kind::TRY_FROM_ERROR));
+  auto from_from = std::make_unique (
+builder.path_in_expression (LangItem::Kind::FROM_FROM));
+
+  auto early_return = builder.return_expr (
+builder.call (std::move (try_from_err),
+ builder.call (std::move (from_from),
+   builder.identifier ("err";
+
+  return Ma

[COMMITTED 041/141] gccrs: Fix an issue with ForeverStack::dfs_rib

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx
(ForeverStack::dfs_rib): Fix const implementation.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 1c83f6bda61..d0d74217b61 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -638,9 +638,8 @@ tl::optional
 ForeverStack::dfs_rib (const ForeverStack::Node &starting_point,
  NodeId to_find) const
 {
-  return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
-return x.rib;
-  });
+  return dfs_node (starting_point, to_find)
+.map ([] (const Node &x) -> const Rib & { return x.rib; });
 }
 
 template 
-- 
2.45.2



[COMMITTED 074/141] gccrs: add diagnostic for E0229 no associated type arguments allowed here

2025-03-24 Thread arthur . cohen
From: Philip Herron 

It seems bounds in qualified paths are not allowed to specify associated
type bindings because its going to be associated with the impl block
anyway.

Fixes Rust-GCC#2369

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.h: add flag
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
* typecheck/rust-tyty-bounds.cc: new diagnostic

gcc/testsuite/ChangeLog:

* rust/compile/issue-2369.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-base.h |  3 ++-
 .../typecheck/rust-hir-type-check-type.cc |  6 --
 gcc/rust/typecheck/rust-tyty-bounds.cc| 17 ++-
 gcc/testsuite/rust/compile/issue-2369.rs  | 21 +++
 4 files changed, 43 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2369.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h 
b/gcc/rust/typecheck/rust-hir-type-check-base.h
index e720b947916..8a1bf6f4cb3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -40,7 +40,8 @@ protected:
   TyTy::TypeBoundPredicate get_predicate_from_bound (
 HIR::TypePath &path,
 tl::optional> associated_self,
-BoundPolarity polarity = BoundPolarity::RegularBound);
+BoundPolarity polarity = BoundPolarity::RegularBound,
+bool is_qualified_type = false);
 
   bool check_for_unconstrained (
 const std::vector ¶ms_to_constrain,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 327cbb010a4..6a09772d023 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -193,8 +193,10 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
 return;
 
   // get the predicate for the bound
-  auto specified_bound = get_predicate_from_bound (qual_path_type.get_trait (),
-  qual_path_type.get_type ());
+  auto specified_bound
+= get_predicate_from_bound (qual_path_type.get_trait (),
+   qual_path_type.get_type (),
+   BoundPolarity::RegularBound, true);
   if (specified_bound.is_error ())
 return;
 
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 3e42427e2ec..fc35abb6ec4 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -196,7 +196,7 @@ TyTy::TypeBoundPredicate
 TypeCheckBase::get_predicate_from_bound (
   HIR::TypePath &type_path,
   tl::optional> associated_self,
-  BoundPolarity polarity)
+  BoundPolarity polarity, bool is_qualified_type_path)
 {
   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
   bool already_resolved
@@ -222,6 +222,21 @@ TypeCheckBase::get_predicate_from_bound (
if (final_generic_seg.has_generic_args ())
  {
args = final_generic_seg.get_generic_args ();
+   if (args.get_binding_args ().size () > 0
+   && associated_self.has_value () && is_qualified_type_path)
+ {
+   auto &binding_args = args.get_binding_args ();
+
+   rich_location r (line_table, args.get_locus ());
+   for (auto it = binding_args.begin (); it != binding_args.end ();
+it++)
+ {
+   auto &arg = *it;
+   r.add_fixit_remove (arg.get_locus ());
+ }
+   rust_error_at (r, ErrorCode::E0229,
+  "associated type bindings are not allowed here");
+ }
  }
   }
   break;
diff --git a/gcc/testsuite/rust/compile/issue-2369.rs 
b/gcc/testsuite/rust/compile/issue-2369.rs
new file mode 100644
index 000..9475aef9d71
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2369.rs
@@ -0,0 +1,21 @@
+#[lang = "sized"]
+trait Sized {}
+
+fn main() {
+pub trait Foo {
+type A;
+fn boo(&self) -> ::A;
+}
+
+struct Bar;
+
+impl Foo for isize {
+type A = usize;
+fn boo(&self) -> usize {
+42
+}
+}
+
+fn baz(x: &>::A) {}
+// { dg-error "associated type bindings are not allowed here .E0229." "" { 
target *-*-* } .-1 }
+}
-- 
2.45.2



[COMMITTED 042/141] gccrs: nr2.0: late: Add proper handling for lang item PathInExpressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Special case 
lang item paths.
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index a3b8e6a515f..7c414c47bc9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -254,8 +254,14 @@ Late::visit (AST::PathInExpression &expr)
   // TODO: How do we have a nice error with `can't capture dynamic environment
   // in a function item` error here?
   // do we emit it in `get`?
+
   if (expr.is_lang_item ())
-return;
+{
+  ctx.map_usage (Usage (expr.get_node_id ()),
+Definition (Analysis::Mappings::get ().get_lang_item_node (
+  expr.get_lang_item (;
+  return;
+}
 
   auto resolved
 = ctx.values.resolve_path (expr.get_segments ()).or_else ([&] () {
-- 
2.45.2



[COMMITTED 087/141] gccrs: ast-builder: Improve function generation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::block): Change return type.
(Builder::loop): Use new APIs.
* ast/rust-ast-builder.h: Change return type of block functions.
---
 gcc/rust/ast/rust-ast-builder.cc | 22 +++---
 gcc/rust/ast/rust-ast-builder.h  | 12 ++--
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 369f5a44630..f59ff19d621 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -279,23 +279,25 @@ Builder::path_in_expression (LangItem::Kind lang_item) 
const
   return PathInExpression (lang_item, {}, loc);
 }
 
-std::unique_ptr
-Builder::block (std::unique_ptr &&stmt,
+std::unique_ptr
+Builder::block (tl::optional> &&stmt,
std::unique_ptr &&tail_expr) const
 {
   auto stmts = std::vector> ();
-  stmts.emplace_back (std::move (stmt));
+
+  if (stmt)
+stmts.emplace_back (std::move (*stmt));
 
   return block (std::move (stmts), std::move (tail_expr));
 }
 
-std::unique_ptr
+std::unique_ptr
 Builder::block (std::vector> &&stmts,
std::unique_ptr &&tail_expr) const
 {
-  return std::unique_ptr (new BlockExpr (std::move (stmts),
-  std::move (tail_expr), {}, {},
-  LoopLabel::error (), loc, loc));
+  return std::unique_ptr (
+new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {},
+  LoopLabel::error (), loc, loc));
 }
 
 std::unique_ptr
@@ -421,11 +423,9 @@ Builder::match_case (std::unique_ptr &&pattern,
 std::unique_ptr
 Builder::loop (std::vector> &&stmts)
 {
-  auto block = std::unique_ptr (
-new BlockExpr (std::move (stmts), nullptr, {}, {}, LoopLabel::error (), 
loc,
-  loc));
+  auto block_expr = block (std::move (stmts), nullptr);
 
-  return std::unique_ptr (new LoopExpr (std::move (block), loc));
+  return std::unique_ptr (new LoopExpr (std::move (block_expr), loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 99ab1610ce7..9fbcea182be 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -82,12 +82,12 @@ public:
   std::unique_ptr deref (std::unique_ptr &&of) const;
 
   /* Create a block with an optional tail expression */
-  std::unique_ptr block (std::vector> &&stmts,
-  std::unique_ptr &&tail_expr
-  = nullptr) const;
-  std::unique_ptr block (std::unique_ptr &&stmt,
-  std::unique_ptr &&tail_expr
-  = nullptr) const;
+  std::unique_ptr block (std::vector> &&stmts,
+   std::unique_ptr &&tail_expr
+   = nullptr) const;
+  std::unique_ptr block (tl::optional> &&stmt,
+   std::unique_ptr &&tail_expr
+   = nullptr) const;
 
   /* Create an early return expression with an optional expression */
   std::unique_ptr return_expr (std::unique_ptr &&to_return
-- 
2.45.2



[COMMITTED 096/141] gccrs: Fix expansion of macros inside modules

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* expand/rust-expand-visitor.cc
(ExpandVisitor::visit): Override DefaultASTVisitor in order to
expand a module's items, rather than directly visit them.
* expand/rust-expand-visitor.h
(ExpandVisitor::visit): Add override.

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro-expand-module.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/expand/rust-expand-visitor.cc|  6 ++
 gcc/rust/expand/rust-expand-visitor.h |  1 +
 .../rust/compile/macros/mbe/macro-expand-module.rs| 11 +++
 3 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 8ba9a15fddf..2830d200f72 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -721,6 +721,12 @@ ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
 visit (bound);
 }
 
+void
+ExpandVisitor::visit (AST::Module &module)
+{
+  expand_inner_items (module.get_items ());
+}
+
 void
 ExpandVisitor::visit (AST::ExternCrate &crate)
 {}
diff --git a/gcc/rust/expand/rust-expand-visitor.h 
b/gcc/rust/expand/rust-expand-visitor.h
index 5fc1011e001..ad237c07c2f 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -237,6 +237,7 @@ public:
   void visit (AST::TypeParam ¶m) override;
   void visit (AST::LifetimeWhereClauseItem &) override;
   void visit (AST::TypeBoundWhereClauseItem &item) override;
+  void visit (AST::Module &module) override;
   void visit (AST::ExternCrate &crate) override;
   void visit (AST::UseTreeGlob &) override;
   void visit (AST::UseTreeList &) override;
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
new file mode 100644
index 000..e3e702eac84
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
@@ -0,0 +1,11 @@
+mod foo {
+macro_rules! bar {
+() => ()
+}
+
+bar! ();
+
+pub struct S;
+}
+
+pub fn buzz(_: foo::S) {}
-- 
2.45.2



[COMMITTED 037/141] gccrs: lang-items: Add From::from

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* util/rust-lang-item.h: Declare it.
* util/rust-lang-item.cc: Use it.
---
 gcc/rust/util/rust-lang-item.cc | 2 ++
 gcc/rust/util/rust-lang-item.h  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index b37a237c24e..145054ff9d7 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -110,6 +110,8 @@ const BiMap 
Rust::LangItem::lang_items = {{
   {"into_result", Kind::TRY_INTO_RESULT},
   {"from_error", Kind::TRY_FROM_ERROR},
   {"from_ok", Kind::TRY_FROM_OK},
+
+  {"from", Kind::FROM_FROM},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 851909d409c..f30b93609b5 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -141,6 +141,9 @@ public:
 TRY_INTO_RESULT,
 TRY_FROM_ERROR,
 TRY_FROM_OK,
+
+// NOTE: This is not a lang item in later versions of Rust
+FROM_FROM,
   };
 
   static const BiMap lang_items;
-- 
2.45.2



[COMMITTED 095/141] gccrs: Remove PathInExpression::get_pattern_node_id

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* ast/rust-path.h
(PathInExpression::get_pattern_node_id): Remove.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-path.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index c2537034b61..805be8e91f7 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -729,8 +729,6 @@ public:
 outer_attrs = std::move (new_attrs);
   }
 
-  NodeId get_pattern_node_id () const { return get_node_id (); }
-
   PathExprSegment &get_final_segment () { return get_segments ().back (); }
   const PathExprSegment &get_final_segment () const
   {
-- 
2.45.2



[COMMITTED 099/141] gccrs: derive(Debug): Use builder's ptrify function instead

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-debug.cc (ptrify): Remove function.
---
 gcc/rust/expand/rust-derive-debug.cc | 8 
 1 file changed, 8 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-debug.cc 
b/gcc/rust/expand/rust-derive-debug.cc
index f37547459a0..7ad3908483a 100644
--- a/gcc/rust/expand/rust-derive-debug.cc
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -38,14 +38,6 @@ DeriveDebug::go (Item &item)
   return std::move (expanded);
 }
 
-/* Pointer-ify something */
-template 
-static std::unique_ptr
-ptrify (T value)
-{
-  return std::unique_ptr (new T (value));
-}
-
 std::unique_ptr
 DeriveDebug::stub_debug_fn ()
 {
-- 
2.45.2



[COMMITTED 078/141] gccrs: improve error diagnostic for bad type-resolution in CallExpr

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We have the type information for the resolved call lets tell the user about
it in the diagnostic and apply the correct error code.

Fixes Rust-GCC#2035

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): improve 
error diag

gcc/testsuite/ChangeLog:

* rust/compile/generics4.rs: cleanup
* rust/compile/generics6.rs: likewise
* rust/compile/type-bindings1.rs: likewise
* rust/compile/unconstrained_type_param.rs: likewise
* rust/compile/issue-2035.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 13 +
 gcc/testsuite/rust/compile/generics4.rs |  1 -
 gcc/testsuite/rust/compile/generics6.rs |  1 -
 gcc/testsuite/rust/compile/issue-2035.rs| 10 ++
 gcc/testsuite/rust/compile/type-bindings1.rs|  1 -
 .../rust/compile/unconstrained_type_param.rs|  1 -
 6 files changed, 19 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2035.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 5c38cb42b39..85d717535ed 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -225,12 +225,17 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
   if (resolved_fn_trait_call)
 return;
 
-  bool valid_tyty = function_tyty->get_kind () == TyTy::TypeKind::FNDEF
-   || function_tyty->get_kind () == TyTy::TypeKind::FNPTR;
+  bool valid_tyty
+= function_tyty->is () || function_tyty->is ();
   if (!valid_tyty)
 {
-  rust_error_at (expr.get_locus (),
-"Failed to resolve expression of function call");
+  bool emit_error = !function_tyty->is ();
+  if (emit_error)
+   {
+ rich_location r (line_table, expr.get_locus ());
+ rust_error_at (r, ErrorCode::E0618, "expected function, found %<%s%>",
+function_tyty->get_name ().c_str ());
+   }
   return;
 }
 
diff --git a/gcc/testsuite/rust/compile/generics4.rs 
b/gcc/testsuite/rust/compile/generics4.rs
index 31b681abb10..c4dbc432c07 100644
--- a/gcc/testsuite/rust/compile/generics4.rs
+++ b/gcc/testsuite/rust/compile/generics4.rs
@@ -6,7 +6,6 @@ struct GenericStruct(T, usize);
 fn main() {
 let a2;
 a2 = GenericStruct::(1, 456); // { dg-error "generic item takes 
at most 1 type arguments but 2 were supplied" }
-   // { dg-error {Failed to resolve 
expression of function call} "" { target *-*-* } .-1 }
 
 let b2: i32 = a2.0;
 // { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/generics6.rs 
b/gcc/testsuite/rust/compile/generics6.rs
index 33093cf706b..d77c559db21 100644
--- a/gcc/testsuite/rust/compile/generics6.rs
+++ b/gcc/testsuite/rust/compile/generics6.rs
@@ -27,6 +27,5 @@ impl Foo {
 
 fn main() {
 let a: i32 = Foo::test(); // { dg-error "multiple applicable items in 
scope for: .test." }
-// { dg-error {Failed to resolve expression of function call} "" { target 
*-*-* } .-1 }
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-2035.rs 
b/gcc/testsuite/rust/compile/issue-2035.rs
new file mode 100644
index 000..c0817d532cc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2035.rs
@@ -0,0 +1,10 @@
+fn func(i: i32) {
+i();
+// { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } 
.-1 }
+}
+
+fn main() {
+let i = 0i32;
+i();
+// { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs 
b/gcc/testsuite/rust/compile/type-bindings1.rs
index 358035bbc17..ef0b47128df 100644
--- a/gcc/testsuite/rust/compile/type-bindings1.rs
+++ b/gcc/testsuite/rust/compile/type-bindings1.rs
@@ -7,5 +7,4 @@ fn main() {
 let a;
 a = Foo::(123f32);
 // { dg-error "associated type bindings are not allowed here" "" { target 
*-*-* } .-1 }
-// { dg-error {Failed to resolve expression of function call} "" { target 
*-*-* } .-2 }
 }
diff --git a/gcc/testsuite/rust/compile/unconstrained_type_param.rs 
b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
index 1cef0b983b0..60554dac0e0 100644
--- a/gcc/testsuite/rust/compile/unconstrained_type_param.rs
+++ b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
@@ -13,5 +13,4 @@ impl Foo {
 fn main() {
 let a = Foo::test();
 // { dg-error "expected" "" { target *-*-* } .-1 }
-// { dg-error "Failed to resolve expression of function call" "" { target 
*-*-* } .-2 }
 }
-- 
2.45.2



[COMMITTED 131/141] gccrs: Remove mangling tests from exclusion list

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Those tests are now passing.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove two mangling tests from exclusion
file.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/nr2/exclude | 2 --
 1 file changed, 2 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e8e99da5801..8aaec5d3b22 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -32,8 +32,6 @@ sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
 undeclared_label.rs
 use_1.rs
-v0-mangle1.rs
-v0-mangle2.rs
 while_break_expr.rs
 issue-3139-2.rs
 issue-2953-2.rs
-- 
2.45.2



[COMMITTED 081/141] gccrs: nr2.0: Resolve paths which start with Self

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Be more careful about
applying ForeverStack::find_closest_module.
(ForeverStack::resolve_segments): Allow traversal into parent
nodes when not in a module node or root node, which
ForeverStack::find_starting_point previously made moot through
use of ForeverStack::find_closest_module. Also, when a child
node lookup fails when resolving in the type namespace, attempt
a rib lookup as a fallback.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Avoid throwing a resolution error for type paths
when the typechecker may be able to finish the resolution. Also,
throw an error when a resolution is ambiguous.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.hxx   | 60 ---
 .../resolve/rust-late-name-resolver-2.0.cc| 25 +---
 gcc/testsuite/rust/compile/nr2/exclude| 35 ---
 3 files changed, 56 insertions(+), 64 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index b51da51948f..d2020554f74 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -381,13 +381,6 @@ ForeverStack::find_starting_point (
 {
   auto iterator = segments.begin ();
 
-  // If we need to do path segment resolution, then we start
-  // at the closest module. In order to resolve something like `foo::bar!()`, 
we
-  // need to get back to the surrounding module, and look for a child module
-  // named `foo`.
-  if (segments.size () > 1)
-starting_point = find_closest_module (starting_point);
-
   for (; !is_last (iterator, segments); iterator++)
 {
   auto &outer_seg = *iterator;
@@ -416,12 +409,14 @@ ForeverStack::find_starting_point (
   if (seg.is_lower_self_seg ())
{
  // insert segment resolution and exit
+ starting_point = find_closest_module (starting_point);
  insert_segment_resolution (outer_seg, starting_point.get ().id);
  iterator++;
  break;
}
   if (seg.is_super_path_seg ())
{
+ starting_point = find_closest_module (starting_point);
  if (starting_point.get ().is_root ())
{
  rust_error_at (seg.get_locus (), ErrorCode::E0433,
@@ -469,27 +464,48 @@ ForeverStack::resolve_segments (
 
   tl::optional::Node &> child = tl::nullopt;
 
-  for (auto &kv : current_node->children)
+  while (true)
{
- auto &link = kv.first;
+ for (auto &kv : current_node->children)
+   {
+ auto &link = kv.first;
+
+ if (link.path.map_or (
+   [&str] (Identifier path) {
+ auto &path_str = path.as_string ();
+ return str == path_str;
+   },
+   false))
+   {
+ child = kv.second;
+ break;
+   }
+   }
 
- if (link.path.map_or (
-   [&str] (Identifier path) {
- auto &path_str = path.as_string ();
- return str == path_str;
-   },
-   false))
+ if (child.has_value ())
{
- child = kv.second;
  break;
}
-   }
 
-  if (!child.has_value ())
-   {
- rust_error_at (seg.get_locus (), ErrorCode::E0433,
-"failed to resolve path segment %qs", str.c_str ());
- return tl::nullopt;
+ if (N == Namespace::Types)
+   {
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
+   {
+ insert_segment_resolution (outer_seg,
+rib_lookup->get_node_id ());
+ return tl::nullopt;
+   }
+   }
+
+ if (!is_start (iterator, segments)
+ || current_node->rib.kind == Rib::Kind::Module
+ || current_node->is_root ())
+   {
+ return tl::nullopt;
+   }
+
+ current_node = ¤t_node->parent.value ();
}
 
   current_node = &child.value ();
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index c134ca03336..7253deb42d9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -294,6 +294,8 @@ Late::visit (AST::TypePath &type)
   // maybe we can overload `resolve_path` to only do
   // typepath-like path resolution? that sounds good
 
+  DefaultResolver::visit (type);
+
   // take care of only simple cases
   // TODO: remove this?
   r

[COMMITTED 086/141] gccrs: derive(Eq): Add implementation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveEq.
* expand/rust-derive-eq.cc: New file.
* expand/rust-derive-eq.h: New file.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/derive-eq-invalid.rs: New test.
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/expand/rust-derive-eq.cc | 207 ++
 gcc/rust/expand/rust-derive-eq.h  |  82 +++
 gcc/rust/expand/rust-derive.cc|   2 +
 .../rust/compile/derive-eq-invalid.rs |  45 
 5 files changed, 337 insertions(+)
 create mode 100644 gcc/rust/expand/rust-derive-eq.cc
 create mode 100644 gcc/rust/expand/rust-derive-eq.h
 create mode 100644 gcc/testsuite/rust/compile/derive-eq-invalid.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 5ddad257805..83ffc47ce28 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -98,6 +98,7 @@ GRS_OBJS = \
 rust/rust-derive-copy.o \
 rust/rust-derive-debug.o \
 rust/rust-derive-default.o \
+rust/rust-derive-eq.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
 rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-eq.cc 
b/gcc/rust/expand/rust-derive-eq.cc
new file mode 100644
index 000..a2a7a769065
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -0,0 +1,207 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+std::unique_ptr
+DeriveEq::assert_receiver_is_total_eq_fn (
+  std::vector> &&types)
+{
+  auto stmts = std::vector> ();
+
+  stmts.emplace_back (assert_param_is_eq ());
+
+  for (auto &&type : types)
+stmts.emplace_back (assert_type_is_eq (std::move (type)));
+
+  auto block = std::unique_ptr (
+new BlockExpr (std::move (stmts), nullptr, {}, {}, AST::LoopLabel::error 
(),
+  loc, loc));
+
+  auto self = builder.self_ref_param ();
+
+  return builder.function ("assert_receiver_is_total_eq",
+  vec (std::move (self)), {}, std::move (block));
+}
+
+std::unique_ptr
+DeriveEq::assert_param_is_eq ()
+{
+  auto eq_bound = std::unique_ptr (
+new TraitBound (builder.type_path ({"core", "cmp", "Eq"}, true), loc));
+
+  auto sized_bound = std::unique_ptr (
+new TraitBound (builder.type_path (LangItem::Kind::SIZED), loc, false,
+   true /* opening_question_mark */));
+
+  auto bounds = vec (std::move (eq_bound), std::move (sized_bound));
+
+  auto assert_param_is_eq = "AssertParamIsEq";
+
+  auto t = std::unique_ptr (
+new TypeParam (Identifier ("T"), loc, std::move (bounds)));
+
+  return builder.struct_struct (
+assert_param_is_eq, vec (std::move (t)),
+{StructField (
+  Identifier ("_t"),
+  builder.single_generic_type_path (
+   LangItem::Kind::PHANTOM_DATA,
+   GenericArgs (
+ {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
+  Visibility::create_private (), loc)});
+}
+
+std::unique_ptr
+DeriveEq::assert_type_is_eq (std::unique_ptr &&type)
+{
+  auto assert_param_is_eq = "AssertParamIsEq";
+
+  // AssertParamIsCopy::
+  auto assert_param_is_eq_ty
+= std::unique_ptr (new TypePathSegmentGeneric (
+  PathIdentSegment (assert_param_is_eq, loc), false,
+  GenericArgs ({}, {GenericArg::create_type (std::move (type))}, {}, loc),
+  loc));
+
+  // TODO: Improve this, it's really ugly
+  auto type_paths = std::vector> ();
+  type_paths.emplace_back (std::move (assert_param_is_eq_ty));
+
+  auto full_path
+= std::unique_ptr (new TypePath ({std::move (type_paths)}, loc));
+
+  return builder.let (builder.wildcard (), std::move (full_path));
+}
+
+std::unique_ptr
+DeriveEq::eq_impl (
+  std::unique_ptr &&fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto eq = builder.type_path ({"core", "cmp", "Eq"}, true);
+
+  auto trait_items = vec (std::move (fn));
+
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+
+  return builder.trait_impl (eq, 

[COMMITTED 125/141] gccrs: Move import mapping resolution to in tree visit

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Import mapping was relying on resolve_path which in turn relies on
the cursor function. This means the mapping resolver should be called
from the correct scope instead of being called from the crate scope.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the
top level visitor from the function scope to attributes.
(Early::go): Remove top level visitor creation and adapt calling code.
Remove call to mapping resolution and import finalization.
(Early::finalize_simple_import): Move the finalization from it's
visitor.
(Early::finalize_glob_import): Likewise.
(Early::finalize_rebind_import): Likewise.
(Early::visit): Add mapping resolution and finalization in
UseDeclaration visitor function.
* resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move
function.
(finalize_glob_import): Likewise.
(finalize_rebind_import): Likewise.
(FinalizeImports::visit): Remove call to finalizers.
* resolve/rust-early-name-resolver-2.0.h (class Early): Add top level
attribute.
* resolve/rust-finalize-imports-2.0.h: Add function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type
to reference.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 98 +--
 .../resolve/rust-early-name-resolver-2.0.h|  9 ++
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 79 +--
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  4 +-
 .../resolve/rust-toplevel-name-resolver-2.0.h |  5 +-
 5 files changed, 105 insertions(+), 90 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index b894d130ccf..492a665f43e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -27,7 +27,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty 
(false)
+Early::Early (NameResolutionContext &ctx)
+  : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
 {}
 
 void
@@ -52,16 +53,10 @@ void
 Early::go (AST::Crate &crate)
 {
   // First we go through TopLevel resolution to get all our declared items
-  auto toplevel = TopLevel (ctx);
   toplevel.go (crate);
 
   // We start with resolving the list of imports that `TopLevel` has built for
   // us
-  for (auto &&import : toplevel.get_imports_to_resolve ())
-build_import_mapping (std::move (import));
-
-  // Once this is done, we finalize their resolution
-  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   dirty = toplevel.is_dirty ();
   // We now proceed with resolving macros, which can be nested in almost any
@@ -375,5 +370,94 @@ Early::visit (AST::StructStruct &s)
   DefaultResolver::visit (s);
 }
 
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+  // FIXME: We probably need to store namespace information
+
+  auto locus = mapping.import_kind.to_resolve.get_locus ();
+  auto data = mapping.data;
+  auto identifier
+= mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+  for (auto &&definition : data.definitions ())
+toplevel
+  .insert_or_error_out (
+   identifier, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+const Early::ImportPair &mapping)
+{
+  auto module = Analysis::Mappings::get ().lookup_ast_module (
+mapping.data.module ().get_node_id ());
+  rust_assert (module);
+
+  GlobbingVisitor glob_visitor (ctx);
+  glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (const Early::ImportPair &mapping)
+{
+  // We can fetch the value here as `resolve_rebind` will only be called on
+  // imports of the right kind
+  auto &path = mapping.import_kind.to_resolve;
+  auto &rebind = mapping.import_kind.rebind.value ();
+  auto data = mapping.data;
+
+  location_t locus = UNKNOWN_LOCATION;
+  std::string declared_name;
+
+  // FIXME: This needs to be done in `FinalizeImports`
+  switch (rebind.get_new_bind_type ())
+{
+case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+  declared_name = rebind.get_identifier ().as_string ();
+  locus = rebind.get_identifier ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::NONE:
+  declared_name = path.get_final_segment ().as_string ();
+  locus = path.get_final_segment ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::WILDCARD:
+  rust_unreachable ();
+  break;
+}
+
+  for (auto &&definition : data.definitions ())
+toplevel.insert_or_er

Re: [PATCH] libgcobol: C++-ify the configuration steps.

2025-03-24 Thread Iain Sandoe
Hi 

> On 24 Mar 2025, at 14:50, Robert Dubner  wrote:
> 
> No I am not sure what to do.
> 
> I tried to apply this patch, both the the master branch and to one of my 
> working copies.

My apologies, some of what I am doing depends on the work that you, Richi
and Jakub have been doing, and so I have a short branch (where each new
piece is tested independently).

This branch
https://github.com/iains/gcc-git/commits/master-wip-cobol-posted/
or
https://forge.sourceware.org/iains/gcc-TEST/src/branch/master-wip-cobol-posted
is up to date.

I guess it 
https://forge.sourceware.org/iains/gcc-TEST/commit/a7f0adf9a1ee557c088b08288f89c15c5def3059

will not cherry-pick cleanly without the (trivial) change here:
https://forge.sourceware.org/iains/gcc-TEST/commit/67f7bee807ccb2cfd070e17460339e611a3c3bce

If it helps I can make a new branch with just this patch on it (the actual 
changes are
quite small but the regeneration of the output makes the patch huge).

Iain



[PATCH 2/2] [COBOL] Remove unused _Float128 using helpers

2025-03-24 Thread Richard Biener


Tested on x86_64-unknown-linux-gnu.

The only remaining _Float128 use is now via the strtof128 inline
which is used in two places to commpute the end of a numeric
literal and verify against the parsed end(?) to do diagnostics.
I'm not sure why or whether this is necessary - I'd have expected
lexing to number tokens and then parsing to diagnose unwanted
characters?  So my preference would be to remove the diagnostic
and where number parsing support error reporting assert that all
lexed numbers can be handled by them.  In any case test coverage
would be nice to have here.

OK?

Thanks,
Richard.

* symbols.h (cbl_field_t::value_set): Remove.
(strfromf128): Remove.
* parse.y (cbl_field_t::value_set): Remove.
---
 gcc/cobol/parse.y   | 22 --
 gcc/cobol/symbols.h |  9 ++---
 2 files changed, 2 insertions(+), 29 deletions(-)

diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 43ecef0de8f..390e115f37e 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -12810,28 +12810,6 @@ cbl_field_t::has_subordinate( const cbl_field_t *that 
) const {
   return false;
 }
 
-bool
-cbl_field_t::value_set( _Float128 value ) {
-  data = value;
-  char *initial = string_of(data.value_of());
-  if( !initial ) return false;
-
-  // Trim trailing zeros.
-  char *p = initial + strlen(initial);
-  for( --p; initial <= p; --p ) {
-if( *p != '0' ) break;
-*p = '\0';
-  }
-
-  data.digits = (p - initial) + 1;
-  p = strchr(initial, '.');
-  data.rdigits = p? initial + data.digits - p : 0;
-
-  data.initial = initial;
-  data.capacity = type_capacity(type, data.digits);
-  return true;
-}
-
 const char *
 cbl_field_t::value_str() const {
 if( data.etc_type == cbl_field_data_t::value_e )
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index f51a2051f51..72bb188ec5b 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -51,16 +51,12 @@
 #if ! (__HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT))
 static_assert( sizeof(output) == sizeof(long double), "long doubles?" );
 
+// ???  This is still used for verificataion that __nptr parses as
+// float number via setting *__endptr.
 static inline _Float128
 strtof128 (const char *__restrict __nptr, char **__restrict __endptr) {
   return strtold(nptr, endptr);
 }
-
-static inline int
-strfromf128 (char *restrict string, size_t size,
-const char *restrict format, _Float128 value) {
-  return  strfroml(str, n, format, fp);
-}
 #endif
 
 extern const char *numed_message;
@@ -600,7 +596,6 @@ struct cbl_field_t {
   bool has_subordinate( const cbl_field_t *that ) const;
 
   const char * internalize();
-  bool value_set( _Float128 value );
   const char *value_str() const;
 
   bool is_key_name() const { return has_attr(record_key_e); }
-- 
2.43.0


[COMMITTED 136/141] gccrs: Prevent multiple resolution insertion

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc
(DeriveClone::clone_impl): Avoid using the same node id multiple
times.
(DeriveClone::clone_enum_identifier): Likewise.
(DeriveClone::clone_enum_tuple): Likewise.
* expand/rust-derive-copy.cc
(DeriveCopy::copy_impl): Likewise.
* resolve/rust-ast-resolve-item.cc
(flatten_list): Likewise.
* resolve/rust-ast-resolve-path.cc
(ResolvePath::resolve_path): Prevent reinsertion of resolutions.
* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Likewise.
* typecheck/rust-hir-type-check-expr.cc
(TypeCheckExpr::resolve_fn_trait_call): Likewise.
* resolve/rust-name-resolver.cc
(Resolver::insert_resolved_name): Catch multiple resolution
insertions.
(Resolver::insert_resolved_type): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/expand/rust-derive-clone.cc  |  43 ++--
 gcc/rust/expand/rust-derive-copy.cc   |  13 +-
 gcc/rust/resolve/rust-ast-resolve-item.cc |  13 +-
 gcc/rust/resolve/rust-ast-resolve-path.cc | 200 +++---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  82 +--
 gcc/rust/resolve/rust-name-resolver.cc|   5 +-
 .../typecheck/rust-hir-type-check-expr.cc |  21 +-
 gcc/testsuite/rust/compile/nr2/exclude|   6 -
 8 files changed, 302 insertions(+), 81 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index d0ffbbdafa7..074ea01b24a 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -91,14 +91,17 @@ DeriveClone::clone_impl (
   std::unique_ptr &&clone_fn, std::string name,
   const std::vector> &type_generics)
 {
-  auto clone = builder.type_path (LangItem::Kind::CLONE);
+  // we should have two of these, so we don't run into issues with
+  // two paths sharing a node id
+  auto clone_bound = builder.type_path (LangItem::Kind::CLONE);
+  auto clone_trait_path = builder.type_path (LangItem::Kind::CLONE);
 
   auto trait_items = vec (std::move (clone_fn));
 
-  auto generics
-= setup_impl_generics (name, type_generics, builder.trait_bound (clone));
+  auto generics = setup_impl_generics (name, type_generics,
+  builder.trait_bound (clone_bound));
 
-  return builder.trait_impl (clone, std::move (generics.self_type),
+  return builder.trait_impl (clone_trait_path, std::move (generics.self_type),
 std::move (trait_items),
 std::move (generics.impl));
 }
@@ -173,9 +176,14 @@ DeriveClone::clone_enum_identifier (PathInExpression 
variant_path,
const std::unique_ptr &variant)
 {
   auto pattern = std::unique_ptr (new ReferencePattern (
-std::unique_ptr (new PathInExpression (variant_path)), false,
-false, loc));
-  auto expr = std::unique_ptr (new PathInExpression (variant_path));
+std::unique_ptr (new PathInExpression (
+  variant_path.get_segments (), {}, variant_path.get_locus (),
+  variant_path.opening_scope_resolution ())),
+false, false, loc));
+  auto expr = std::unique_ptr (
+new PathInExpression (variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ()));
 
   return builder.match_case (std::move (pattern), std::move (expr));
 }
@@ -206,14 +214,19 @@ DeriveClone::clone_enum_tuple (PathInExpression 
variant_path,
   auto pattern_items = std::unique_ptr (
 new TupleStructItemsNoRange (std::move (patterns)));
 
-  auto pattern = std::unique_ptr (
-new ReferencePattern (std::unique_ptr (new TupleStructPattern (
-   variant_path, std::move (pattern_items))),
- false, false, loc));
-
-  auto expr
-= builder.call (std::unique_ptr (new PathInExpression 
(variant_path)),
-   std::move (cloned_patterns));
+  auto pattern = std::unique_ptr (new ReferencePattern (
+std::unique_ptr (new TupleStructPattern (
+  PathInExpression (variant_path.get_segments (), {},
+   variant_path.get_locus (),
+   variant_path.opening_scope_resolution ()),
+  std::move (pattern_items))),
+false, false, loc));
+
+  auto expr = builder.call (std::unique_ptr (new PathInExpression (
+ variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ())),
+   std::move (cloned_patterns));
 
   return builder.match_case (std::move (pattern), std::move (expr));
 }
diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
inde

[pushed] c++: pack indexing and if consteval

2025-03-24 Thread Jason Merrill
Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

The pack index is manifestly constant-evaluated, and the call to
maybe_constant_value needs to reflect that or we wrongly complain about
non-constant index if the evaluation uses if consteval.

gcc/cp/ChangeLog:

* semantics.cc (finish_type_pack_element): Pass mce_true to
maybe_constant_value.

gcc/testsuite/ChangeLog:

* g++.dg/cpp26/pack-indexing16.C: New test.
---
 gcc/cp/semantics.cc  |  2 +-
 gcc/testsuite/g++.dg/cpp26/pack-indexing16.C | 16 
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp26/pack-indexing16.C

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index b0a5f9ad660..b390d663e24 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5086,7 +5086,7 @@ finish_underlying_type (tree type)
 static tree
 finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
 {
-  idx = maybe_constant_value (idx);
+  idx = maybe_constant_value (idx, NULL_TREE, mce_true);
   if (TREE_CODE (idx) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (idx)))
 {
   if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp26/pack-indexing16.C 
b/gcc/testsuite/g++.dg/cpp26/pack-indexing16.C
new file mode 100644
index 000..92ade86d06b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/pack-indexing16.C
@@ -0,0 +1,16 @@
+// { dg-do compile { target c++26 } }
+
+int i;
+constexpr int idx()
+{
+  if consteval { return 0; }
+  else { return i; }
+}
+
+template 
+int first () { return Ns...[idx()]; }
+
+int main()
+{
+  return first<0,1,2>();
+}

base-commit: 57fdc97dac1453849a76bdce265428d441a03de0
-- 
2.49.0



Re: [PATCH] libstdc++: Fix handling of common cpp20-only ranges for flat sets [PR119415]

2025-03-24 Thread Patrick Palka
On Mon, 24 Mar 2025, Tomasz Kamiński wrote:

> These patch add check to verify if common range iterators satisfies
> Cpp17LegacyIterator requirements (__detail::__cpp17_input_iterator),
> before invoking overloads of insert that accepts two iterators.
> As such overloads existed before c++20 iterators were introduced,
> they commonly assume existence of iterator_traits<..>::iterator_category,
> and passing a cpp20-only iterators, leads to hard errors.
> 
> In case if user-defined container wants to support more efficient
> insertion in such cases, it should provided insert_range method,
> as in the case of standard containers.
> 
>   PR libstdc++/119415
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/std/flat_set (flat_multiset::insert_range,
>   flat_set::insert_range): Add __detail::__cpp17_input_iterator check.

There's a chance this ChangeLog entry might not be accepted by the
pre-commit hook.  It might need to be written as

* include/std/flat_set (flat_multiset::insert_range)
(flat_set::insert_range): Add __detail::__cpp17_input_iterator check.

as per the ChangeLog style guide[1] which says:

Break long lists of function names by closing continued lines with ‘)’,
rather than ‘,’, and opening the continuation with ‘(’.

OTOH, what the patch is lexically changing is _Flat_set_impl::insert_range,
so maybe the ChangeLog entry should just mention that?

[1]: 
https://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html#Style-of-Change-Logs;

>   * testsuite/23_containers/flat_multiset/1.cc: New tests
>   * testsuite/23_containers/flat_set/1.cc: New tests
> ---
> Testing on x86_64-linux. OK for trunk?
> 
>  libstdc++-v3/include/std/flat_set |  3 +-
>  .../23_containers/flat_multiset/1.cc  | 18 
>  .../testsuite/23_containers/flat_set/1.cc | 28 +++
>  3 files changed, 48 insertions(+), 1 deletion(-)
> 
> diff --git a/libstdc++-v3/include/std/flat_set 
> b/libstdc++-v3/include/std/flat_set
> index 9240f2b9a2e..ea416e67503 100644
> --- a/libstdc++-v3/include/std/flat_set
> +++ b/libstdc++-v3/include/std/flat_set
> @@ -480,7 +480,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> typename container_type::iterator __it;
> if constexpr (requires { _M_cont.insert_range(_M_cont.end(), __rg); })
>   __it = _M_cont.insert_range(_M_cont.end(), __rg);
> -   else if constexpr (ranges::common_range<_Rg>)
> +   else if constexpr (ranges::common_range<_Rg> 
> +  && 
> __detail::__cpp17_input_iterator>)
>   __it = _M_cont.insert(_M_cont.end(), ranges::begin(__rg), 
> ranges::end(__rg));
> else
>   {
> diff --git a/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc 
> b/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc
> index 910f5dca5be..0858be4a9fe 100644
> --- a/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc
> +++ b/libstdc++-v3/testsuite/23_containers/flat_multiset/1.cc
> @@ -143,6 +143,23 @@ test06()
>VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
>  }
>  
> +void test07()
> +{
> +#ifdef __SIZEOF_INT128__
> +  // PR libstdc++/119415 - flat_foo::insert_range cannot handle common ranges
> +  // on c++20 only iterators
> +  auto r = std::views::iota(__int128(1), __int128(6));
> +
> +  std::flat_multiset s;
> +  s.insert_range(r);
> +  VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
> +
> +  std::flat_multiset, NoInsertRange> s2;
> +  s2.insert_range(r);
> +  VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
> +#endif   
> +}
> +
>  int
>  main()
>  {
> @@ -153,4 +170,5 @@ main()
>test04();
>test05();
>test06();
> +  test07();
>  }
> diff --git a/libstdc++-v3/testsuite/23_containers/flat_set/1.cc 
> b/libstdc++-v3/testsuite/23_containers/flat_set/1.cc
> index f0eaac936bf..374be80bb9d 100644
> --- a/libstdc++-v3/testsuite/23_containers/flat_set/1.cc
> +++ b/libstdc++-v3/testsuite/23_containers/flat_set/1.cc
> @@ -8,6 +8,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -158,6 +159,32 @@ test06()
>VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
>  }
>  
> +template
> +struct NoInsertRange : std::vector
> +{
> +  using std::vector::vector;
> +
> +  template
> +  void insert_range(typename std::vector::const_iterator, R&&) = delete;
> +};
> +
> +void test07()
> +{
> +#ifdef __SIZEOF_INT128__
> +  // PR libstdc++/119415 - flat_foo::insert_range cannot handle common ranges
> +  // on c++20 only iterators
> +  auto r = std::views::iota(__int128(1), __int128(6));
> +
> +  std::flat_set s;
> +  s.insert_range(r);
> +  VERIFY( std::ranges::equal(s, (int[]){1, 2, 3, 4, 5}) );
> +
> +  std::flat_set, NoInsertRange> s2;
> +  s2.insert_range(r);
> +  VERIFY( std::ranges::equal(s2, (int[]){1, 2, 3, 4, 5}) );
> +#endif   
> +}
> +
>  int
>  main()
>  {
> @@ -168,4 +195,5 @@ main()
>test04();
>test05();
>test06();
> +  test07();
>  }
> -- 

Re: [PATCH] Fix up some further cases of missing or extraneous spaces in diagnostics

2025-03-24 Thread Joseph Myers
On Sat, 22 Mar 2025, Jakub Jelinek wrote:

> On Sat, Mar 22, 2025 at 08:18:27AM +0100, Andreas Schwab wrote:
> > On Mär 22 2025, Jakub Jelinek wrote:
> > 
> > > I think just the c.opt change needs an explanation, the "" in the
> > > description is simply eaten up somewhere during the option processing and
> > 
> > exgettext could do the quoting itself, obviating the need for doing it
> > explicitly and eliminating an easy to make error.
> 
> I think it must be exgettext and something in the option processing at the
> same time.

Note that we have bug 118979 for the exgettext extraction issue (I guess 
we should leave that bug open until extraction / option processing are 
fixed here).

-- 
Joseph S. Myers
josmy...@redhat.com

Re: [PATCH v2] RISC-V: Fix wrong LMUL when only implict zve32f.

2025-03-24 Thread Kito Cheng
On Mon, Mar 24, 2025 at 11:35 PM Robin Dapp  wrote:
>
> > This does not only happen on ELEN=32 and VLEN=32, it happened on all
> > ELEN=32 arch, and one of our internal configurations hit this...
>
> Wait, is there something I keep missing?  There must be I guess.
>
> Disregarding the SEW=8 case because that one is clear, but take for example:
>
>   ENTRY (RVVMF4HI, TARGET_MIN_VLEN > 32 && !TARGET_XTHEADVECTOR, LMUL_F4, 64)
>
> that the patch changes to
>
>   ENTRY (RVVMF4HI, TARGET_VECTOR_ELEN_64 && !TARGET_XTHEADVECTOR, LMUL_F4, 64)
>
> My reading of the spec is that we are allowed to emit instructions with that
> mode for ELEN = 32 and VLEN = 64 but not for ELEN = 32 and VLEN = 32.  To me
> that is in the same vein as when emitting RVVMF4SI for VLEN >= 128 even though
> RVVMF4SI is not permissible by default (i.e. VLEN = 64).  If that's incorrect
> then please let me know.

Oh, ok, I got the point why you confused on this, the new condition is
little bit `indirect`,
it say TARGET_VECTOR_ELEN_64, it would be clear if we TARGET_VECTOR_ELEN > 32,
however we don't have that so we test TARGET_VECTOR_ELEN_64 instead of
TARGET_VECTOR_ELEN > 32, and that will implicitly mean not allow
zve32x or zve32f
with any VLEN since we didn't limit/test VLEN here.

In theory that should also test VLEN >= 64 for that, but since we
already forbit zve32x
or zve32f which means it at least requires zve64 and it will imply VLEN >= 64,
so we don't need to test that.

NOTE: RVVMF4HI is OK for VLEN=64 since 64 * 1/4 = 16 = able to hold
one HI, and you say SI in your reply I assume that is a typo?

> >> That's unfortunate but in line with other
> >> IMHO unfortunate spec decisions like unaligned vector access so there's no 
> >> way
> >> around it.
> >
> > I didn't get the point around the unaligned vector stuff? Do you mean
> > the access does not align to VLEN or something else, do you mind
> > giving a few examples?
>
> I meant the general situation with not making vector misalignment required
> (i.e. non faulting) in the spec.  I realize that this has been a tradeoff for
> embedded-oriented vector implementations but it's annoying from a compiler's
> perspective to not be able to emit them in a default march.  Similar here but
> surely not as important for performance:  I would have liked us to be able to
> emit MF8 regardless of ELEN and just avoid the modes where it doesn't make
> sense.

I guess I still haven't got the point yet? we didn't touch the
alignment within this patch,
so it still requires element alignment for each vector type?
I mean using MF8 or losing MF8 didn't let us get the capability to do
misalignment access?

We lose ELLEN=8 MF8 (RVVMF8QI), but we still ELEN=8 MF4 (RVVMF4QI) to
do those unaligned memory accesses, that should be functional
equivalence.
(and both are occupy one vector register, so using MF8 isn't get fewer
register pressure than MF4)


>
> --
> Regards
>  Robin
>


[COMMITTED 039/141] gccrs: ast: Add new Expr::Kinds

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

Collapses all of the OperatorExprs into Expr instead of first having to check 
for OperatorExpr and
then check for each OperatorExpr::Kind.

gcc/rust/ChangeLog:

* ast/rust-ast.h: Add new Expr::Kinds.
* ast/rust-expr.h: Implement missing get_expr_kind(), Add 
get_function_expr_ptr()
---
 gcc/rust/ast/rust-ast.h  | 10 ++
 gcc/rust/ast/rust-expr.h | 31 +++
 2 files changed, 41 insertions(+)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 5e724d184de..42be097f056 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1263,6 +1263,16 @@ public:
 Identifier,
 FormatArgs,
 MacroInvocation,
+Borrow,
+Dereference,
+ErrorPropagation,
+Negation,
+ArithmeticOrLogical,
+Comparison,
+LazyBoolean,
+TypeCast,
+Assignment,
+CompoundAssignment,
   };
 
   virtual Kind get_expr_kind () const = 0;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 852c3f3a3a4..cff09fe17d7 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -407,6 +407,8 @@ public:
   bool get_is_double_borrow () const { return double_borrow; }
   bool is_raw_borrow () const { return raw_borrow; }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Borrow; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -437,6 +439,8 @@ public:
 return *main_or_left_expr;
   }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; 
}
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -468,6 +472,11 @@ public:
 return *main_or_left_expr;
   }
 
+  Expr::Kind get_expr_kind () const override
+  {
+return Expr::Kind::ErrorPropagation;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -511,6 +520,8 @@ public:
 return *main_or_left_expr;
   }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -599,6 +610,11 @@ public:
   void visit_lhs (ASTVisitor &vis) { main_or_left_expr->accept_vis (vis); }
   void visit_rhs (ASTVisitor &vis) { right_expr->accept_vis (vis); }
 
+  Expr::Kind get_expr_kind () const override
+  {
+return Expr::Kind::ArithmeticOrLogical;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -686,6 +702,8 @@ public:
 
   ExprType get_kind () { return expr_type; }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Comparison; }
+
   /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
* maybe? */
 protected:
@@ -774,6 +792,8 @@ public:
 
   ExprType get_kind () { return expr_type; }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::LazyBoolean; 
}
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -836,6 +856,8 @@ public:
 return *type_to_convert_to;
   }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -914,6 +936,8 @@ public:
 return *right_expr;
   }
 
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Assignment; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1000,6 +1024,11 @@ public:
 return right_expr;
   }
 
+  Expr::Kind get_expr_kind () const override
+  {
+return Expr::Kind::CompoundAssignment;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2139,6 +2168,8 @@ public:
 return *function;
   }
 
+  std::unique_ptr &get_function_expr_ptr () { return function; }
+
   const std::vector &get_outer_attrs () const { return outer_attrs; 
}
   std::vector &get_outer_attrs () override { return outer_attrs; }
 
-- 
2.45.2



[COMMITTED 033/141] gccrs: Resolved item type shall be differentiated later

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

We need to query all namespaces and error out at a later stage if the
retrieved item is wrong.

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc 
(TraitResolver::resolve_path_to_trait):
Query all namespaces.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 82019328e16..04af5abf837 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -127,8 +127,10 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath 
&path,
 }
   else
 {
-  ok = resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
-  &ref);
+  auto path_nodeid = path.get_mappings ().get_nodeid ();
+  ok = resolver->lookup_resolved_type (path_nodeid, &ref)
+  || resolver->lookup_resolved_name (path_nodeid, &ref)
+  || resolver->lookup_resolved_macro (path_nodeid, &ref);
 }
 
   if (!ok)
-- 
2.45.2



[COMMITTED 113/141] gccrs: nr2.0: Make sure PathInExpression is default resolved

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Call DefaultResolver::visit earlier, in order to
ensure it is called even if Late::visit returns early.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 4 ++--
 gcc/testsuite/rust/compile/nr2/exclude  | 5 -
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 8dd1088d65d..9cf2b1f81c9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -255,6 +255,8 @@ Late::visit (AST::PathInExpression &expr)
   // in a function item` error here?
   // do we emit it in `get`?
 
+  DefaultResolver::visit (expr);
+
   if (expr.is_lang_item ())
 {
   ctx.map_usage (Usage (expr.get_node_id ()),
@@ -284,8 +286,6 @@ Late::visit (AST::PathInExpression &expr)
 
   ctx.map_usage (Usage (expr.get_node_id ()),
 Definition (resolved->get_node_id ()));
-
-  DefaultResolver::visit (expr);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 02da99de52f..763387f3548 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -12,9 +12,6 @@ issue-1901.rs
 issue-1981.rs
 issue-2043.rs
 issue-2330.rs
-issue-2723-1.rs
-issue-2723-2.rs
-issue-2782.rs
 issue-2812.rs
 issue-850.rs
 issue-855.rs
@@ -36,7 +33,6 @@ self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
-traits3.rs
 undeclared_label.rs
 use_1.rs
 v0-mangle1.rs
@@ -45,7 +41,6 @@ while_break_expr.rs
 exhaustiveness2.rs
 issue-3139-2.rs
 issue-3033.rs
-issue-3009.rs
 issue-2953-2.rs
 issue-2905-2.rs
 issue-266.rs
-- 
2.45.2



[COMMITTED 050/141] gccrs: ast: builder: Add Return expression builder

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Declare it.
* ast/rust-ast-builder.cc (Builder::return_expr): Define it.
---
 gcc/rust/ast/rust-ast-builder.cc | 7 +++
 gcc/rust/ast/rust-ast-builder.h  | 4 
 2 files changed, 11 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 3a3181f3752..aef0e110ce0 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -276,6 +276,13 @@ Builder::block (std::vector> &&stmts,
   LoopLabel::error (), loc, loc));
 }
 
+std::unique_ptr
+Builder::return_expr (std::unique_ptr &&to_return)
+{
+  return std::unique_ptr (
+new ReturnExpr (std::move (to_return), {}, loc));
+}
+
 std::unique_ptr
 Builder::let (std::unique_ptr pattern, std::unique_ptr type,
  std::unique_ptr init) const
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 9c5c1645eb9..90a878791df 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -89,6 +89,10 @@ public:
   std::unique_ptr &&tail_expr
   = nullptr) const;
 
+  /* Create an early return expression with an optional expression */
+  std::unique_ptr return_expr (std::unique_ptr &&to_return
+= nullptr);
+
   /* Create a let binding with an optional type and initializer (`let  :
*  = `) */
   std::unique_ptr let (std::unique_ptr pattern,
-- 
2.45.2



[COMMITTED 067/141] gccrs: session manager: Call into DesugarForLoops

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Call the visitor.
---
 gcc/rust/rust-session-manager.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 3adde297a4e..fabb3d426cd 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -18,6 +18,7 @@
 
 #include "rust-session-manager.h"
 #include "rust-collect-lang-items.h"
+#include "rust-desugar-for-loops.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-pattern-analysis.h"
 #include "rust-immutable-name-resolution-context.h"
@@ -614,6 +615,9 @@ Session::compile_crate (const char *filename)
   // expansion pipeline stage
 
   expansion (parsed_crate, name_resolution_ctx);
+
+  AST::DesugarForLoops ().go (parsed_crate);
+
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
   if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
 {
-- 
2.45.2



[PATCH] PR middle-end/119442: expr.cc: Fix vec_duplicate into vector boolean modes

2025-03-24 Thread Kyrylo Tkachov
Hi all,

In this testcase GCC tries to expand a VNx4BI vector:
vector(4)  _40;
_39 = () _24;
_40 = {_39, _39, _39, _39};

This ends up in a scalarised sequence of bitfield insert operations.
This is despite the fact that AArch64 provides a vec_duplicate pattern
specifically for vec_duplicate into VNx4BI.

The store_constructor code is overly conservative when trying vec_duplicate
as it sees a requested VNx4BImode and an element mode of QImode, which I guess
is the storage mode of BImode objects.

The vec_duplicate expander in aarch64-sve.md explicitly allows QImode element
modes so it should be safe to use it. This patch extends that mode check
to allow such expanders.

The testcase is heavily auto-reduced from a real application but in itself is
nonsensical, but it does demonstrate the current problematic codegen.

This the testcase goes from:
pfalse p15.b
str p15, [sp, #6, mul vl]
mov w0, 0
ldr w2, [sp, 12]
bfi w2, w0, 0, 4
uxtw x2, w2
bfi w2, w0, 4, 4
uxtw x2, w2
bfi w2, w0, 8, 4
uxtw x2, w2
bfi w2, w0, 12, 4
str w2, [sp, 12]
ldr p15, [sp, #6, mul vl]

into:
whilelo p15.s, wzr, wzr

The whilelo could be optimised away into a pfalse of course, but the important
part is that the bfis are gone.

Bootstrapped and tested on aarch64-none-linux-gnu.

Given this a regression from GCC 13 is this ok for trunk now?
Thanks,
Kyrill

Signed-off-by: Kyrylo Tkachov 

gcc/

PR middle-end/119442
* expr.cc (store_constructor): Also allow element modes explicitly
accepted by target vec_duplicate pattern.

gcc/testsuite/

PR middle-end/119442
* gcc.target/aarch64/vls_sve_vec_dup_1.c: New test.



0001-PR-middle-end-119442-expr.cc-Fix-vec_duplicate-into-.patch
Description: 0001-PR-middle-end-119442-expr.cc-Fix-vec_duplicate-into-.patch


[COMMITTED 065/141] gccrs: ast: builder: Fix arguments of Builder::let

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Mark all arguments as &&.
* ast/rust-ast-builder.cc (Builder::let): Likewise.
---
 gcc/rust/ast/rust-ast-builder.cc | 4 ++--
 gcc/rust/ast/rust-ast-builder.h  | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 4c42b5bddae..369f5a44630 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -306,8 +306,8 @@ Builder::return_expr (std::unique_ptr &&to_return)
 }
 
 std::unique_ptr
-Builder::let (std::unique_ptr pattern, std::unique_ptr type,
- std::unique_ptr init) const
+Builder::let (std::unique_ptr &&pattern, std::unique_ptr &&type,
+ std::unique_ptr &&init) const
 {
   return std::unique_ptr (new LetStmt (std::move (pattern),
 std::move (init), std::move (type),
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 21da13f14c8..99ab1610ce7 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -95,9 +95,9 @@ public:
 
   /* Create a let binding with an optional type and initializer (`let  :
*  = `) */
-  std::unique_ptr let (std::unique_ptr pattern,
-std::unique_ptr type = nullptr,
-std::unique_ptr init = nullptr) const;
+  std::unique_ptr let (std::unique_ptr &&pattern,
+std::unique_ptr &&type = nullptr,
+std::unique_ptr &&init = nullptr) const;
 
   /**
* Create a call expression to a function, struct or enum variant, given its
-- 
2.45.2



[COMMITTED 038/141] gccrs: add support for ref literal patterns

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Fixes Rust-GCC#3174

gcc/rust/ChangeLog:

* backend/rust-compile-pattern.cc (CompilePatternBindings::visit): make 
recursive
* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): 
handle ref flag

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3174.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-pattern.cc  | 18 
 .../typecheck/rust-hir-type-check-pattern.cc  | 13 +++--
 gcc/testsuite/rust/compile/issue-3174.rs  | 28 +++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 4 files changed, 52 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3174.rs

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 4e352fd3da3..e83717b378b 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -481,8 +481,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern 
&pattern)
  tuple_field_index++,
  pattern->get_locus ());
 
-   ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+   CompilePatternBindings::Compile (*pattern, binding, ctx);
  }
  }
else
@@ -497,8 +496,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern 
&pattern)
  tuple_field_index++,
  pattern->get_locus ());
 
-   ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+   CompilePatternBindings::Compile (*pattern, binding, ctx);
  }
  }
   }
@@ -607,8 +605,16 @@ CompilePatternBindings::visit (HIR::ReferencePattern 
&pattern)
 void
 CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
 {
-  ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
-  match_scrutinee_expr);
+  if (!pattern.get_is_ref ())
+{
+  ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
+  match_scrutinee_expr);
+  return;
+}
+
+  tree ref = address_expression (match_scrutinee_expr,
+EXPR_LOCATION (match_scrutinee_expr));
+  ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (), ref);
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index a118d1537f8..ac43eaafacf 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -519,9 +519,18 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
 }
 
 void
-TypeCheckPattern::visit (HIR::IdentifierPattern &)
+TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
 {
-  infered = parent;
+  if (!pattern.get_is_ref ())
+{
+  infered = parent;
+  return;
+}
+
+  infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
+TyTy::TyVar (parent->get_ref ()),
+pattern.is_mut () ? Mutability::Mut
+  : Mutability::Imm);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/issue-3174.rs 
b/gcc/testsuite/rust/compile/issue-3174.rs
new file mode 100644
index 000..87588e1ed24
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3174.rs
@@ -0,0 +1,28 @@
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+enum Option {
+Some(i32),
+None,
+}
+
+impl Option {
+fn add(&mut self) {
+match *self {
+Option::Some(ref mut a) => *a += 1,
+Option::None => {}
+}
+}
+}
+
+fn main() {
+unsafe {
+let mut a = Option::None;
+a.add();
+let _s = "%d\n\0";
+let _s = _s as *const str;
+let s = _s as *const i8;
+printf(s, a);
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index c5c7326500d..e5e5c12a978 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -150,4 +150,5 @@ issue-2953-1.rs
 issue-3030.rs
 traits12.rs
 try-trait.rs
+issue-3174.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 052/141] gccrs: Fix bug in type resolution of paths

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc
(Early::resolve_glob_import): Use
NameResolutionContext::resolve_path instead of
ForeverStack::resolve_path.
(Early::visit): Likewise.
(Early::visit_attributes): Likewise.
* resolve/rust-early-name-resolver-2.0.h
(Early::resolve_path_in_all_ns): Likewise.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Likewise, insert segment resolutions not
handled by NameResolutionContext::resolve_path, and avoid throwing
an error when path resolution could be finished by the typechecker.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::resolve_path): Add.
* typecheck/rust-hir-type-check-path.cc
(TypeCheckExpr::resolve_root_path): Use segment node ids instead
of the path node id to look up segment resolutions when using
the 2.0 resolver, as is done with the 1.0 resolver.
* typecheck/rust-hir-type-check-type.cc
(TypeCheckType::resolve_root_path): Likewise.
* resolve/rust-forever-stack.h
(ForeverStack::resolve_path): Add callback parameter for
inserting segment resolutions.
(ForeverStack::find_starting_point): Likewise.
(ForeverStack::resolve_segments): Likewise.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Likewise.
(ForeverStack::resolve_segments): Likewise.
(ForeverStack::resolve_path): Likewise and avoid resolving
inside TraitOrImpl ribs.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 13 ++---
 .../resolve/rust-early-name-resolver-2.0.h|  9 ++--
 gcc/rust/resolve/rust-forever-stack.h | 18 ---
 gcc/rust/resolve/rust-forever-stack.hxx   | 48 +++
 .../resolve/rust-late-name-resolver-2.0.cc| 36 --
 .../resolve/rust-name-resolution-context.h| 40 
 .../typecheck/rust-hir-type-check-path.cc |  5 +-
 .../typecheck/rust-hir-type-check-type.cc |  2 +-
 gcc/testsuite/rust/compile/nr2/exclude| 29 ---
 9 files changed, 128 insertions(+), 72 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 342f1027273..d1e7ee0c9f8 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -74,7 +74,8 @@ Early::go (AST::Crate &crate)
 bool
 Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
 {
-  auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
+  auto resolved
+= ctx.resolve_path (glob.to_resolve.get_segments (), Namespace::Types);
   if (!resolved.has_value ())
 return false;
 
@@ -259,7 +260,7 @@ Early::visit (AST::MacroInvocation &invoc)
   // we won't have changed `definition` from `nullopt` if there are more
   // than one segments in our path
   if (!definition.has_value ())
-definition = ctx.macros.resolve_path (path.get_segments ());
+definition = ctx.resolve_path (path.get_segments (), Namespace::Macros);
 
   // if the definition still does not have a value, then it's an error
   if (!definition.has_value ())
@@ -300,8 +301,8 @@ Early::visit_attributes (std::vector &attrs)
  auto traits = attr.get_traits_to_derive ();
  for (auto &trait : traits)
{
- auto definition
-   = ctx.macros.resolve_path (trait.get ().get_segments ());
+ auto definition = ctx.resolve_path (trait.get ().get_segments (),
+ Namespace::Macros);
  if (!definition.has_value ())
{
  // FIXME: Change to proper error message
@@ -324,8 +325,8 @@ Early::visit_attributes (std::vector &attrs)
 ->lookup_builtin (name)
 .is_error ()) // Do not resolve builtins
{
- auto definition
-   = ctx.macros.resolve_path (attr.get_path ().get_segments ());
+ auto definition = ctx.resolve_path (attr.get_path ().get_segments (),
+ Namespace::Macros);
  if (!definition.has_value ())
{
  // FIXME: Change to proper error message
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index a7ad0f78fb8..e309b50174c 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -227,9 +227,12 @@ private:
   };
 };
 
-ctx.values.resolve_path (segments).map (pair_with_ns (Namespace::Values));
-ctx.types.resolve_path (segments).map (pair_with_ns (Namespace::Types));
-ctx.macros.resolve_path (segments).map

[COMMITTED 053/141] gccrs: Fix ICE when fn_once and fn_once_output lang item is not defined

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We needed to check for the optional has a value here or not it leads to an
ICE.

gcc/rust/ChangeLog:

* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): add 
checks for lang items

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-tyty.cc | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index f0c967e0949..02d91b1f195 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2226,12 +2226,24 @@ void
 ClosureType::setup_fn_once_output () const
 {
   // lookup the lang items
-  auto fn_once_lang_item = LangItem::Kind::FN_ONCE;
-  auto fn_once_output_lang_item = LangItem::Kind::FN_ONCE_OUTPUT;
+  auto fn_once_lookup = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE);
+  auto fn_once_output_lookup
+= mappings.lookup_lang_item (LangItem::Kind::FN_ONCE_OUTPUT);
+  if (!fn_once_lookup)
+{
+  rust_fatal_error (UNKNOWN_LOCATION,
+   "Missing required % lang item");
+  return;
+}
+  if (!fn_once_output_lookup)
+{
+  rust_fatal_error (UNKNOWN_LOCATION,
+   "Missing required % lang item");
+  return;
+}
 
-  DefId &trait_id = mappings.lookup_lang_item (fn_once_lang_item).value ();
-  DefId &trait_item_id
-= mappings.lookup_lang_item (fn_once_output_lang_item).value ();
+  DefId &trait_id = fn_once_lookup.value ();
+  DefId &trait_item_id = fn_once_output_lookup.value ();
 
   // resolve to the trait
   HIR::Item *item = mappings.lookup_defid (trait_id).value ();
-- 
2.45.2



[COMMITTED 021/141] gccrs: hir: Add LangItem paths to PathPattern class

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* hir/tree/rust-hir-path.h: Adapt PathPattern to accept lang-item paths.
* hir/tree/rust-hir-path.cc: Assert we are dealing with a segmented 
path, create lang-item
constructors.
* hir/tree/rust-hir.cc (PathPattern::convert_to_simple_path): Likewise.
---
 gcc/rust/hir/tree/rust-hir-path.cc | 20 +++
 gcc/rust/hir/tree/rust-hir-path.h  | 86 +++---
 gcc/rust/hir/tree/rust-hir.cc  |  6 +++
 3 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-path.cc 
b/gcc/rust/hir/tree/rust-hir-path.cc
index 7db2b25b5aa..ee4a57294db 100644
--- a/gcc/rust/hir/tree/rust-hir-path.cc
+++ b/gcc/rust/hir/tree/rust-hir-path.cc
@@ -133,6 +133,8 @@ PathExprSegment::operator= (PathExprSegment const &other)
 void
 PathPattern::iterate_path_segments (std::function cb)
 {
+  rust_assert (kind == Kind::Segmented);
+
   for (auto it = segments.begin (); it != segments.end (); it++)
 {
   if (!cb (*it))
@@ -150,6 +152,15 @@ PathInExpression::PathInExpression (Analysis::NodeMapping 
mappings,
 has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
 {}
 
+PathInExpression::PathInExpression (Analysis::NodeMapping mappings,
+   LangItem::Kind lang_item, location_t locus,
+   bool has_opening_scope_resolution,
+   std::vector outer_attrs)
+  : PathPattern (lang_item),
+PathExpr (std::move (mappings), std::move (outer_attrs)),
+has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+{}
+
 bool
 PathInExpression::is_self () const
 
@@ -358,6 +369,15 @@ QualifiedPathInExpression::QualifiedPathInExpression (
 path_type (std::move (qual_path_type)), locus (locus)
 {}
 
+QualifiedPathInExpression::QualifiedPathInExpression (
+  Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+  LangItem::Kind lang_item, location_t locus,
+  std::vector outer_attrs)
+  : PathPattern (lang_item),
+PathExpr (std::move (mappings), std::move (outer_attrs)),
+path_type (std::move (qual_path_type)), locus (locus)
+{}
+
 QualifiedPathInType::QualifiedPathInType (
   Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
   std::unique_ptr associated_segment,
diff --git a/gcc/rust/hir/tree/rust-hir-path.h 
b/gcc/rust/hir/tree/rust-hir-path.h
index bbb9c2d6077..c46f81e981c 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -19,6 +19,7 @@
 #ifndef RUST_HIR_PATH_H
 #define RUST_HIR_PATH_H
 
+#include "rust-hir-map.h"
 #include "rust-hir-simple-path.h"
 #include "rust-hir-type-no-bounds.h"
 #include "rust-hir-pattern-abstract.h"
@@ -230,15 +231,34 @@ public:
 // HIR node representing a pattern that involves a "path" - abstract base class
 class PathPattern : public Pattern
 {
+public:
+  enum class Kind
+  {
+Segmented,
+LangItem
+  };
+
+private:
   std::vector segments;
+  tl::optional lang_item;
+  Kind kind;
 
 protected:
   PathPattern (std::vector segments)
-: segments (std::move (segments))
+: segments (std::move (segments)), lang_item (tl::nullopt),
+  kind (Kind::Segmented)
+  {}
+
+  PathPattern (LangItem::Kind lang_item)
+: segments ({}), lang_item (lang_item), kind (Kind::LangItem)
   {}
 
   // Returns whether path has segments.
-  bool has_segments () const { return !segments.empty (); }
+  bool has_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return !segments.empty ();
+  }
 
   /* Converts path segments to their equivalent SimplePath segments if 
possible,
* and creates a SimplePath from them. */
@@ -248,26 +268,61 @@ protected:
 public:
   /* Returns whether the path is a single segment (excluding qualified path
* initial as segment). */
-  bool is_single_segment () const { return segments.size () == 1; }
+  bool is_single_segment () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.size () == 1;
+  }
 
   std::string as_string () const override;
 
   void iterate_path_segments (std::function cb);
 
-  size_t get_num_segments () const { return segments.size (); }
+  size_t get_num_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.size ();
+  }
 
-  std::vector &get_segments () { return segments; }
+  std::vector &get_segments ()
+  {
+rust_assert (kind == Kind::Segmented);
+return segments;
+  }
 
-  const std::vector &get_segments () const { return segments; 
}
+  const std::vector &get_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments;
+  }
 
-  PathExprSegment &get_root_seg () { return segments.at (0); }
+  PathExprSegment &get_root_seg ()
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.at (0);
+  }
+
+  const PathExprSegment &get_final_segment () const
+  {
+rust_assert (kind == Kind::Segmented)

[COMMITTED 027/141] gccrs: Add debug dump to old name resolver

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

It might be necessary to compare both name resolution' internal states
during the transition. This new debug representation could help with
that.

gcc/rust/ChangeLog:

* resolve/rust-name-resolver.h: Add new degug dump for old name
resolver.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-name-resolver.h | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/gcc/rust/resolve/rust-name-resolver.h 
b/gcc/rust/resolve/rust-name-resolver.h
index 43b79e51005..a3b34a9f160 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -204,6 +204,41 @@ public:
   void insert_captured_item (NodeId id);
   const std::set &get_captures (NodeId id) const;
 
+  std::string as_debug_string () const
+  {
+std::stringstream ss;
+
+ss << "Names:\n";
+for (auto &n : name_ribs)
+  {
+   ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+  << "\n";
+  }
+ss << "Types:\n";
+for (auto &n : type_ribs)
+  {
+   ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+  << "\n";
+  }
+ss << "Macros:\n";
+
+for (auto &n : macro_ribs)
+  {
+   ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+  << "\n";
+  }
+
+ss << "Labels:\n";
+
+for (auto &n : label_ribs)
+  {
+   ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str ()
+  << "\n";
+  }
+
+return ss.str ();
+  }
+
 protected:
   bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id,
   const Scope &scope);
-- 
2.45.2



[COMMITTED 029/141] gccrs: Remove query mode on CompileItem

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Query mode was a hack to catch up some compile errors early, it was
deemed to be removed at some time. Recent changes to NR1 highlighted
an incompatibility with it hence it's removal.

gcc/rust/ChangeLog:

* backend/rust-compile-item.h: Remove query mode.
* backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile):
Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-item.h  | 6 ++
 gcc/rust/backend/rust-compile-resolve-path.cc | 6 ++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-item.h 
b/gcc/rust/backend/rust-compile-item.h
index efc65fe0d5e..eccb040bc93 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -31,15 +31,13 @@ protected:
 public:
   static tree compile (HIR::Item *item, Context *ctx,
   TyTy::BaseType *concrete = nullptr,
-  bool is_query_mode = false,
   location_t ref_locus = UNDEF_LOCATION)
   {
 CompileItem 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 item: %s",
- item->as_string ().c_str ());
+if (compiler.reference == error_mark_node)
+  rust_debug ("failed to compile 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 6ede1bea22f..a40f5542a68 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -240,11 +240,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
   if (auto resolved_item = ctx->get_mappings ().lookup_hir_item (ref))
 {
   if (!lookup->has_substitutions_defined ())
-   return CompileItem::compile (*resolved_item, ctx, nullptr, true,
-expr_locus);
+   return CompileItem::compile (*resolved_item, ctx, nullptr, expr_locus);
   else
-   return CompileItem::compile (*resolved_item, ctx, lookup, true,
-expr_locus);
+   return CompileItem::compile (*resolved_item, ctx, lookup, expr_locus);
 }
   else if (auto hir_extern_item
   = ctx->get_mappings ().lookup_hir_extern_item (ref))
-- 
2.45.2



[COMMITTED 056/141] gccrs: Fix crash in privay reporter for placeholder types

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This guards against a crash but i think this should actually be treated
as if its a generic type like below. But for now this addresses a crash which 
can occur.

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::check_base_type_privacy):
Add guard for placeholder

Signed-off-by: Philip Herron 
---
 .../checks/errors/privacy/rust-privacy-reporter.cc | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index dcc7681..896c1c449ab 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -243,10 +243,12 @@ PrivacyReporter::check_base_type_privacy 
(Analysis::NodeMapping &node_mappings,
   static_cast (ty)->get_fields ())
recursive_check (param.get_tyty ());
   return;
-case TyTy::PLACEHOLDER:
-  return recursive_check (
-   // FIXME: Can we use `resolve` here? Is that what we should do?
-   static_cast (ty)->resolve ());
+  case TyTy::PLACEHOLDER: {
+   const auto p = static_cast (ty);
+   if (!p->can_resolve ())
+ return;
+   return recursive_check (p->resolve ());
+  }
 case TyTy::PROJECTION:
   return recursive_check (
static_cast (ty)->get ());
-- 
2.45.2



[COMMITTED 057/141] gccrs: Fix bad generic substitution error on fn/adt types

2025-03-24 Thread arthur . cohen
From: Philip Herron 

When passing generics around we try to adjust them because there are cases
where the names are adjusted from other generics this can fail for traits
because of the implicit Self and we just need to continue on without
adjustment.

Fxies Rust-GCC#3382

gcc/rust/ChangeLog:

* typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit):
continue on for trait item mode.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this.
* rust/compile/issue-3382.rs: New test.

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-substitution-mapper.cc |  8 ++-
 gcc/testsuite/rust/compile/issue-3382.rs  | 61 +++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 3 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3382.rs

diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc 
b/gcc/rust/typecheck/rust-substitution-mapper.cc
index dbf49bef5b7..1e151577180 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -192,8 +192,10 @@ SubstMapperInternal::visit (TyTy::FnType &type)
 {
   TyTy::SubstitutionArgumentMappings adjusted
 = type.adjust_mappings_for_this (mappings);
-  if (adjusted.is_error ())
+  if (adjusted.is_error () && !mappings.trait_item_mode ())
 return;
+  if (adjusted.is_error () && mappings.trait_item_mode ())
+adjusted = mappings;
 
   TyTy::BaseType *concrete = type.handle_substitions (adjusted);
   if (concrete != nullptr)
@@ -205,8 +207,10 @@ SubstMapperInternal::visit (TyTy::ADTType &type)
 {
   TyTy::SubstitutionArgumentMappings adjusted
 = type.adjust_mappings_for_this (mappings);
-  if (adjusted.is_error ())
+  if (adjusted.is_error () && !mappings.trait_item_mode ())
 return;
+  if (adjusted.is_error () && mappings.trait_item_mode ())
+adjusted = mappings;
 
   TyTy::BaseType *concrete = type.handle_substitions (adjusted);
   if (concrete != nullptr)
diff --git a/gcc/testsuite/rust/compile/issue-3382.rs 
b/gcc/testsuite/rust/compile/issue-3382.rs
new file mode 100644
index 000..6f4382f1b52
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3382.rs
@@ -0,0 +1,61 @@
+#[lang = "sized"]
+trait Sized {}
+
+enum Result {
+#[lang = "Ok"]
+Ok(T),
+#[lang = "Err"]
+Err(E),
+}
+
+#[lang = "try"]
+pub trait Try {
+/// The type of this value when viewed as successful.
+// #[unstable(feature = "try_trait", issue = "42327")]
+type Ok;
+/// The type of this value when viewed as failed.
+// #[unstable(feature = "try_trait", issue = "42327")]
+type Error;
+
+/// Applies the "?" operator. A return of `Ok(t)` means that the
+/// execution should continue normally, and the result of `?` is the
+/// value `t`. A return of `Err(e)` means that execution should branch
+/// to the innermost enclosing `catch`, or return from the function.
+///
+/// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+/// in the return type of the enclosing scope (which must itself implement
+/// `Try`). Specifically, the value `X::from_error(From::from(e))`
+/// is returned, where `X` is the return type of the enclosing function.
+#[lang = "into_result"]
+#[unstable(feature = "try_trait", issue = "42327")]
+fn into_result(self) -> Result;
+
+/// Wrap an error value to construct the composite result. For example,
+/// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+#[lang = "from_error"]
+#[unstable(feature = "try_trait", issue = "42327")]
+fn from_error(v: Self::Ok) -> Self;
+
+/// Wrap an OK value to construct the composite result. For example,
+/// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+#[lang = "from_ok"]
+#[unstable(feature = "try_trait", issue = "42327")]
+fn from_ok(v: Self::Error) -> Self;
+}
+
+impl Try for Result {
+type Ok = T;
+type Error = E;
+
+fn into_result(self) -> Result {
+self
+}
+
+fn from_ok(v: T) -> Self {
+Result::Ok(v)
+}
+
+fn from_error(v: E) -> Self {
+Result::Err(v)
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 29d6e21b773..8229b541bbc 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -123,4 +123,5 @@ issue-3030.rs
 traits12.rs
 try-trait.rs
 derive-debug1.rs
+issue-3382.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 059/141] gccrs: ast-builder: Add methods for QualifiedPathInExpressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::qualified_path_in_expression): New.
(Builder::function): Change the return type.
* ast/rust-ast-builder.h: Declare qualified_path_in_expression 
functions.
* expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Adapt to 
new APIs.
---
 gcc/rust/ast/rust-ast-builder.cc | 32 +++-
 gcc/rust/ast/rust-ast-builder.h  | 16 +++---
 gcc/rust/expand/rust-derive-debug.cc |  4 ++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index aef0e110ce0..4c42b5bddae 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -64,6 +64,27 @@ Builder::array (std::vector> 
&&members) const
   return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc));
 }
 
+std::unique_ptr
+Builder::qualified_path_in_expression (std::unique_ptr &&type,
+  TypePath trait,
+  PathExprSegment segment) const
+{
+  auto segments = {segment};
+
+  return qualified_path_in_expression (std::move (type), trait, segments);
+}
+
+std::unique_ptr
+Builder::qualified_path_in_expression (
+  std::unique_ptr &&type, TypePath trait,
+  std::vector &&segments) const
+{
+  auto qual_type = QualifiedPathType (std::move (type), loc, trait);
+
+  return std::unique_ptr (
+new QualifiedPathInExpression (qual_type, std::move (segments), {}, loc));
+}
+
 std::unique_ptr
 Builder::identifier (std::string name) const
 {
@@ -111,17 +132,18 @@ Builder::fn_qualifiers () const
   return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
 }
 
-Function
-Builder::function (Identifier function_name,
+std::unique_ptr
+Builder::function (std::string function_name,
   std::vector> params,
   std::unique_ptr return_type,
   std::unique_ptr block,
   FunctionQualifiers qualifiers, WhereClause where_clause,
   Visibility visibility) const
 {
-  return Function (function_name, qualifiers, {}, std::move (params),
-  std::move (return_type), where_clause, std::move (block),
-  visibility, {}, loc);
+  return std::unique_ptr (
+new Function (function_name, qualifiers, {}, std::move (params),
+ std::move (return_type), where_clause, std::move (block),
+ visibility, {}, loc));
 }
 
 PathExprSegment
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 90a878791df..21da13f14c8 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -104,7 +104,8 @@ public:
* arguments (`path(arg0, arg1, arg2)`)
*/
   std::unique_ptr call (std::unique_ptr &&path,
- std::vector> &&args) const;
+ std::vector> &&args
+ = {}) const;
   std::unique_ptr call (std::unique_ptr &&path,
  std::unique_ptr &&arg) const;
 
@@ -114,6 +115,15 @@ public:
   std::unique_ptr
   array (std::vector> &&members) const;
 
+  /* Create a qualified path in expression (`::seg::expr`) */
+  std::unique_ptr
+  qualified_path_in_expression (std::unique_ptr &&type, TypePath trait,
+   PathExprSegment segment) const;
+  std::unique_ptr
+  qualified_path_in_expression (std::unique_ptr &&type, TypePath trait,
+   std::vector &&segments
+   = {}) const;
+
   /* Self parameter for a function definition (`&self`) */
   std::unique_ptr self_ref_param (bool mutability = false) const;
   /* A regular named function parameter for a definition (`a: type`) */
@@ -123,8 +133,8 @@ public:
   /* Empty function qualifiers, with no specific qualifiers */
   FunctionQualifiers fn_qualifiers () const;
 
-  Function
-  function (Identifier function_name,
+  std::unique_ptr
+  function (std::string function_name,
std::vector> params,
std::unique_ptr return_type, std::unique_ptr block,
FunctionQualifiers qualifiers
diff --git a/gcc/rust/expand/rust-derive-debug.cc 
b/gcc/rust/expand/rust-derive-debug.cc
index 910f27c67b2..f37547459a0 100644
--- a/gcc/rust/expand/rust-derive-debug.cc
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -77,10 +77,10 @@ DeriveDebug::stub_debug_fn ()
 
   auto params = vec (std::move (self), std::move (fmt));
 
-  auto function = builder.function ({"fmt"}, std::move (params),
+  auto function = builder.function ("fmt", std::move (params),
std::move (return_type), std::move (block));
 
-  return ptrify (function);
+  return function;
 }
 
 std::unique_ptr
-- 
2.45.2



[COMMITTED 026/141] gccrs: Labels shall be pushed within label namespace

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Labels were using the wrong namespace.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Change label
push function from type rib to label rib.
* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
Likewise.
(ResolveItem::visit): Likewise.
(ResolveExternItem::visit): Likewise.
* resolve/rust-ast-resolve-stmt.h: Likewise.
* resolve/rust-ast-resolve.cc (NameResolution::go): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc | 14 +++---
 gcc/rust/resolve/rust-ast-resolve-item.cc | 10 +-
 gcc/rust/resolve/rust-ast-resolve-stmt.h  |  2 +-
 gcc/rust/resolve/rust-ast-resolve.cc  |  2 +-
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc 
b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 9d5d00fa6a2..be960beccd5 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -209,7 +209,7 @@ ResolveExpr::visit (AST::IfLetExpr &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   // We know expr.get_patterns () has one pattern at most
   // so there's no reason to handle it like an AltPattern.
@@ -239,7 +239,7 @@ ResolveExpr::visit (AST::IfLetExprConseqElse &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   // We know expr.get_patterns () has one pattern at most
   // so there's no reason to handle it like an AltPattern.
@@ -268,7 +268,7 @@ ResolveExpr::visit (AST::BlockExpr &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   if (expr.has_label ())
 {
@@ -576,7 +576,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   // resolve the expression
   PatternDeclaration::go (expr.get_pattern (), Rib::ItemType::Var);
@@ -642,7 +642,7 @@ ResolveExpr::visit (AST::MatchExpr &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   // resolve
   AST::MatchArm &arm = match_case.get_arm ();
@@ -711,7 +711,7 @@ ResolveExpr::visit (AST::ClosureExprInner &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   std::vector bindings
 = {PatternBinding (PatternBoundCtx::Product, std::set ())};
@@ -741,7 +741,7 @@ ResolveExpr::visit (AST::ClosureExprInnerTyped &expr)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   std::vector bindings
 = {PatternBinding (PatternBoundCtx::Product, std::set ())};
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index b26ac340e92..cecc8ad6857 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -61,7 +61,7 @@ ResolveTraitItems::visit (AST::Function &function)
   resolver->get_label_scope ().push (scope_node_id);
   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
   resolver->push_new_type_

[COMMITTED 019/141] gccrs: lang-items: Add LangItem::IsEnumVariant

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* util/rust-lang-item.cc (LangItem::IsEnumVariant): New function.
* util/rust-lang-item.h: Declare it.
---
 gcc/rust/util/rust-lang-item.cc | 9 +
 gcc/rust/util/rust-lang-item.h  | 5 -
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index ac90f979e83..b37a237c24e 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -248,4 +248,13 @@ LangItem::NegationOperatorToLangItem (NegationOperator op)
   rust_unreachable ();
 }
 
+bool
+LangItem::IsEnumVariant (LangItem::Kind type)
+{
+  const static std::set enum_variants
+= {Kind::OPTION_NONE, Kind::OPTION_SOME, Kind::RESULT_OK, 
Kind::RESULT_ERR};
+
+  return enum_variants.find (type) != enum_variants.end ();
+}
+
 } // namespace Rust
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index ad081a7d3fb..851909d409c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -146,15 +146,18 @@ public:
   static const BiMap lang_items;
 
   static tl::optional Parse (const std::string &item);
+
   static std::string ToString (Kind type);
   static std::string PrettyString (Kind type);
+
   static Kind OperatorToLangItem (ArithmeticOrLogicalOperator op);
   static Kind
   CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op);
   static Kind NegationOperatorToLangItem (NegationOperator op);
   static Kind ComparisonToLangItem (ComparisonOperator op);
-
   static std::string ComparisonToSegment (ComparisonOperator op);
+
+  static bool IsEnumVariant (Kind type);
 };
 
 } // namespace Rust
-- 
2.45.2



[COMMITTED 060/141] gccrs: derive(Default): Add implementation

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive.cc (DeriveVisitor::derive): Call DeriveDefault.
* expand/rust-derive-default.cc: New file.
* expand/rust-derive-default.h: New file.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/derive-default1.rs: New test.
* rust/execute/torture/derive-default1.rs: New test.
* rust/compile/nr2/exclude: Exclude them.
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/expand/rust-derive-default.cc| 173 ++
 gcc/rust/expand/rust-derive-default.h |  58 ++
 gcc/rust/expand/rust-derive.cc|   2 +
 gcc/testsuite/rust/compile/derive-default1.rs |  29 +++
 gcc/testsuite/rust/compile/nr2/exclude|   1 +
 .../rust/execute/torture/derive-default1.rs   |  26 +++
 7 files changed, 290 insertions(+)
 create mode 100644 gcc/rust/expand/rust-derive-default.cc
 create mode 100644 gcc/rust/expand/rust-derive-default.h
 create mode 100644 gcc/testsuite/rust/compile/derive-default1.rs
 create mode 100644 gcc/testsuite/rust/execute/torture/derive-default1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index bc58a341131..24054531d9e 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -97,6 +97,7 @@ GRS_OBJS = \
 rust/rust-derive-clone.o \
 rust/rust-derive-copy.o \
 rust/rust-derive-debug.o \
+rust/rust-derive-default.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
 rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-default.cc 
b/gcc/rust/expand/rust-derive-default.cc
new file mode 100644
index 000..c54f8c318dd
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-default.cc
@@ -0,0 +1,173 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-default.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
+#include "rust-path.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveDefault::DeriveDefault (location_t loc)
+  : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr
+DeriveDefault::go (Item &item)
+{
+  item.accept_vis (*this);
+
+  rust_assert (expanded);
+
+  return std::move (expanded);
+}
+
+std::unique_ptr
+DeriveDefault::default_call (std::unique_ptr &&type)
+{
+  auto default_trait = builder.type_path ({"core", "default", "Default"}, 
true);
+
+  auto default_fn
+= builder.qualified_path_in_expression (std::move (type), default_trait,
+   builder.path_segment ("default"));
+
+  return builder.call (std::move (default_fn));
+}
+
+std::unique_ptr
+DeriveDefault::default_fn (std::unique_ptr &&return_expr)
+{
+  auto self_ty
+= std::unique_ptr (new TypePath (builder.type_path ("Self")));
+
+  auto block = std::unique_ptr (
+new BlockExpr ({}, std::move (return_expr), {}, {},
+  AST::LoopLabel::error (), loc, loc));
+
+  return builder.function ("default", {}, std::move (self_ty),
+  std::move (block));
+}
+
+std::unique_ptr
+DeriveDefault::default_impl (
+  std::unique_ptr &&default_fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto default_path = builder.type_path ({"core", "default", "Default"}, true);
+
+  auto trait_items = vec (std::move (default_fn));
+
+  auto generics = setup_impl_generics (name, type_generics,
+  builder.trait_bound (default_path));
+
+  return builder.trait_impl (default_path, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
+}
+
+void
+DeriveDefault::visit_struct (StructStruct &item)
+{
+  if (item.is_unit_struct ())
+{
+  auto unit_ctor
+   = builder.struct_expr_struct (item.get_struct_name ().as_string ());
+  expanded = default_impl (default_fn (std::move (unit_ctor)),
+  item.get_struct_name ().as_string (),
+  item.get_generic_params ());
+  return;
+}
+
+  auto cloned_fields = std::vector> ();
+  for (auto &field : item.get_fields ())
+{
+  auto name = field.get_field_name ().as_string ();
+  auto expr = default_call (field.get_field_ty

[COMMITTED 072/141] gccrs: enum type layout needs to respect the enum repr type

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Addresses Rust-GCC#3352

gcc/rust/ChangeLog:

* backend/rust-compile-type.cc 
(TyTyResolveCompile::get_implicit_enumeral_node_type):
use repr
(TyTyResolveCompile::visit): update prototype
* backend/rust-compile-type.h: likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-type.cc | 16 
 gcc/rust/backend/rust-compile-type.h  |  3 +--
 2 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 85e78658335..74368a29f49 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -55,7 +55,7 @@ TyTyResolveCompile::compile (Context *ctx, const 
TyTy::BaseType *ty,
 // see: gcc/c/c-decl.cc:8230-8241
 // 
https://github.com/Rust-GCC/gccrs/blob/0024bc2f028369b871a65ceb11b2fddfb0f9c3aa/gcc/c/c-decl.c#L8229-L8241
 tree
-TyTyResolveCompile::get_implicit_enumeral_node_type ()
+TyTyResolveCompile::get_implicit_enumeral_node_type (TyTy::BaseType *repr)
 {
   // static tree enum_node = NULL_TREE;
   // if (enum_node == NULL_TREE)
@@ -77,15 +77,7 @@ TyTyResolveCompile::get_implicit_enumeral_node_type ()
   //   }
   // return enum_node;
 
-  static tree enum_node = NULL_TREE;
-  if (enum_node == NULL_TREE)
-{
-  // equivalent to isize
-  enum_node = Backend::named_type (
-   "enumeral", Backend::integer_type (false, Backend::get_pointer_size ()),
-   BUILTINS_LOCATION);
-}
-  return enum_node;
+  return compile (ctx, repr);
 }
 
 tree
@@ -384,8 +376,8 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
= Backend::named_type ("payload", variants_union, locus);
 
   // create the overall struct
-  tree enumeral_type
-   = TyTyResolveCompile::get_implicit_enumeral_node_type ();
+  tree enumeral_type = TyTyResolveCompile::get_implicit_enumeral_node_type 
(
+   type.get_repr_options ().repr);
   Backend::typed_identifier discrim (RUST_ENUM_DISR_FIELD_NAME,
 enumeral_type, locus);
   Backend::typed_identifier variants_union_field ("payload",
diff --git a/gcc/rust/backend/rust-compile-type.h 
b/gcc/rust/backend/rust-compile-type.h
index e01ca430d45..398d7f8bda9 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -30,8 +30,6 @@ public:
   static tree compile (Context *ctx, const TyTy::BaseType *ty,
   bool trait_object_mode = false);
 
-  static tree get_implicit_enumeral_node_type ();
-
   static tree get_unit_type ();
 
   void visit (const TyTy::InferType &) override;
@@ -66,6 +64,7 @@ protected:
   tree create_slice_type_record (const TyTy::SliceType &type);
   tree create_str_type_record (const TyTy::StrType &type);
   tree create_dyn_obj_record (const TyTy::DynamicObjectType &type);
+  tree get_implicit_enumeral_node_type (TyTy::BaseType *repr);
 
 private:
   TyTyResolveCompile (Context *ctx, bool trait_object_mode);
-- 
2.45.2



[COMMITTED 082/141] gccrs: Add type check on if-expr

2025-03-24 Thread arthur . cohen
From: Benjamin Thos 

Check if an if-expr returns void type or a coercible type like an early return.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Add check on if-expr.

gcc/testsuite/ChangeLog:

* rust/compile/implicit_returns_err3.rs: Change test to be valid.
* rust/compile/torture/if.rs: Likewise.
* rust/compile/if-without-else.rs: New test.

Signed-off-by: Benjamin Thos 
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 13 +++--
 gcc/testsuite/rust/compile/if-without-else.rs   |  9 +
 gcc/testsuite/rust/compile/implicit_returns_err3.rs |  2 +-
 gcc/testsuite/rust/compile/torture/if.rs|  8 ++--
 4 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/if-without-else.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 85d717535ed..4e57d6a8ffb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -526,9 +526,18 @@ TypeCheckExpr::visit (HIR::IfExpr &expr)
expr.get_if_condition ().get_locus ()),
  expr.get_locus ());
 
-  TypeCheckExpr::Resolve (expr.get_if_block ());
+  TyTy::BaseType *block_type = TypeCheckExpr::Resolve (expr.get_if_block ());
 
-  infered = TyTy::TupleType::get_unit_type ();
+  TyTy::BaseType *unit_ty = nullptr;
+  ok = context->lookup_builtin ("()", &unit_ty);
+  rust_assert (ok);
+
+  infered
+= coercion_site (expr.get_mappings ().get_hirid (),
+TyTy::TyWithLocation (unit_ty),
+TyTy::TyWithLocation (block_type,
+  expr.get_if_block ().get_locus ()),
+expr.get_locus ());
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/if-without-else.rs 
b/gcc/testsuite/rust/compile/if-without-else.rs
new file mode 100644
index 000..1a0f6449d70
--- /dev/null
+++ b/gcc/testsuite/rust/compile/if-without-else.rs
@@ -0,0 +1,9 @@
+fn foo(pred: bool) -> u8 {
+if pred { // { dg-error "mismatched types" }
+1
+}
+3
+}
+
+fn main(){
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs 
b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
index ac982137798..f0330aca9c0 100644
--- a/gcc/testsuite/rust/compile/implicit_returns_err3.rs
+++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
@@ -1,6 +1,6 @@
 fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but 
got " }
 if x > 1 {
-1
+return 1;
 }
 }
 
diff --git a/gcc/testsuite/rust/compile/torture/if.rs 
b/gcc/testsuite/rust/compile/torture/if.rs
index bcd520f66a9..3b753a71eb2 100644
--- a/gcc/testsuite/rust/compile/torture/if.rs
+++ b/gcc/testsuite/rust/compile/torture/if.rs
@@ -4,6 +4,10 @@ fn foo() -> bool {
 
 fn bar() {}
 
+fn baz(a: i32) {
+a;
+}
+
 struct Foo1 {
 one: i32
 }
@@ -13,7 +17,7 @@ fn main() {
 if foo() {
 bar();
 let a = Foo1{one: 1};
-a.one
+baz (a.one);
 }
 
-}
\ No newline at end of file
+}
-- 
2.45.2



Re: [PATCH 06/10] testsuite: aarch64: arm: Add -mfpu=auto to arm_v8_2a_bf16_neon_ok

2025-03-24 Thread Christophe Lyon
On Mon, 24 Mar 2025 at 15:13, Richard Earnshaw (lists)
 wrote:
>
> On 21/03/2025 17:30, Christophe Lyon wrote:
> > On Fri, 21 Mar 2025 at 16:51, Richard Earnshaw (lists)
> >  wrote:
> >>
> >> On 21/03/2025 15:15, Christophe Lyon wrote:
> >>> On Fri, 21 Mar 2025 at 15:25, Richard Earnshaw (lists)
> >>>  wrote:
> 
>  On 21/03/2025 14:05, Christophe Lyon wrote:
> > On Fri, 21 Mar 2025 at 11:18, Richard Earnshaw (lists)
> >  wrote:
> >>
> >> On 20/03/2025 16:15, Christophe Lyon wrote:
> >>> Depending on if/how the testing flags are overridden, the first value
> >>> we try("") might not do what we want.
> >>>
> >>> For instance, if the whole testsuite is executed with
> >>> (A) -mthumb -march=armv7-m -mtune=cortex-m3 -mfloat-abi=softfp
> >>>
> >>> bf16_neon_ok is first compiled with
> >>> (A) (B)
> >>> where B = -mcpu=unset -march=armv8.2-a+bf16
> >>>
> >>> which is accepted, so a testcase like vld2q_lane_bf16_indices_1.c
> >>> is compiled with:
> >>> (A) (C) (B)
> >>> where C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a 
> >>> -mfpu=neon-fp16 -mfp16-format=ieee
> >>>
> >>> because advsimd-intrinsics.exp has set additional_flags to (C)
> >>> via arm_neon_fp16_ok
> >>>
> >>> So the testcase is compiled with
> >>> [...] -mfpu=neon-fp16 -mcpu=unset -march=armv8.2-a+bf16
> >>> (thus -mfpu=neon-fp16) and bf16 support is disabled.
> >>>
> >>> The patch replaces "" with -mfpu=auto which matches the intended
> >>> effect of -march=armv8.2-a+bf16 as added by bf16_neon_ok, and the
> >>> testcase is now compiled with
> >>> (A) (C) -mfpu=auto (B)
> >>>
> >>> However, since this effective-target is also used on aarch64 (which
> >>> does not support -mfpu=auto), we do this only on arm.
> >>>
> >>> This patch improves coverage, and makes
> >>> v{ld,st}[234]q_lane_bf16_indices_1.c pass when testsuite flags are
> >>> overridden as described above (e.g. for M-profile).
> >>>
> >>>   gcc/testsuite/
> >>>   * lib/target-supports.exp
> >>>   (check_effective_target_arm_v8_2a_bf16_neon_ok_nocache):
> >>>   Conditionally use -mfpu=auto.
> >>> ---
> >>>  gcc/testsuite/lib/target-supports.exp | 9 -
> >>>  1 file changed, 8 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/gcc/testsuite/lib/target-supports.exp 
> >>> b/gcc/testsuite/lib/target-supports.exp
> >>> index e2622a445c5..09b16a14024 100644
> >>> --- a/gcc/testsuite/lib/target-supports.exp
> >>> +++ b/gcc/testsuite/lib/target-supports.exp
> >>> @@ -6871,12 +6871,19 @@ proc add_options_for_arm_fp16fml_neon { flags 
> >>> } {
> >>>  proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } {
> >>>  global et_arm_v8_2a_bf16_neon_flags
> >>>  set et_arm_v8_2a_bf16_neon_flags ""
> >>> +set fpu_auto ""
> >>>
> >>>  if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
> >>>   return 0;
> >>>  }
> >>>
> >>> -foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" 
> >>> "-mfloat-abi=hard -mfpu=neon-fp-armv8" } {
> >>> +if { [istarget arm*-*-*] } {
> >>> + set fpu_auto "-mfpu=auto"
> >>> +}
> >>> +
> >>> +foreach flags [list "$fpu_auto" \
> >>
> >> Shouldn't we try first with "", even on Arm?  Thus
> >>foreach flags [list "" "$fpu_auto" \
> >> ...
> >>
> > I don't think so, that's why I tried to explain above.
> > "" is acceptable / accepted in arm_v8_2a_bf16_neon_ok
> > (this is (A) (B) above, where the important parts are:
> > -march=armv7-m -mcpu=unset -march=armv8.2-a+bf16
> > (so -mfpu is set to the toolchain's default)
> 
>  That's never going to work reliably.  We need to check, somewhere, the 
>  full set of options we intend to pass to the compilation.  We can't 
>  assume that separately testing if A is ok and B is ok => A + B is ok.
> 
> >>>
> >>> Hmmm I think I raised that problem years ago, because of the way the
> >>> test system is designed...
> >>>
> >
> > but then the actual testcase is compiled with additional flags (C)
> > defined by the test driver using arm_neon_fp16_ok
> > C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a
> > -mfpu=neon-fp16 -mfp16-format=ieee
> >
> > so the relevant parts of (A) (C) (B) are:
> > -march=armv7-m  -mfpu=neon -mcpu=unset -march=armv7-a -mfpu=neon-fp16
> > -mcpu=unset -march=armv8.2-a+bf16
> > which can be simplified into
> > -mfpu=neon-fp16 -march=armv8.2-a+bf16
> >
> > I think we need to start with -mfpu=auto instead of "", so that when
> > -march=armv8.2-a+bf16 takes effect, we have cancelled any other -mfpu.
> >
> 
>  Ideally a test shouldn't add any options in some test runs; that way we 
>  add some 'b

Re: [Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Harald Anlauf

Hi Thomas,

Am 24.03.25 um 22:28 schrieb Thomas Koenig:

Hi Harald,


the attached patch contains a chunk changing resolve.cc
that is neither described in the suggested commit message,
and it fails to compile here:

../../gcc-trunk/gcc/fortran/resolve.cc: In function 'void
check_c_funptr_assign_interface(gfc_expr*, gfc_expr*)':
../../gcc-trunk/gcc/fortran/resolve.cc:12248:48: error: 'gfc_expr' {aka
'struct gfc_expr'} has no member named 'is_c_interop'
12248 |   if (rhs->expr_type != EXPR_FUNCTION || !rhs->is_c_interop)
   |    ^~~~

Can you please check whether you inadvertently added something
that was not planned or tested?


I sent out the wrong version of the patch, sorry (one which contained
an intermediate stage of something I tried, and then abandoned).

Here is the one that actually in my tree, and that I regression-tested.


this is better.

Two things:

+/* Write out an interoperable function returning a function pointer. 
Better

+   handled separately.  As we know nothing about the type, assume
+   a C default return of int.  */
+
+static void
+write_funptr_fcn (gfc_symbol *sym)
+{
+  fprintf (dumpfile, "void (*%s (", sym->binding_label);

The comment does not match the code: the return type is (void *),
isn't it?

Second:

+  if (sym->ts.type == BT_DERIVED
+ && strcmp (sym->ts.u.derived->name, "c_funptr") == 0)

Wouldn't it be better to test for:

sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR

so that we do not accidentally handle a user-defined type
of same name and bind(c)?

OK with the above addressed.

Thanks for the patch!

Harald


Best regards

 Thomas







[committed] libstdc++: Add testcases for resolved bug [PR101527]

2025-03-24 Thread Jonathan Wakely
These tests were fixed by a front-end change r13-465-g4df735e01e3199 so
this just adds them to the testsuite to be sure we don't regress.

libstdc++-v3/ChangeLog:

PR libstdc++/101527
* testsuite/24_iterators/common_iterator/101527.cc: New test.
* testsuite/24_iterators/counted_iterator/101527.cc: New test.
---

Tested x86_64-linux. Pushed to trunk.

 .../24_iterators/common_iterator/101527.cc | 14 ++
 .../24_iterators/counted_iterator/101527.cc| 14 ++
 2 files changed, 28 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/24_iterators/common_iterator/101527.cc
 create mode 100644 
libstdc++-v3/testsuite/24_iterators/counted_iterator/101527.cc

diff --git a/libstdc++-v3/testsuite/24_iterators/common_iterator/101527.cc 
b/libstdc++-v3/testsuite/24_iterators/common_iterator/101527.cc
new file mode 100644
index 000..0a2a5e8dfcc
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/common_iterator/101527.cc
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++20 } }
+
+// PR libstdc++/101527
+// implementation of std::common_iterator and std::counted_iterator's
+// operator== seems to be wrong
+
+#include 
+
+bool test_pr101527()
+{
+  std::common_iterator it1;
+  std::common_iterator it2;
+  return it1 == it2;
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/counted_iterator/101527.cc 
b/libstdc++-v3/testsuite/24_iterators/counted_iterator/101527.cc
new file mode 100644
index 000..51c6e99cd77
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/counted_iterator/101527.cc
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++20 } }
+
+// PR libstdc++/101527
+// implementation of std::common_iterator and std::counted_iterator's
+// operator== seems to be wrong
+
+#include 
+
+bool test_pr101527()
+{
+  std::counted_iterator it1;
+  std::counted_iterator it2;
+  return it1 == it2;
+}
-- 
2.49.0



Re: [PATCH][RFC] [cobol] change cbl_field_data_t::etc_t::value from _Float128 to tree

2025-03-24 Thread James K. Lowden
On Thu, 20 Mar 2025 13:30:27 +0100 (CET)
Richard Biener  wrote:

> @@ -4126,7 +4137,11 @@ count:  %empty   { $$ = 0; }
> if( e ) { // verify not floating point with nonzero fraction
>   auto field = cbl_field_of(e);
>   assert(is_literal(field));
> - if( field->data.value_of() != 
> size_t(field->data.value_of()) ) {
> + REAL_VALUE_TYPE vi;
> + HOST_WIDE_INT vii = real_to_integer (TREE_REAL_CST_PTR 
> (field->data.value_of()));
> + real_from_integer (&vi, VOIDmode, vii, SIGNED);
> + if( !real_identical (TREE_REAL_CST_PTR 
> (field->data.value_of()),
> +  &vi) ) {
> nmsg++;
> error_msg(@NAME, "invalid PICTURE count '(%s)'",
>   field->data.initial );

I just want to verify this still does what we want.  We had

> - if( field->data.value_of() != size_t(field->data.value_of()) ) {

When cbl_field_t::data::value_of returned _Float128, that line compared a 
_Float128 to its value as a size_t.  If the number was negative, had a 
fractional component, or was too large, the test failed.  

Now cbl_field_t::data::value_of returns a tree.  Steps: 

1.  produce HOST_WIDE_INT vii from the tree
2.  set REAL_VALUE_TYPE vi from vii
3.  use real_identical to compare vi to the original

The comment for real_identical says it's a bitwise comparison.  That's not the 
same as saying the floating point value can be represented exactly as a size_t. 
 

If that's guaranteed to work, great, thanks.  If not, how do I test the sign, 
magnitude and fraction of the value?  


  Until now, numeric literals in the parser were represented as _Float128 and 
in the CDF (cdf.y) as int64_t.  Neither is strictly correct.  ISO says numeric 
literals are fixed-point, not floating:  

"The value of a fixed-point numeric literal is the algebraic quantity 
represented by the characters in the fixed-point numeric literal. The size of a 
fixed-point numeric literal is equal to the number of digits in the string of 
characters in the literal."

That means

01 ONE-GRAND CONSTANT 10 * 10 * 10.

should be a fixed-point value of 3 bytes with scaling factor of 0.  As of now, 
I believe we're using a tree of REAL_CST, but in the future I guess we should 
switch to FIXED_CST.  


--jkl



Re: [PATCH] vect: Add assert to expand_vector_conversion [PR118616]

2025-03-24 Thread Andrew Pinski
On Mon, Mar 24, 2025 at 2:00 AM Richard Biener
 wrote:
>
> On Sun, Mar 23, 2025 at 9:46 PM Andrew Pinski  
> wrote:
> >
> > In some cases (after inliing due to LTO and -O3), GCC cannot
> > figure out that the length of the converts vect is not empty
> > when supportable_indirect_convert_operation returns true. So
> > we get an extra warning because we loop through all but the last
> > entry and GCC decided that `converts.length () - 1` is -1. This
> > adds an checking only assert to avoid the warning and maybe even
> > produce slightly better code for this function.
>
> What about release checking then?

Thinking this over, I am going to replace gcc_checking_assert with
gcc_assert. Since we are going to load the length of the vect anyways,
checking if the vect is empty is almost free here and most likely
produce better code in general.  Since we currently don't change
gcc_checking_assert into `if(!check) __builtin_unreachable()` ( I
filed PR 119439 for that which also requires more work on the assume
attribute usage too).

Thanks,
Andrew

>
> > Bootstrapped and tested on x86_64-linux-gnu.
>
> OK.
>
> > PR tree-optimization/118616
> > gcc/ChangeLog:
> >
> > * tree-vect-generic.cc (expand_vector_conversion): Add
> > an assert that converts vect is non empty if
> > supportable_indirect_convert_operation returns true.
> >
> > Signed-off-by: Andrew Pinski 
> > ---
> >  gcc/tree-vect-generic.cc | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
> > index 173ebd9a7ba..246297ec6a9 100644
> > --- a/gcc/tree-vect-generic.cc
> > +++ b/gcc/tree-vect-generic.cc
> > @@ -1759,6 +1759,7 @@ expand_vector_conversion (gimple_stmt_iterator *gsi)
> >   converts))
> >  {
> >new_rhs = arg;
> > +  gcc_checking_assert (!converts.is_empty ());
> >for (unsigned int i = 0; i < converts.length () - 1; i++)
> > {
> >   new_lhs = make_ssa_name (converts[i].first);
> > --
> > 2.43.0
> >


Re: [PATCH, V3] PR target/118541 - Do not generate unordered fp cmoves for IEEE compares on PowerPC

2025-03-24 Thread Florian Weimer
* Michael Meissner:

> +enum reverse_cond_t {
> +  REVERSE_COND_ORDERED_OK,
> +  REVERSE_COND_NO_ORDERED
> +};

This should probably be something 
like

enum reverse_cond_t {
  ordered_ok,
  no_ordered,
};

to inhibit implicit conversion to integer types and bool.

(Completely untested.)

> +
>  extern enum rtx_code rs6000_reverse_condition (machine_mode,
> -enum rtx_code);
> +enum rtx_code,
> +enum reverse_cond_t);
>  extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
>  extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx);
>  extern void rs6000_emit_sCOND (machine_mode, rtx[]);
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index f9f9a0b931d..c2235d917ad 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -15360,17 +15360,38 @@ rs6000_print_patchable_function_entry (FILE *file,
>  }
>  
>  enum rtx_code
> -rs6000_reverse_condition (machine_mode mode, enum rtx_code code)
> +rs6000_reverse_condition (machine_mode mode,
> +   enum rtx_code code,
> +   enum reverse_cond_t ordered_cmp_ok)
>  {
>/* Reversal of FP compares takes care -- an ordered compare
> - becomes an unordered compare and vice versa.  */
> -  if (mode == CCFPmode
> -  && (!flag_finite_math_only
> -   || code == UNLT || code == UNLE || code == UNGT || code == UNGE
> -   || code == UNEQ || code == LTGT))
> -return reverse_condition_maybe_unordered (code);
> -  else
> -return reverse_condition (code);
> + becomes an unordered compare and vice versa.
> +
> + However, this is not safe for ordered comparisons (i.e. for isgreater,
> + etc.)  starting with the power9 because ifcvt.cc will want to create a 
> fp
> + cmove, and the x{s,v}cmp{eq,gt,ge}{dp,qp} instructions will trap if one 
> of
> + the arguments is a signalling NaN.  */
> +
> +  if (mode == CCFPmode)
> +{
> +  /* If NaNs are allowed, don't allow the reversal of floating point
> +  comparisons when the comparison is used in the context of a floating
> +  point conditional move when REVERSE_COND_NO_ORDERED is passed.  We do
> +  allow the comparsion to be reversed for explicit jumps when
> +  REVERSE_COND_ORDERED_OK is passed.  */
> +  if (!flag_finite_math_only)
> + return (ordered_cmp_ok == REVERSE_COND_NO_ORDERED

That would turn into

  ordered_cmp_ok == reverse_cond_t::no_ordered

(Note that identifiers ending in _t are reserved by POSIX.)


[committed] libgomp: Save OpenMP device number when initializing the interop object (was: [Patch] libgomp/plugin/plugin-nvptx.c: Fix device used for stream creation)

2025-03-24 Thread Tobias Burnus

Hi Thomas,

Short answer: both are about devices, but otherwise
completely separate.

And: Thanks for testing and the report, which shows that
having at least one system with multiple GPUs makes sense!

* * *

Attached patch fixes the here reported issue by setting
the device number - which feature wise got lost when
implementing the feature.

Committed asr15-8870-g4d5d1a7326c850

* * *

Longer version:

Thomas Schwinge wrote:


Earlier today, I happened to be testing current OG14 branch.  On a
multi-Nvidia GPU system, I saw:

...

 Running on the nvptx device (0)
 interop-fr-1.exe: [...]/libgomp.c/interop-fr-1.c:287: check_nvptx: 
Assertion `dev_num == dev' failed.

...

 282int dev_num = (int) omp_get_interop_int (obj, omp_ipr_device_num, 
&ret_code);


Somehow, setting 'obj->device_num = devicep->target_id;' got lost
between writing the WIP patch and the real patch ...

(Albeit I think there was never actual written code that did set it.)

As the memory is calloc'ed, it will work for device == 0,
which is the first non-host device (= the one GPU). And as
the host is unsupported, it will return NULL (→ omp_interop_none)
such that the issue cannot occur for the host.

* * *

Regarding the other patch, committed earlier today:


libgomp/plugin/plugin-nvptx.c: Fix device used for stream creation


... "just" ensures that the pointer (cuStream) for the right device is 
returned.


This is only detectable when actually using the stream (i.e. calling 
CUDA API functions) and the default / specified device has not the 
OpenMP device number 0.


So far, we do not have such a test case: The OpenMP one uses the default 
device and relies on being the same on CUDA and on the host.


This makes only a difference when the testcase actually uses the 
returned CUDA context or device stream. The context was already handled, 
the stream creation hasn't.


Something to check in a future testcase.

Tobiascommit 4d5d1a7326c8509a4a6fc94eedc3ba22d68f806f
Author: Tobias Burnus 
Date:   Mon Mar 24 19:52:10 2025 +0100

libgomp: Save OpenMP device number when initializing the interop object

The interop object (opaque object to the user, used internally in libgomp)
already had a 'device_num' member, but it was missed to actually set it.

libgomp/ChangeLog:

* target.c (gomp_interop_internal): Set the 'device_num' member
when initializing an interop object.
---
 libgomp/target.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libgomp/target.c b/libgomp/target.c
index 36ed797b0a9..a64ee96af2a 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -5324,6 +5324,7 @@ gomp_interop_internal (void *data)
 	}
 	  *obj =
 	(struct interop_obj_t *) calloc (1, sizeof (struct interop_obj_t));
+	  (*obj)->device_num = devicep->target_id;
 	  devicep->interop_func (*obj, devicep->target_id,
  gomp_interop_flag_init, targetsync,
  prefer_type);


RE: [PATCH 2/2] [COBOL] Remove unused _Float128 using helpers

2025-03-24 Thread Robert Dubner
Jim will be ready with some additional changes Tuesday morning.  Those
will be on top of the entire Pile O'Patches that were mostly authored by
you and Jakub.  

I'll prepare the commit for the whole shebang when he's done.



> -Original Message-
> From: Richard Biener 
> Sent: Monday, March 24, 2025 09:46
> To: gcc-patches@gcc.gnu.org
> Cc: rdub...@symas.com
> Subject: [PATCH 2/2] [COBOL] Remove unused _Float128 using helpers
> 
> 
> Tested on x86_64-unknown-linux-gnu.
> 
> The only remaining _Float128 use is now via the strtof128 inline
> which is used in two places to commpute the end of a numeric
> literal and verify against the parsed end(?) to do diagnostics.
> I'm not sure why or whether this is necessary - I'd have expected
> lexing to number tokens and then parsing to diagnose unwanted
> characters?  So my preference would be to remove the diagnostic
> and where number parsing support error reporting assert that all
> lexed numbers can be handled by them.  In any case test coverage
> would be nice to have here.
> 
> OK?
> 
> Thanks,
> Richard.
> 
>   * symbols.h (cbl_field_t::value_set): Remove.
>   (strfromf128): Remove.
>   * parse.y (cbl_field_t::value_set): Remove.
> ---
>  gcc/cobol/parse.y   | 22 --
>  gcc/cobol/symbols.h |  9 ++---
>  2 files changed, 2 insertions(+), 29 deletions(-)
> 
> diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
> index 43ecef0de8f..390e115f37e 100644
> --- a/gcc/cobol/parse.y
> +++ b/gcc/cobol/parse.y
> @@ -12810,28 +12810,6 @@ cbl_field_t::has_subordinate( const cbl_field_t
> *that ) const {
>return false;
>  }
> 
> -bool
> -cbl_field_t::value_set( _Float128 value ) {
> -  data = value;
> -  char *initial = string_of(data.value_of());
> -  if( !initial ) return false;
> -
> -  // Trim trailing zeros.
> -  char *p = initial + strlen(initial);
> -  for( --p; initial <= p; --p ) {
> -if( *p != '0' ) break;
> -*p = '\0';
> -  }
> -
> -  data.digits = (p - initial) + 1;
> -  p = strchr(initial, '.');
> -  data.rdigits = p? initial + data.digits - p : 0;
> -
> -  data.initial = initial;
> -  data.capacity = type_capacity(type, data.digits);
> -  return true;
> -}
> -
>  const char *
>  cbl_field_t::value_str() const {
>  if( data.etc_type == cbl_field_data_t::value_e )
> diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
> index f51a2051f51..72bb188ec5b 100644
> --- a/gcc/cobol/symbols.h
> +++ b/gcc/cobol/symbols.h
> @@ -51,16 +51,12 @@
>  #if ! (__HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT))
>  static_assert( sizeof(output) == sizeof(long double), "long doubles?"
);
> 
> +// ???  This is still used for verificataion that __nptr parses as
> +// float number via setting *__endptr.
>  static inline _Float128
>  strtof128 (const char *__restrict __nptr, char **__restrict __endptr) {
>return strtold(nptr, endptr);
>  }
> -
> -static inline int
> -strfromf128 (char *restrict string, size_t size,
> -const char *restrict format, _Float128 value) {
> -  return  strfroml(str, n, format, fp);
> -}
>  #endif
> 
>  extern const char *numed_message;
> @@ -600,7 +596,6 @@ struct cbl_field_t {
>bool has_subordinate( const cbl_field_t *that ) const;
> 
>const char * internalize();
> -  bool value_set( _Float128 value );
>const char *value_str() const;
> 
>bool is_key_name() const { return has_attr(record_key_e); }
> --
> 2.43.0


[wwwdocs] Add Ada's GCC 15 changelog entry

2025-03-24 Thread Fernando Oleo Blanco
Dear GCC maintainers,

I have written the GCC 15 changelog for Ada. I am attaching the patch to 
the email. It has already had an initial review by Marc, but feel free 
to comment on it and request any changes.

Best regards,
Fernando Oleo BlancoFrom 733eeb430068eb59982c28c43c321db5866685d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= 
Date: Thu, 20 Mar 2025 14:44:26 +0100
Subject: [PATCH] gcc-15/changes: Document Ada changes

Co-authored-by: Fernando Oleo Blanco 
---
 htdocs/gcc-15/changes.html | 112 -
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html
index 7e5da369..830d45ad 100644
--- a/htdocs/gcc-15/changes.html
+++ b/htdocs/gcc-15/changes.html
@@ -125,7 +125,117 @@ a work-in-progress.
   
 
 
-
+Ada
+
+  
+GNAT now allows
+the https://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Round.html#index-Round";>'Round
+attribute also for fixed point types.
+  
+  
+The new GNAT
+attribute https://gcc.gnu.org/onlinedocs/gnat_rm/Attribute-Super.html#index-Super";>'Super
+can be applied to objects of tagged types in order to obtain a view
+conversion to the most immediate specific parent type.
+  
+  
+https://gcc.gnu.org/onlinedocs/gnat_rm/Mutably-Tagged-Types-with-Size_2019Class-Aspect.html";>Mutably tagged types with a defined size are now available
+through the use of Size'Class. This allows defining a maximum
+size for the tagged. Example:
+
+type Base is tagged null record with Size'Class => 16 * 8;
+ -- Size in bits (128 bits, or 16 bytes)
+
+type Derived_Type is new Base with record Data_Field : Integer; end record;
+ -- ERROR if Derived_Type exceeds 16 bytes
+
+  
+  
+New https://gcc.gnu.org/onlinedocs/gnat_rm/Generalized-Finalization.html";>Finalizable
+aspect. It is a GNAT language extension which serves as a lightweight
+alternative to controlled types. They have been designed with
+provability in mind.
+
+type Ctrl is record
+ Id : Natural := 0;
+end record with Finalizable => (Initialize   => Initialize,
+Adjust   => Adjust,
+Finalize => Finalize,
+Relaxed_Finalization => True);
+
+procedure Adjust (Obj : in out Ctrl);
+procedure Finalize   (Obj : in out Ctrl);
+procedure Initialize (Obj : in out Ctrl);
+
+  
+  
+The
+aspect https://gcc.gnu.org/onlinedocs/gnat_rm/No_005fRaise-aspect.html";>No_Raise
+has been added, it is the same as Pragma No_Raise.
+  
+  
+The
+aspect https://gcc.gnu.org/onlinedocs/gnat_rm/External_005fInitialization-Aspect.html";>External_Initialization
+has been added, it allows for data to be initialized using an external file
+which is loaded during compilation time.
+  
+  
+The
+aspect https://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Exit_005fCases.html#index-Exit_005fCases";>Exit_Cases
+has been added to annotate functions and procedures with side effects in
+SPARK
+(see https://docs.adacore.com/spark2014-docs/html/lrm/subprograms.html#program-exit-aspects";>SPARK
+reference manual) . It can be used to partition the input state into a
+list of cases and specify, for each case, how the subprogram is allowed to
+terminate.
+  
+  
+Language extensions are enabled through the use of pragma
+Extensions_Allowed (On | Off | All_Extensions); which has had its
+syntax changed. An argument of All_Extensions has the same
+effect as On, except
+that https://gcc.gnu.org/onlinedocs/gnat_rm/Experimental-Language-Extensions.html";>some
+extra experimental extensions are enabled.
+  
+  
+Several new compilation flags have been added, some examples
+include https://gcc.gnu.org/onlinedocs/gnat_ugn/Info-message-Control.html";>-gnatis, https://gcc.gnu.org/onlinedocs/gnat_ugn/Warning-Message-Control.html#index--gnatw_002en-_0028gcc_0029";>-gnatw.n, https://gcc.gnu.org/onlinedocs/gnat_ugn/Warning-Message-Control.html#index--gnatw_005fl-_0028gcc_0029";>-gnatw_l
+and https://gcc.gnu.org/onlinedocs/gnat_ugn/Warning-Message-Control.html#index--gnatw_002ev-_0028gcc_0029";>-gnatw.v.
+The internal debugging utilities for the compiler have also received a lot
+of new options, please refer
+to https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/ada/debug.adb";>debug.adb
+for more information.
+  
+  
+The diagnostics code has seen a major refactor, it now supports the sarif
+format -fdiagnostics-format=sarif-file among other
+improvements. More changes are expected in following releases.
+  
+  
+System.Image_A has now printing routines to output address
+information in HEX.
+  
+  
+Several program units have had contracts added to them and SPARK analysis
+has been enabled.
+  
+  
+Support for FreeBSD, Android and aarch64 targets has been improved.

[PATCH] i386: Fix AVX10.2 sat cvt intrinsic.

2025-03-24 Thread Hu, Lin1
Hi, all

The patch aims to modify the missed fixed for vcvttph2iubs's testcase.

Bootstrapped and tested on x86_64-linux-gnu{-m32,-m64}.

Commited as obvious change like the previous approved fix patch.

BRs,
Lin

gcc/testsuite/ChangeLog:

* gcc.target/i386/avx10_2-512-vcvttph2iubs-2.c: Modify testcase.
---
 .../i386/avx10_2-512-vcvttph2iubs-2.c | 28 +++
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.target/i386/avx10_2-512-vcvttph2iubs-2.c 
b/gcc/testsuite/gcc.target/i386/avx10_2-512-vcvttph2iubs-2.c
index d057c83831a..1db5a891c21 100644
--- a/gcc/testsuite/gcc.target/i386/avx10_2-512-vcvttph2iubs-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx10_2-512-vcvttph2iubs-2.c
@@ -9,6 +9,7 @@
 #endif
 #include "avx10-helper.h"
 #include 
+#include 
 
 #define SIZE (AVX512F_LEN / 16)
 #include "avx512f-mask-type.h"
@@ -37,7 +38,7 @@ TEST (void)
   UNION_TYPE (AVX512F_LEN, h) s;
   UNION_TYPE (AVX512F_LEN, i_w) res1, res2, res3;
   MASK_TYPE mask = MASK_VALUE;
-  short res_ref[SIZE] = { 0 };
+  short res_ref[SIZE] = { 0 }, res_ref2[SIZE] = { 0 };
   int i, sign = 1;
 
   for (i = 0; i < SIZE; i++)
@@ -54,11 +55,7 @@ TEST (void)
   res3.x = INTRINSIC (_maskz_ipcvtts_ph_epu8) (mask, s.x);
 
   CALC (s.a, res_ref);
-
-#if AVX512F_LEN == 512
-  res1.x = INTRINSIC (_ipcvtts_roundph_epu8) (s.x, 8);
-  res2.x = INTRINSIC (_mask_ipcvtts_roundph_epu8) (res2.x, mask, s.x, 8);
-  res3.x = INTRINSIC (_maskz_ipcvtts_roundph_epu8) (mask, s.x, 8);
+  memcpy(res_ref2, res_ref, sizeof(res_ref));
 
   if (UNION_CHECK (AVX512F_LEN, i_w) (res1, res_ref))
 abort ();
@@ -70,5 +67,24 @@ TEST (void)
   MASK_ZERO (i_w) (res_ref, mask, SIZE);
   if (UNION_CHECK (AVX512F_LEN, i_w) (res3, res_ref))
 abort ();
+
+#if AVX512F_LEN == 512
+  for (i = 0; i < SIZE; i++)
+res2.a[i] = DEFAULT_VALUE;
+
+  res1.x = INTRINSIC (_ipcvtts_roundph_epu8) (s.x, 8);
+  res2.x = INTRINSIC (_mask_ipcvtts_roundph_epu8) (res2.x, mask, s.x, 8);
+  res3.x = INTRINSIC (_maskz_ipcvtts_roundph_epu8) (mask, s.x, 8);
+
+  if (UNION_CHECK (AVX512F_LEN, i_w) (res1, res_ref2))
+abort ();
+
+  MASK_MERGE (i_w) (res_ref2, mask, SIZE);
+  if (UNION_CHECK (AVX512F_LEN, i_w) (res2, res_ref2))
+abort ();
+
+  MASK_ZERO (i_w) (res_ref2, mask, SIZE);
+  if (UNION_CHECK (AVX512F_LEN, i_w) (res3, res_ref2))
+abort ();
 #endif
 }
-- 
2.31.1



RE: [PATCH] cobol: Move includes before system.h

2025-03-24 Thread Robert Dubner
I'm going to take your word on this one.

LGTM

> -Original Message-
> From: Iain Sandoe 
> Sent: Monday, March 24, 2025 06:21
> To: jklow...@cobolworx.com; rdub...@symas.com; gcc-patches@gcc.gnu.org
> Subject: [PATCH] cobol: Move includes before system.h
> 
> A trivial patch that ensures host includes referenced directly are
> included before system.h (to avoid issues with poisoned interfaces).
> Tested on x86_64-linux,darwin aarch64-linux, OK for trunk?
> thanks
> Iain
> 
> --- 8< ---
> 
> This just moves a couple of includes ahead of cobol-system.h which
> in turn includes system.h.
> 
> gcc/cobol/ChangeLog:
> 
>   * cdf-copy.cc: Move host includes before system.h
> 
> Signed-off-by: Iain Sandoe 
> ---
>  gcc/cobol/cdf-copy.cc | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc
> index 179dbacea93..c620c828a0b 100644
> --- a/gcc/cobol/cdf-copy.cc
> +++ b/gcc/cobol/cdf-copy.cc
> @@ -34,13 +34,13 @@
>  //
>  // We regret any confusion engendered.
> 
> +#include 
> +
>  #include "cobol-system.h"
>  #include "cbldiag.h"
>  #include "util.h"
>  #include "copybook.h"
> 
> -#include 
> -
>  #define COUNT_OF(X) (sizeof(X) / sizeof(X[0]))
> 
>  /*
> --
> 2.39.2 (Apple Git-143)



[COMMITTED 117/141] gccrs: Keep definition provenance to skip enum variants

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Enum variants shouldn't be accessed directly even from within an enum.
This commit keeps the provenance for enum variants definition so we
can skip them when resolving a value within an enum definition.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h: Add new function to insert enum
variants and add argument to resolver's get function to explicitely
skip enum variants.
* resolve/rust-forever-stack.hxx: Update function
definitions.
* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::insert_variant):
Add function to insert enum variants.
* resolve/rust-name-resolution-context.h: Add function's prototype.
* resolve/rust-rib.cc (Rib::Definition::Definition): Add new boolean to
hint at enum variant provenance.
(Rib::Definition::is_variant): New getter for variant status.
(Rib::Definition::Shadowable): Update constructor to opt out of enum
variants.
(Rib::Definition::Globbed): Likewise.
(Rib::Definition::NonShadowable): Change constructor to forward enum
variant provenance status.
* resolve/rust-rib.h: Update function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::insert_enum_variant_or_error_out):
Add function to insert enum variants in the name resolver.
(TopLevel::visit): Update several enum variant's visitor function
with the new enum variant name resolving code.
* resolve/rust-toplevel-name-resolver-2.0.h: Update function
prototypes.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.h |  3 ++
 gcc/rust/resolve/rust-forever-stack.hxx   | 18 +--
 .../resolve/rust-name-resolution-context.cc   |  6 +++
 .../resolve/rust-name-resolution-context.h|  3 ++
 gcc/rust/resolve/rust-rib.cc  | 17 --
 gcc/rust/resolve/rust-rib.h   | 14 -
 .../rust-toplevel-name-resolver-2.0.cc| 54 ++-
 .../resolve/rust-toplevel-name-resolver-2.0.h | 17 +-
 8 files changed, 106 insertions(+), 26 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 64e8a0f0f2c..22efc973197 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -591,6 +591,9 @@ public:
*/
   tl::expected insert (Identifier name, NodeId id);
 
+  tl::expected insert_variant (Identifier name,
+  NodeId id);
+
   /**
* Insert a new shadowable definition in the innermost `Rib` in this stack
*
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 9e66c802d5f..628b8c5b6fe 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -173,6 +173,14 @@ ForeverStack::insert (Identifier name, 
NodeId node)
   Rib::Definition::Shadowable (node));
 }
 
+template <>
+inline tl::expected
+ForeverStack::insert_variant (Identifier name, NodeId node)
+{
+  return insert_inner (peek (), name.as_string (),
+  Rib::Definition::NonShadowable (node, true));
+}
+
 template 
 Rib &
 ForeverStack::peek ()
@@ -275,10 +283,12 @@ ForeverStack::get (const Identifier &name)
 
 return candidate.map_or (
   [&resolved_definition] (Rib::Definition found) {
-   // for most namespaces, we do not need to care about various ribs - they
-   // are available from all contexts if defined in the current scope, or
-   // an outermore one. so if we do have a candidate, we can return it
-   // directly and stop iterating
+   if (found.is_variant ())
+ return KeepGoing::Yes;
+   // for most namespaces, we do not need to care about various ribs -
+   // they are available from all contexts if defined in the current
+   // scope, or an outermore one. so if we do have a candidate, we can
+   // return it directly and stop iterating
resolved_definition = found;
 
return KeepGoing::No;
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 1b375213878..517a4836aaf 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -45,6 +45,12 @@ NameResolutionContext::insert (Identifier name, NodeId id, 
Namespace ns)
 }
 }
 
+tl::expected
+NameResolutionContext::insert_variant (Identifier name, NodeId id)
+{
+  return types.insert_variant (name, id);
+}
+
 tl::expected
 NameResolutionContext::insert_shadowable (Identifier name, NodeId id,
  Namespace ns)
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index a381411514d..ea81bdeed54 100644
--- a/gcc/rust/resolve/rust-name-res

[COMMITTED 073/141] gccrs: remove name resolution inserts from type-path

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We resolve path segments and inserted their resolution into the name
resolution space which was an old hack to use this as information in
code-gen/check-passes in order to help things move forward but this is
not nessecary

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): remove 
name resolution info
(TypeCheckType::resolve_root_path): likewise
* typecheck/rust-hir-type-check-type.h: likewise

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-type.cc | 142 ++
 gcc/rust/typecheck/rust-hir-type-check-type.h |   9 +-
 2 files changed, 16 insertions(+), 135 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 6afa7cf3af9..327cbb010a4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -136,9 +136,7 @@ TypeCheckType::visit (HIR::TypePath &path)
   // remaining segments if possible
   bool wasBigSelf = false;
   size_t offset = 0;
-  NodeId resolved_node_id = UNKNOWN_NODEID;
-  TyTy::BaseType *root
-= resolve_root_path (path, &offset, &resolved_node_id, &wasBigSelf);
+  TyTy::BaseType *root = resolve_root_path (path, &offset, &wasBigSelf);
   if (root->get_kind () == TyTy::TypeKind::ERROR)
 {
   rust_debug_loc (path.get_locus (), "failed to resolve type-path type");
@@ -159,9 +157,9 @@ TypeCheckType::visit (HIR::TypePath &path)
 }
 
   translated
-= resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (),
-   path.get_segments (), offset, path_type,
-   path.get_mappings (), path.get_locus (), wasBigSelf);
+= resolve_segments (path.get_mappings ().get_hirid (), path.get_segments 
(),
+   offset, path_type, path.get_mappings (),
+   path.get_locus (), wasBigSelf);
 
   rust_debug_loc (path.get_locus (), "resolved type-path to: [%s]",
  translated->debug_str ().c_str ());
@@ -180,32 +178,8 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
 
   if (!qual_path_type.has_as_clause ())
 {
-  // then this is just a normal path-in-expression
-  NodeId root_resolved_node_id = UNKNOWN_NODEID;
-  bool ok = false;
-  if (flag_name_resolution_2_0)
-   {
- auto &nr_ctx
-   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- if (auto id = nr_ctx.lookup (
-   qual_path_type.get_type ().get_mappings ().get_nodeid ()))
-   {
- root_resolved_node_id = *id;
- ok = true;
-   }
-   }
-  else
-   {
- ok = resolver->lookup_resolved_type (
-   qual_path_type.get_type ().get_mappings ().get_nodeid (),
-   &root_resolved_node_id);
-   }
-  rust_assert (ok);
-
   translated
-   = resolve_segments (root_resolved_node_id,
-   path.get_mappings ().get_hirid (),
+   = resolve_segments (path.get_mappings ().get_hirid (),
path.get_segments (), 0, translated,
path.get_mappings (), path.get_locus (), false);
 
@@ -278,7 +252,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
}
 }
 
-  NodeId root_resolved_node_id = UNKNOWN_NODEID;
   if (impl_item == nullptr)
 {
   // this may be valid as there could be a default trait implementation 
here
@@ -286,27 +259,19 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
   // not because this will have already been validated as part of the trait
   // impl block
   translated = item.get_tyty_for_receiver (root);
-  root_resolved_node_id
-   = item.get_raw_item ()->get_mappings ().get_nodeid ();
 }
   else
 {
   HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
   bool ok = query_type (impl_item_id, &translated);
   if (!ok)
-   {
- // FIXME
- // I think query_type should error if required here anyway
- return;
-   }
+   return;
 
   if (!args.is_error ())
{
  // apply the args
  translated = SubstMapperInternal::Resolve (translated, args);
}
-
-  root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
 }
 
   // turbo-fish segment path::
@@ -337,34 +302,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
   // continue on as a path-in-expression
   bool fully_resolved = path.get_segments ().empty ();
   if (fully_resolved)
-{
-  if (flag_name_resolution_2_0)
-   {
- auto &nr_ctx = const_cast (
-   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
-
- nr_ctx.map_usage (Resolver2_0::Usage (
- path.get_mappings ().get_nodeid ()),
-   Resolver2_0::Definition (root_resolved_nod

[COMMITTED 123/141] gccrs: track DefId on ADT Types this could be useful information

2025-03-24 Thread arthur . cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): track 
DefId of origin
* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): likewise
(ADTType::ADTType): likewise
(ADTType::get_id): likewise
(ADTType::clone): likewise
* typecheck/rust-tyty.h: likewise

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-item.cc |  8 +++-
 gcc/rust/typecheck/rust-tyty.cc   | 47 ++-
 gcc/rust/typecheck/rust-tyty.h| 39 ++-
 3 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 16c664fb595..a003848cce0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -232,6 +232,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
+struct_decl.get_mappings ().get_defid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
@@ -314,6 +315,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
+struct_decl.get_mappings ().get_defid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
@@ -376,7 +378,8 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
 
   // multi variant ADT
   auto *type
-= new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
+= new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
+enum_decl.get_mappings ().get_hirid (),
 enum_decl.get_mappings ().get_hirid (),
 enum_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::ENUM, std::move (variants),
@@ -447,7 +450,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
  std::move (fields)));
 
   auto *type
-= new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
+= new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
+union_decl.get_mappings ().get_hirid (),
 union_decl.get_mappings ().get_hirid (),
 union_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::UNION, std::move (variants),
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 5d5da4d258c..3951fa88da8 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -638,7 +638,7 @@ BaseType::monomorphized_clone () const
   for (auto &variant : adt->get_variants ())
cloned_variants.push_back (variant->monomorphized_clone ());
 
-  return new ADTType (adt->get_ref (), adt->get_ty_ref (),
+  return new ADTType (adt->get_id (), adt->get_ref (), adt->get_ty_ref (),
  adt->get_identifier (), adt->ident,
  adt->get_adt_kind (), cloned_variants,
  adt->clone_substs (), adt->get_repr_options (),
@@ -1621,6 +1621,43 @@ VariantDef::get_ident () const
 
 // ADTType
 
+ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
+ ADTKind adt_kind, std::vector variants,
+ std::vector subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set refs)
+  : BaseType (ref, ref, TypeKind::ADT, ident, refs),
+SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+region_constraints),
+id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector variants,
+ std::vector subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set refs)
+  : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
+SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+region_constraints),
+id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector variants,
+ std::vector subst_refs,
+ ReprOptions repr,
+ SubstitutionArgumentMappings generic_arguments,

[COMMITTED 102/141] gccrs: Adjust type path resolution error message

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Adjust error message to match
the 2.0 name resolver.

gcc/testsuite/ChangeLog:

* rust/compile/additional-trait-bounds2.rs: Adjust expected
errors.
* rust/compile/const_generics_4.rs: Likewise.
* rust/compile/const_generics_7.rs: Likewise.
* rust/compile/generic-default1.rs: Likewise.
* rust/compile/generics5.rs: Likewise.
* rust/compile/generics9.rs: Likewise.
* rust/compile/issue-2423.rs: Likewise.
* rust/compile/method2.rs: Likewise.
* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-ast-resolve-type.cc  |  2 +-
 .../rust/compile/additional-trait-bounds2.rs   |  2 +-
 gcc/testsuite/rust/compile/const_generics_4.rs |  2 +-
 gcc/testsuite/rust/compile/const_generics_7.rs | 14 +++---
 gcc/testsuite/rust/compile/generic-default1.rs |  2 +-
 gcc/testsuite/rust/compile/generics5.rs|  2 +-
 gcc/testsuite/rust/compile/generics9.rs|  2 +-
 gcc/testsuite/rust/compile/issue-2423.rs   |  6 +++---
 gcc/testsuite/rust/compile/method2.rs  |  2 +-
 gcc/testsuite/rust/compile/nr2/exclude |  6 --
 10 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index f0e5468a245..af63898a5d2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -316,7 +316,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId 
&resolved_node_id)
   else if (is_first_segment)
{
  rust_error_at (segment->get_locus (), ErrorCode::E0412,
-"failed to resolve TypePath: %s in this scope",
+"could not resolve type path %qs",
 segment->as_string ().c_str ());
  return false;
}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
index 843228ae9a6..1c49b750319 100644
--- a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
@@ -6,4 +6,4 @@ pub unsafe auto trait Sync {}
 
 trait A {}
 
-impl dyn A + Send + Sync + NonExist {} // { dg-error "failed to resolve 
TypePath: NonExist in this scope" }
+impl dyn A + Send + Sync + NonExist {} // { dg-error "could not resolve type 
path .NonExist." }
diff --git a/gcc/testsuite/rust/compile/const_generics_4.rs 
b/gcc/testsuite/rust/compile/const_generics_4.rs
index b364d3bb738..2766e4ca3c5 100644
--- a/gcc/testsuite/rust/compile/const_generics_4.rs
+++ b/gcc/testsuite/rust/compile/const_generics_4.rs
@@ -4,4 +4,4 @@ const P: usize = 14;
 
 struct Foo; // { dg-error "cannot find value .M. in 
this scope" }
 struct Bar;
-struct Baz; // { dg-error "failed to resolve 
TypePath: NotAType in this scope" }
+struct Baz; // { dg-error "could not resolve type 
path .NotAType." }
diff --git a/gcc/testsuite/rust/compile/const_generics_7.rs 
b/gcc/testsuite/rust/compile/const_generics_7.rs
index 2c128db92ea..dad4c21f84a 100644
--- a/gcc/testsuite/rust/compile/const_generics_7.rs
+++ b/gcc/testsuite/rust/compile/const_generics_7.rs
@@ -1,17 +1,17 @@
 struct S;
 
-pub fn foo() {} // { dg-error "failed to resolve" }
-type Foo = S; // { dg-error "failed to resolve" }
-struct Foo2; // { dg-error "failed to resolve" }
-enum Foo3 { // { dg-error "failed to resolve" }
+pub fn foo() {} // { dg-error "could not resolve" }
+type Foo = S; // { dg-error "could not resolve" }
+struct Foo2; // { dg-error "could not resolve" }
+enum Foo3 { // { dg-error "could not resolve" }
 Foo,
 Bar,
 }
-union Foo4 { // { dg-error "failed to resolve" }
+union Foo4 { // { dg-error "could not resolve" }
 a: usize,
 b: i32,
 }
-trait Fooable {} // { dg-error "failed to resolve" }
+trait Fooable {} // { dg-error "could not resolve" }
 
 trait Traitable {}
-impl Traitable for Foo2 {} // { dg-error "failed to 
resolve" }
+impl Traitable for Foo2 {} // { dg-error "could not 
resolve" }
diff --git a/gcc/testsuite/rust/compile/generic-default1.rs 
b/gcc/testsuite/rust/compile/generic-default1.rs
index 0a132bf5d6b..41556406bc6 100644
--- a/gcc/testsuite/rust/compile/generic-default1.rs
+++ b/gcc/testsuite/rust/compile/generic-default1.rs
@@ -1,5 +1,5 @@
 struct Foo(A);
-// { dg-error "failed to resolve TypePath: i321" "" { target *-*-* } .-1 }
+// { dg-error "could not resolve type path .i321." "" { target *-*-* } .-1 }
 
 fn main() {
 let a;
diff --git a/gcc/testsuite/rust/compile/generics5.rs 
b/gcc/testsuite/rust/compile/generics5.rs
index 6c847b5a29b..f8610380795 100644
--- a/gcc/testsuite/rust/compile/generics5.rs
+++ b/gcc/testsuite/rust/compile/generics5.rs
@@ -3,7 +3,7 @@ struct GenericStruct(T, usize);
 f

Re: [PATCH v2] libstdc++: Fix std::vector::append_range for overlapping ranges

2025-03-24 Thread Patrick Palka
On Mon, 24 Mar 2025, Jonathan Wakely wrote:

> Unlike insert_range and assign_range, the append_range function does not
> have a precondition that the range doesn't overlap *this. That means we
> need to avoid relocating the existing elements until after copying from
> the range. This means I need to revert r15-8488-g3e1d760bf49d0e which
> made the from_range_t constructor use append_range, because the
> constructor can avoid the additional complexity needed by append_range.
> When relocating the existing elements in append_range we can use
> std::__relocate_a to do it more efficiently, if that's valid.
> 
> std::vector::append_range needs similar treatment, although it's a
> bit simpler as we know that the elements are trivially copyable and so
> we don't need to worry about them throwing. assign_range doesn't allow
> overlapping ranges, so can be rewritten to be more efficient than
> calling append_range for the forward or sized range case.
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/bits/stl_bvector.h (vector::assign_range): More
>   efficient implementation for forward/sized ranges.
>   (vector::append_range): Handle potentially overlapping range.
>   * include/bits/stl_vector.h (vector(from_range_t, R&&, Alloc)):
>   Do not use append_range for non-sized input range case.
>   (vector::append_range)
>   (vector::append_range): Handle potentially overlapping range.
>   * include/bits/vector.tcc (vector::insert_range): Forward range
>   instead of moving it.
>   * testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc:
>   Test overlapping ranges.
>   * testsuite/23_containers/vector/modifiers/append_range.cc:
>   Likewise.
> ---
> 
> Changed vector::assign_range to just use a loop for the
> non-sized input range case, instead of calling append_range.
> 
> Changed private copy ctor to deleted move ctor in RAII type.
> 
> Testing x86_64-linux now.
> 
>  libstdc++-v3/include/bits/stl_bvector.h   |  69 ++--
>  libstdc++-v3/include/bits/stl_vector.h| 101 ++-
>  libstdc++-v3/include/bits/vector.tcc  |   2 +-
>  .../bool/modifiers/insert/append_range.cc |  50 ++
>  .../vector/modifiers/append_range.cc  | 164 ++
>  5 files changed, 366 insertions(+), 20 deletions(-)
> 
> diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
> b/libstdc++-v3/include/bits/stl_bvector.h
> index 3ee15eaa938..5addab048c9 100644
> --- a/libstdc++-v3/include/bits/stl_bvector.h
> +++ b/libstdc++-v3/include/bits/stl_bvector.h
> @@ -1035,8 +1035,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>   assign_range(_Rg&& __rg)
>   {
> static_assert(assignable_from>);
> -   clear();
> -   append_range(std::forward<_Rg>(__rg));
> +   if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
> + {
> +   if (auto __n = size_type(ranges::distance(__rg)))
> + {
> +   reserve(__n);
> +   this->_M_impl._M_finish
> +   = ranges::copy(std::forward<_Rg>(__rg), begin()).out;
> + }
> +   else
> + clear();
> + }
> +   else
> + {
> +   clear();
> +   auto __first = ranges::begin(__rg);
> +   const auto __last = ranges::end(__rg);
> +   for (; __first != __last; ++__first)
> + emplace_back(*__first);
> + }
>   }
>  #endif
>  
> @@ -1385,24 +1402,52 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>   constexpr void
>   append_range(_Rg&& __rg)
>   {
> +   // N.B. append_range(r) allows r to overlap with *this,
> +   // e.g. it could be *this | views::filter(pred) | views::to_input
> +   // and so we must not invalidate existing elements too soon.
> if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
>   {
> -   reserve(size() + size_type(ranges::distance(__rg)));
> -   this->_M_impl._M_finish = ranges::copy(__rg, end()).out;
> +   const auto __n = size_type(ranges::distance(__rg));
> +   const auto __sz = size();
> +
> +   // If there are no existing elements it's safe to allocate now.
> +   if (__sz == 0)
> + reserve(__n);
> +
> +   const auto __capacity = capacity();
> +   if ((__capacity - __sz) >= __n)
> + {
> +   this->_M_impl._M_finish
> +   = ranges::copy(std::forward<_Rg>(__rg), end()).out;
> +   return;
> + }
> +
> +   vector __tmp(get_allocator());
> +   __tmp.reserve(_M_check_len(__n, "vector::append_range"));
> +   __tmp._M_impl._M_finish
> += _M_copy_aligned(cbegin(), cend(), __tmp.begin());
> +   __tmp._M_impl._M_finish
> += ranges::copy(std::forward<_Rg>(__rg), __tmp.end()).out;
> +   swap(__tmp);
>   }
> else
>   {
> au

[COMMITTED 077/141] gccrs: self paths are patterns but we dont have mappings for it

2025-03-24 Thread arthur . cohen
From: Philip Herron 

With simple patterns we dont introduce any more inference varaibles as
they are already declared in a specific way. This would only lead to
more unconstrained inference varaibles than is required.

Fixes Rust-GCC#3022

gcc/rust/ChangeLog:

* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): add 
location mappings
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path): check for self

gcc/testsuite/ChangeLog:

* rust/compile/issue-3022.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-ast-lower-base.cc|  1 +
 gcc/rust/typecheck/rust-hir-type-check-path.cc |  5 -
 gcc/testsuite/rust/compile/issue-3022.rs   | 18 ++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3022.rs

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index 35a25093b73..add02747b0a 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -666,6 +666,7 @@ ASTLoweringBase::lower_self (AST::Param ¶m)
   Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
 mappings.get_next_hir_id (crate_num),
 mappings.get_next_localdef_id (crate_num));
+  mappings.insert_location (mapping.get_hirid (), param.get_locus ());
 
   if (self.has_type ())
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index a5243631fbd..33570ffa1c7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -312,6 +312,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
   auto seg_is_module = mappings.lookup_module (ref).has_value ();
   auto seg_is_crate = mappings.is_local_hirid_crate (ref);
   auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
+  auto seg_is_self = is_root && !have_more_segments
+&& seg.get_segment ().as_string () == "self";
   if (seg_is_module || seg_is_crate)
{
  // A::B::C::this_is_a_module::D::E::F
@@ -388,7 +390,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
-  else if (lookup->needs_generic_substitutions () && !seg_is_pattern)
+  else if (lookup->needs_generic_substitutions () && !seg_is_pattern
+  && !seg_is_self)
{
  lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
}
diff --git a/gcc/testsuite/rust/compile/issue-3022.rs 
b/gcc/testsuite/rust/compile/issue-3022.rs
new file mode 100644
index 000..b8b8e6fd5c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3022.rs
@@ -0,0 +1,18 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+fn foo(self) -> T;
+}
+
+struct Bar {
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+value: U,
+valte: T,
+}
+
+impl, U> Foo for Bar {
+fn foo(self) -> U {
+self.value
+}
+}
-- 
2.45.2



[COMMITTED 114/141] gccrs: expansion: Correctly expand $crate metavar

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc: Use new SubstituteCtx API.
* expand/rust-macro-expand.h: Likewise.
* expand/rust-macro-substitute-ctx.cc: Implement proper expansion of 
$crate.
* expand/rust-macro-substitute-ctx.h: Adapt APIs to take macro 
definition when
substituting.
* util/rust-hir-map.cc (Mappings::insert_macro_def): Store crate 
information when
inserting macro definition in mappings.
(Mappings::lookup_macro_def_crate): New.
* util/rust-hir-map.h: Adapt mappings to store crate in which macros 
were defined.

gcc/testsuite/ChangeLog:

* rust/execute/crate-metavar1.rs: New test.
* rust/compile/crate-metavar1.rs: New test.
---
 gcc/rust/expand/rust-macro-expand.cc | 10 ++--
 gcc/rust/expand/rust-macro-expand.h  |  3 +-
 gcc/rust/expand/rust-macro-substitute-ctx.cc | 51 +---
 gcc/rust/expand/rust-macro-substitute-ctx.h  | 25 --
 gcc/rust/util/rust-hir-map.cc| 14 +-
 gcc/rust/util/rust-hir-map.h |  4 +-
 gcc/testsuite/rust/compile/crate-metavar1.rs | 14 ++
 gcc/testsuite/rust/execute/crate-metavar1.rs | 11 +
 8 files changed, 115 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/crate-metavar1.rs
 create mode 100644 gcc/testsuite/rust/execute/crate-metavar1.rs

diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index 3822dc296c8..cd17a3f9ba1 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -23,6 +23,7 @@
 #include "rust-ast-full.h"
 #include "rust-ast-visitor.h"
 #include "rust-diagnostics.h"
+#include "rust-macro.h"
 #include "rust-parse.h"
 #include "rust-cfg-strip.h"
 #include "rust-early-name-resolver.h"
@@ -118,7 +119,7 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
   for (auto &ent : matched_fragments)
 matched_fragments_ptr.emplace (ent.first, ent.second.get ());
 
-  return transcribe_rule (*matched_rule, invoc_token_tree,
+  return transcribe_rule (rules_def, *matched_rule, invoc_token_tree,
  matched_fragments_ptr, semicolon, peek_context ());
 }
 
@@ -1023,7 +1024,8 @@ tokens_to_str (std::vector> 
&tokens)
 
 AST::Fragment
 MacroExpander::transcribe_rule (
-  AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
+  AST::MacroRulesDefinition &definition, AST::MacroRule &match_rule,
+  AST::DelimTokenTree &invoc_token_tree,
   std::map &matched_fragments,
   AST::InvocKind invoc_kind, ContextType ctx)
 {
@@ -1037,8 +1039,8 @@ MacroExpander::transcribe_rule (
   auto invoc_stream = invoc_token_tree.to_token_stream ();
   auto macro_rule_tokens = transcribe_tree.to_token_stream ();
 
-  auto substitute_context
-= SubstituteCtx (invoc_stream, macro_rule_tokens, matched_fragments);
+  auto substitute_context = SubstituteCtx (invoc_stream, macro_rule_tokens,
+  matched_fragments, definition);
   std::vector> substituted_tokens
 = substitute_context.substitute_tokens ();
 
diff --git a/gcc/rust/expand/rust-macro-expand.h 
b/gcc/rust/expand/rust-macro-expand.h
index 5e127906bb7..360294c6bf9 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -331,7 +331,8 @@ struct MacroExpander
   AST::DelimTokenTree &invoc_token_tree);
 
   AST::Fragment transcribe_rule (
-AST::MacroRule &match_rule, AST::DelimTokenTree &invoc_token_tree,
+AST::MacroRulesDefinition &definition, AST::MacroRule &match_rule,
+AST::DelimTokenTree &invoc_token_tree,
 std::map &matched_fragments,
 AST::InvocKind invoc_kind, ContextType ctx);
 
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc 
b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index a06f831d7dd..02e4e3b1c5a 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -17,9 +17,46 @@
 // .
 
 #include "rust-macro-substitute-ctx.h"
+#include "input.h"
+#include "rust-hir-map.h"
+#include "rust-token.h"
 
 namespace Rust {
 
+bool
+SubstituteCtx::substitute_dollar_crate (
+  std::vector> &expanded)
+{
+  auto &mappings = Analysis::Mappings::get ();
+
+  auto def_crate = mappings.lookup_macro_def_crate (definition.get_node_id ());
+  auto current_crate = mappings.get_current_crate ();
+
+  rust_assert (def_crate);
+
+  // If we're expanding a macro defined in the current crate which uses $crate,
+  // we can just replace the metavar with the `crate` path segment. Otherwise,
+  // use the fully qualified extern-crate lookup path `::`
+  if (*def_crate == current_crate)
+{
+  expanded.push_back (std::make_unique (
+   Rust::Token::make_identifier (UNKNOWN_LOCATION, "crate")));
+}
+  else
+{
+  auto name = mappings.get_crate_name (*def_crate);
+
+  rust_assert (name)

Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-24 Thread Jakub Jelinek
On Mon, Mar 24, 2025 at 02:36:31PM +0100, Paul-Antoine Arras wrote:
> Hi Thomas,
> 
> On 24/03/2025 13:47, Thomas Schwinge wrote:
> > On 2025-03-21T18:35:57+0100, Paul-Antoine Arras  wrote:
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gfortran.dg/gomp/interop-5.f90
> > > @@ -0,0 +1,21 @@
> > > +! { dg-additional-options "-fdump-tree-omplower" }
> > > +
> > > +subroutine sub1 (a1, a2, a3, a4)
> > > +   use omp_lib, only: omp_interop_kind
> > 
> >  [...]/gfortran.dg/gomp/interop-5.f90:4:8: Fatal Error: Cannot open 
> > module file 'omp_lib.mod' for reading at (1): No such file or directory
> >  compilation terminated.
> >  compiler exited with status 1
> >  FAIL: gfortran.dg/gomp/interop-5.f90   -O  (test for excess errors)
> > 
> > As other files state:
> > 
> >  ! The following definitions are in omp_lib, which cannot be included
> >  ! in gcc/testsuite/
> 
> Thanks for pointing that out! The attached patch should fix it.
> 
> If no one objects, I'll commit it shortly.

LGTM.

> --- gcc/testsuite/gfortran.dg/gomp/interop-5.f90
> +++ gcc/testsuite/gfortran.dg/gomp/interop-5.f90
> @@ -1,7 +1,13 @@
>  ! { dg-additional-options "-fdump-tree-omplower" }
>  
>  subroutine sub1 (a1, a2, a3, a4)
> -   use omp_lib, only: omp_interop_kind
> +   use iso_c_binding
> +   implicit none
> +
> +   ! The following definitions are in omp_lib, which cannot be included
> +   ! in gcc/testsuite/
> +   integer, parameter :: omp_interop_kind = c_intptr_t
> +
> integer(omp_interop_kind) :: a1  ! by ref
> integer(omp_interop_kind), optional :: a2 ! as pointer
> integer(omp_interop_kind), allocatable :: a3 ! ref to pointer


Jakub



RE: [PATCH] libgcobol: use standard f128 suffix instead of Q for _Float128 literals

2025-03-24 Thread Robert Dubner
You and Iain Sandoe should coordinate on this one, given the work he's
doing on libquadmath.

> -Original Message-
> From: Andreas Schwab 
> Sent: Monday, March 24, 2025 06:42
> To: gcc-patches@gcc.gnu.org
> Cc: jklow...@cobolworx.com; rdub...@symas.com
> Subject: [PATCH] libgcobol: use standard f128 suffix instead of Q for
> _Float128 literals
> 
> * intrinsic.cc: Use standard f128 suffix for _Float128 literals.
> * libgcobol.cc: Likewise.
> ---
>  libgcobol/intrinsic.cc | 18 +-
>  libgcobol/libgcobol.cc | 36 ++--
>  2 files changed, 27 insertions(+), 27 deletions(-)
> 
> diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc
> index e3d255a29d6..6dfd98704c2 100644
> --- a/libgcobol/intrinsic.cc
> +++ b/libgcobol/intrinsic.cc
> @@ -55,7 +55,7 @@
> 
>  #define JD_OF_1601_01_02 2305812.5
> 
> -#define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0Q)
> +#define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0f128)
>  #define NO_RDIGITS (0)
> 
>  struct cobol_tm
> @@ -981,7 +981,7 @@ __gg__acos( cblc_field_t *dest,
>_Float128 value;
>value = __gg__float128_from_qualified_field(source, source_offset,
> source_size);
> 
> -  if( value < -1.00Q || value > +1.00Q )
> +  if( value < -1.00f128 || value > +1.00f128 )
>  {
>  exception_raise(ec_argument_function_e);
>  value = WEIRD_TRANSCENDENT_RETURN_VALUE;
> @@ -1056,7 +1056,7 @@ __gg__asin( cblc_field_t *dest,
>source_offset,
>source_size);
> 
> -  if( value < -1.0Q || value > +1.00Q )
> +  if( value < -1.0f128 || value > +1.00f128 )
>  {
>  exception_raise(ec_argument_function_e);
>  value = WEIRD_TRANSCENDENT_RETURN_VALUE;
> @@ -1366,7 +1366,7 @@ void
>  __gg__e(cblc_field_t *dest)
>{
>// FUNCTION E
> -  static _Float128 e = 2.7182818284590452353602874713526624977572Q;
> +  static _Float128 e = 2.7182818284590452353602874713526624977572f128;
>__gg__float128_to_field(dest,
>e,
>truncation_e,
> @@ -1404,7 +1404,7 @@ __gg__exp10(cblc_field_t *dest,
>_Float128 value = __gg__float128_from_qualified_field(source,
>  source_offset,
>  source_size);
> -  value = powf128(10.0Q, value);
> +  value = powf128(10.0f128, value);
>__gg__float128_to_field(dest,
>value,
>truncation_e,
> @@ -3169,7 +3169,7 @@ __gg__pi(cblc_field_t *dest)
>{
>// FUNCTION PI
> 
> -  static _Float128 pi = 3.141592653589793238462643383279502884Q;
> +  static _Float128 pi = 3.141592653589793238462643383279502884f128;
>__gg__float128_to_field(dest,
>pi,
>truncation_e,
> @@ -3198,12 +3198,12 @@ __gg__present_value(cblc_field_t *dest,
>  _Float128 arg1 =
> __gg__float128_from_qualified_field(__gg__treeplet_1f[i],
> 
> __gg__treeplet_1o[i],
> 
> __gg__treeplet_1s[i]);
> -if( arg1 <= -1.0Q )
> +if( arg1 <= -1.0f128 )
>{
>exception_raise(ec_argument_function_e);
>break;
>}
> -discount = 1.0Q / (1.0Q + arg1);
> +discount = 1.0f128 / (1.0f128 + arg1);
>  }
>else
>  {
> @@ -3562,7 +3562,7 @@ __gg__sqrt( cblc_field_t *dest,
>  source_offset,
>  source_size);
> 
> -  if( value <= 0.0Q )
> +  if( value <= 0.0f128 )
>  {
>  exception_raise(ec_argument_function_e);
>  }
> diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
> index 0890835822c..be179d4d9b9 100644
> --- a/libgcobol/libgcobol.cc
> +++ b/libgcobol/libgcobol.cc
> @@ -858,7 +858,7 @@ int128_to_int128_rounded( cbl_round_t rounded,
>_Float128 fpart = _Float128(remainder) / _Float128(factor);
>__int128 retval = value;
> 
> -  if(rounded == nearest_even_e && fpart != -0.5Q && fpart != 0.5Q )
> +  if(rounded == nearest_even_e && fpart != -0.5f128 && fpart != 0.5f128
)
>  {
>  // "bankers rounding" has been requested.
>  //
> @@ -879,14 +879,14 @@ int128_to_int128_rounded( cbl_round_t rounded,
>// 0.5 through 0.9 becomes 1
>if( value < 0 )
>  {
> -if( fpart <= -0.5Q )
> +if( fpart <= -0.5f128 )
>{
>retval -= 1;
>}
>  }
>else
>  {
> -if( fpart >= 0.5Q )
> +if( fpart >= 0.5f128 )
>{
>retval += 1;
>}
> @@ -920,14 +920,14 @@ int128_to_int128_rounded( cbl_round_t rounded,
>// 0.6 through 0.9 becomes 1
>if( value < 0 )
>  {
> -if( fpart < -0.5Q )
> +if( fpart < -0.5f128 )
>{
>retval -= 1;
>}
>  }
> 

RE: [PATCH] change cbl_field_data_t::etc_t::value from _Float128 to tree

2025-03-24 Thread Robert Dubner



> -Original Message-
> From: Richard Biener 
> Sent: Monday, March 24, 2025 05:04
> To: Robert Dubner 
> Cc: Jakub Jelinek ; gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH] change cbl_field_data_t::etc_t::value from
_Float128
> to tree
> 
> On Sun, 23 Mar 2025, Robert Dubner wrote:
> 
> > I am enclosing a patch to be applied on top of yours.  (Your patch got
> us
> > down to zero errors in the "Coughlan" tests, 2 UAT errors, and 4
errors
> in
> > the NIST tests.  Well done!)
> >
> > This one passes all of my tests, in both ASCII and EBCDIC forms.  It
> also
> > passes "make check-cobol".  That's on my x_86_64-linux machine.
> >
> > (That's the good news.  The bad news is that this is exposing gaps in
> > coverage of our test suites.  There is stuff that the misnamed
numstr2i
> > routine used to do that isn't being done, but no errors are flagged in
> any
> > test.)
> >
> > Given that this version passes everything that our regression tests
> cover,
> > is it time to accumulate all this work into a single patch and have
that
> > committed?
> 
> That would be nice, it's difficult to keep track of all the things in
> flight.  And thanks Jakub for picking up the ball while I was
> weekending in the German wilderness ;)
> 
> I was also wondering of adding test coverage for the various paths we're
> touching.

I am creating a process whereby I selectively convert many of our UAT
tests to the DejaGnu format.  I just today sent a bug report to Jakub.  I
am having trouble making the new gd-output-file directive he so graciously
created work, and I need that for the process.

Bob D.

> 
> Richard.
> 
> > Perhaps I should create that patch, seeing as how at this moment only
I
> > can do all of my known tests.
> >
> > Bob D.
> >
> >
> > diff --git a/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > b/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > index 787468a194ff..6547b59955ab 100644
> > --- a/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > +++ b/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > @@ -535,7 +535,7 @@ prog.cob:44:20: error: invalid picture for
> > Alphanumeric-edited
> >  prog.cob:67:22: error: PICTURE '(str-constant)' requires a CONSTANT
> value
> > 67 |03  PIC X(str-constant).
> >|  ^
> > -prog.cob:69:22: error: invalid PICTURE count
> > '(-1.E+00)'
> > +prog.cob:69:22: error: invalid PICTURE count '(signed-constant)'
> > 69 |03  PIC X(signed-constant).
> >|  ^
> >  prog.cob:69:21: error: PICTURE count '(-1)' is negative
> > diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
> > index ca86ffa2fc74..f3cab0a4ad1e 100644
> > --- a/gcc/cobol/genapi.cc
> > +++ b/gcc/cobol/genapi.cc
> > @@ -4897,8 +4897,7 @@ parser_display_internal(tree file_descriptor,
> >}
> >  else
> >{
> > -  p += 1;
> > -  int exp = atoi(p);
> > +  int exp = atoi(p+1);
> >if( exp >= 6 || exp <= -5 )
> > {
> > // We are going to stick with the E notation, so ach has our
> > result
> > diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
> > index 0077863d766b..c2fe2d8d2265 100644
> > --- a/gcc/cobol/parse.y
> > +++ b/gcc/cobol/parse.y
> > @@ -6935,6 +6935,17 @@ cce_expr:   cce_factor
> >  cce_factor: NUMSTR {
> >/* ???  real_from_string does not allow arbitrary
> > radix.  */
> >// $$ = numstr2i($1.string, $1.radix);
> > +  // When DECIMAL IS COMMA, commas act as decimal
> points.
> > +  // What follows is an expedient hack; the numstr2i
> > routine
> > +  // actually needs to be fixed.
> > +  for(size_t i=0; i > +{
> > +if( $1.string[i] == ',' )
> > +  {
> > +  $1.string[i] = '.';
> > +  }
> > +}
> > +  // End of hack
> >   real_from_string3 (&$$, $1.string,
> >  TYPE_MODE (float128_type_node));
> >  }
> > @@ -12894,14 +12905,14 @@ literal_refmod_valid( YYLTYPE loc, const
> > cbl_refer_t& r ) {
> >  if( ! is_literal(refmod.len->field) ) return true;
> >  auto edge = real_to_integer (TREE_REAL_CST_PTR
> > (refmod.len->field->data.value_of()));
> >  if( 0 < edge ) {
> > -  if( --edge < r.field->data.capacity ) return true;
> > +  if( edge-1 < r.field->data.capacity ) return true;
> >  }
> >  // len < 0 or not: 0 < from + len <= capacity
> >  error_msg(loc, "%s(%s:%zu) out of bounds, "
> >"size is %u",
> >   r.field->name,
> >   refmod.from->name(),
> > - size_t(refmod.len->field->data.value_of()),
> > + size_t(edge),
> >   static_cast(r.field->data.capacity) );
> >  return false;
> >}
> > @@ -12930,7 +12941,7 @@ literal_refmod_valid( YYLTYPE loc, const
> > cb

RE: [PATCH] libgcobol: Ensure that config.h is included.

2025-03-24 Thread Robert Dubner
I am taking your word for it on testing.

LGTM

> -Original Message-
> From: Iain Sandoe 
> Sent: Monday, March 24, 2025 05:01
> To: jklow...@cobolworx.com; rdub...@symas.com; gcc-patches@gcc.gnu.org
> Subject: [PATCH] libgcobol: Ensure that config.h is included.
> 
> This one is quite simple; we currently go through the configuration
> process and mostly ignore its output.  This fixes that so that we may
> use the configured values to make things more portable.
> 
> tested on x86_64-linux,darwin aarch64-linux, OK for trunk?
> thanks
> Iain
> 
> --- 8< ---
> 
> This includes config.h before any other project-related headers
> or sources so that they properly make use of the values determined
> by configure.
> 
> libgcobol/ChangeLog:
> 
>   * charmaps.cc: Include config.h.
>   * constants.cc: Likewise.
>   * gfileio.cc: Likewise.
>   * gmath.cc: Likewise.
>   * io.cc: Likewise.
>   * libgcobol.cc: Likewise.
>   * valconv.cc: Likewise.
> 
> Signed-off-by: Iain Sandoe 
> ---
>  libgcobol/charmaps.cc  | 2 ++
>  libgcobol/constants.cc | 2 ++
>  libgcobol/gfileio.cc   | 2 ++
>  libgcobol/gmath.cc | 2 ++
>  libgcobol/io.cc| 3 +++
>  libgcobol/libgcobol.cc | 2 ++
>  libgcobol/valconv.cc   | 2 ++
>  7 files changed, 15 insertions(+)
> 
> diff --git a/libgcobol/charmaps.cc b/libgcobol/charmaps.cc
> index 6a7975030df..6ad74adbc74 100644
> --- a/libgcobol/charmaps.cc
> +++ b/libgcobol/charmaps.cc
> @@ -38,6 +38,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "common-defs.h"
>  #include "io.h"
> diff --git a/libgcobol/constants.cc b/libgcobol/constants.cc
> index 3b4d68a730b..0aa9373492e 100644
> --- a/libgcobol/constants.cc
> +++ b/libgcobol/constants.cc
> @@ -40,6 +40,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "io.h"
>  #include "common-defs.h"
> diff --git a/libgcobol/gfileio.cc b/libgcobol/gfileio.cc
> index 9852dbf0f35..74c5a073c41 100644
> --- a/libgcobol/gfileio.cc
> +++ b/libgcobol/gfileio.cc
> @@ -40,6 +40,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "io.h"
>  #include "common-defs.h"
> diff --git a/libgcobol/gmath.cc b/libgcobol/gmath.cc
> index 2af0e8a8614..fb2eae38ef3 100644
> --- a/libgcobol/gmath.cc
> +++ b/libgcobol/gmath.cc
> @@ -39,6 +39,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "common-defs.h"
>  #include "io.h"
> diff --git a/libgcobol/io.cc b/libgcobol/io.cc
> index 4dca42e0bad..95e1d026686 100644
> --- a/libgcobol/io.cc
> +++ b/libgcobol/io.cc
> @@ -27,6 +27,9 @@
>   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE
>   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>   */
> +
> +#include "config.h"
> +
>  #include "io.h"
>  #include "stdio.h"
>  #include "stdlib.h"
> diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
> index 0890835822c..6aeaaa2c142 100644
> --- a/libgcobol/libgcobol.cc
> +++ b/libgcobol/libgcobol.cc
> @@ -49,6 +49,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "common-defs.h"
>  #include "io.h"
> diff --git a/libgcobol/valconv.cc b/libgcobol/valconv.cc
> index 0b80d72cc3a..41a933d68db 100644
> --- a/libgcobol/valconv.cc
> +++ b/libgcobol/valconv.cc
> @@ -35,6 +35,8 @@
>  #include 
>  #include 
> 
> +#include "config.h"
> +
>  #include "ec.h"
>  #include "common-defs.h"
>  #include "charmaps.h"
> --
> 2.39.2 (Apple Git-143)



[PATCH 2/2] testsuite, cobol: If libgcobol has a .spec file use it.

2025-03-24 Thread Iain Sandoe
This conditionally adds a path for libgcobol when that contains
libgcobol.spec.

gcc/testsuite/ChangeLog:

* lib/cobol.exp: Conditionally add a path for libgcobol.spec.

Signed-off-by: Iain Sandoe 
---
 gcc/testsuite/lib/cobol.exp | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/cobol.exp b/gcc/testsuite/lib/cobol.exp
index cd88bcb66d1..a0eeb4e64e9 100644
--- a/gcc/testsuite/lib/cobol.exp
+++ b/gcc/testsuite/lib/cobol.exp
@@ -107,8 +107,11 @@ proc cobol_link_flags { paths } {
 }
 
 if { $gccpath != "" } {
+  if [file exists "${gccpath}/libgcobol/libgcobol.spec"] {
+  append flags "-B${gccpath}/libgcobol "
+  }
   if [file exists "${gccpath}/libgcobol/libgcobol.a"] {
-  append flags "-L${gccpath}/libgcobol"
+  append flags "-L${gccpath}/libgcobol "
   }
   if { [file exists "${gccpath}/libgcobol/.libs/libgcobol.a"] ||
 [file exists "${gccpath}/libgobol/.libs/libgcobol.${shlib_ext}"] } {
-- 
2.39.2 (Apple Git-143)



Re: [PATCH] OpenMP: 'interop' construct - add ME support + target-independent libgomp

2025-03-24 Thread Paul-Antoine Arras

On 21/03/2025 20:17, Sandra Loosemore wrote:

On 3/21/25 11:35, Paul-Antoine Arras wrote:

Thanks Sandra and Jakub for your comments.

Here is attached an updated version of the patch:

* Removed special case for n==1, now use an array even when only one 
interop object is passed.

* Updated scan dumps; added C/C++ disjunction where needed.
* Updated the signature of GOMP_interop to actual rather than generic 
types.

* Renamed 'nowait' argument into 'flags' to allow for future extension.
* Added comments.
* Fixed style and formatting.


I have one more nit about this interface:

+/* Process the OpenMP interop directive. 'init' and 'destroy' take an 
array

+   of 'omp_interop_t *', 'use' an array of 'omp_interop_t', where
+   'omp_interop_t' is internally 'struct interop_obj_t *';
+   'flag' is used for the 'nowait' clause.  */
+
+void
+GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
+  const int *target_targetsync, const char **prefer_type, int 
n_use,

+  struct interop_obj_t **use, int n_destroy,
+  struct interop_obj_t ***destroy, unsigned int flags,
+  void **depend)


Is it possible to make the init and destroy arrays const?  I think the 
right C syntax for that would be "struct interop_obj_t ** const * 
init" (I admit I always find this syntax confusing, though, so don't 
take my word for it without checking).


Basically, I'm thinking that if you have #pragma omp dispatch with a 
variant call that implicitly constructs/destructs omp_interop_t objects, 
we ought to be able to pass the same array to both GOMP_interop calls 
and know that the constructor call doesn't clobber the contents of the 
array itself (only the objects its elements point to.)  And if you have 
such a thing in a loop, the optimizers ought to be able to hoist the 
array initialization completely out of the loop so that it only happens 
once.


Likewise I think prefer_type could be declared as "const char * const 
prefer_type"?


Does the attached patch reflect what you have in mind?

If so, I guess I can commit it soon.
--
PAdiff --git libgomp/libgomp_g.h libgomp/libgomp_g.h
index 8993ec610fb..274f4937680 100644
--- libgomp/libgomp_g.h
+++ libgomp/libgomp_g.h
@@ -359,9 +359,10 @@ extern void GOMP_teams (unsigned int, unsigned int);
 extern bool GOMP_teams4 (unsigned int, unsigned int, unsigned int, bool);
 extern void *GOMP_target_map_indirect_ptr (void *);
 struct interop_obj_t;
-extern void GOMP_interop (int, int, struct interop_obj_t ***, const int *,
-			  const char **, int, struct interop_obj_t **, int,
-			  struct interop_obj_t ***, unsigned, void **);
+extern void GOMP_interop (int, int, struct interop_obj_t **const *, const int *,
+			  const char *const *, int, struct interop_obj_t **,
+			  int, struct interop_obj_t **const *, unsigned,
+			  void **);
 
 /* teams.c */
 
diff --git libgomp/target.c libgomp/target.c
index 36ed797b0a9..54c244e0f13 100644
--- libgomp/target.c
+++ libgomp/target.c
@@ -5279,11 +5279,11 @@ ialias (omp_get_interop_rc_desc)
 struct interop_data_t
 {
   int device_num, n_init, n_use, n_destroy;
-  struct interop_obj_t ***init;
+  struct interop_obj_t **const *init;
   struct interop_obj_t **use;
-  struct interop_obj_t ***destroy;
+  struct interop_obj_t **const *destroy;
   const int *target_targetsync;
-  const char **prefer_type;
+  const char *const *prefer_type;
 };
 
 static void
@@ -5348,10 +5348,10 @@ gomp_interop_internal (void *data)
'flags' is used for the 'nowait' clause.  */
 
 void
-GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
-	  const int *target_targetsync, const char **prefer_type, int n_use,
-	  struct interop_obj_t **use, int n_destroy,
-	  struct interop_obj_t ***destroy, unsigned int flags,
+GOMP_interop (int device_num, int n_init, struct interop_obj_t **const *init,
+	  const int *target_targetsync, const char *const *prefer_type,
+	  int n_use, struct interop_obj_t **use, int n_destroy,
+	  struct interop_obj_t **const *destroy, unsigned int flags,
 	  void **depend)
 {
   struct interop_data_t args;


RE: [PATCH] libgcobol: Only use random_r if it is available [PR119295]

2025-03-24 Thread Robert Dubner
Taking your word on testing,

LGTM

> -Original Message-
> From: Iain Sandoe 
> Sent: Sunday, March 23, 2025 20:59
> To: jklow...@schemamania.org; rdub...@symas.com; gcc-patches@gcc.gnu.org
> Subject: [PATCH] libgcobol: Only use random_r if it is available
> [PR119295]
> 
> Tested on x86_64 and aarch64 Linux and x86_64 darwin,
> OK for trunk?
> thanks
> Iain
> 
> This applies on top of
> https://gcc.gnu.org/pipermail/gcc-patches/2025-March/678927.html
> 
> --- 8< ---
> 
> We do not have a replacement at the moment, so fall back to using
> regular random and friends.
> 
>   PR cobol/119295
> 
> libgcobol/ChangeLog:
> 
>   * config.h.in: Regenerate.
>   * configure: Regenerate.
>   * configure.ac: Configure random_r and friends
>   * intrinsic.cc (__gg__random): Use random_r when available.
>   (__gg__random_next): Likewise.
> 
> Signed-off-by: Iain Sandoe 
> ---
>  libgcobol/config.h.in  |  12 +
>  libgcobol/configure| 105 -
>  libgcobol/configure.ac |   3 ++
>  libgcobol/intrinsic.cc |  25 --
>  4 files changed, 138 insertions(+), 7 deletions(-)
> 
> diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in
> index 14ebaeb2b26..e7e1492b579 100644
> --- a/libgcobol/config.h.in
> +++ b/libgcobol/config.h.in
> @@ -9,6 +9,9 @@
>  /* Define if you have the iconv() function and it works. */
>  #undef HAVE_ICONV
> 
> +/* Define to 1 if you have the `initstate_r' function. */
> +#undef HAVE_INITSTATE_R
> +
>  /* Define to 1 if you have the  header file. */
>  #undef HAVE_INTTYPES_H
> 
> @@ -18,6 +21,15 @@
>  /* Define to 1 if you have the  header file. */
>  #undef HAVE_MEMORY_H
> 
> +/* Define to 1 if you have the `random_r' function. */
> +#undef HAVE_RANDOM_R
> +
> +/* Define to 1 if you have the `setstate_r' function. */
> +#undef HAVE_SETSTATE_R
> +
> +/* Define to 1 if you have the `srandom_r' function. */
> +#undef HAVE_SRANDOM_R
> +
>  /* Define to 1 if you have the  header file. */
>  #undef HAVE_STDINT_H
> 
> diff --git a/libgcobol/configure b/libgcobol/configure
> index ffbfebd96bf..0a6bafe265b 100755
> --- a/libgcobol/configure
> +++ b/libgcobol/configure
> @@ -629,6 +629,7 @@ ac_includes_default="\
>  # include 
>  #endif"
> 
> +ac_func_list=
>  ac_unique_file="Makefile.am"
>  ac_subst_vars='am__EXEEXT_FALSE
>  am__EXEEXT_TRUE
> @@ -2337,6 +2338,76 @@ rm -f conftest.val
>as_fn_set_status $ac_retval
> 
>  } # ac_fn_cxx_compute_int
> +
> +# ac_fn_cxx_check_func LINENO FUNC VAR
> +# 
> +# Tests whether FUNC exists, setting the cache variable VAR accordingly
> +ac_fn_cxx_check_func ()
> +{
> +  as_lineno=${as_lineno-"$1"}
> as_lineno_stack=as_lineno_stack=$as_lineno_stack
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
> +$as_echo_n "checking for $2... " >&6; }
> +if eval \${$3+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  if test x$gcc_no_link = xyes; then
> +  as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES."
> "$LINENO" 5
> +fi
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +/* Define $2 to an innocuous variant, in case  declares $2.
> +   For example, HP-UX 11i  declares gettimeofday.  */
> +#define $2 innocuous_$2
> +
> +/* System header to define __stub macros and hopefully few prototypes,
> +which can conflict with char $2 (); below.
> +Prefer  to  if __STDC__ is defined, since
> + exists even on freestanding compilers.  */
> +
> +#ifdef __STDC__
> +# include 
> +#else
> +# include 
> +#endif
> +
> +#undef $2
> +
> +/* Override any GCC internal prototype to avoid an error.
> +   Use char because int might match the return type of a GCC
> +   builtin and then its argument prototype would still apply.  */
> +#ifdef __cplusplus
> +extern "C"
> +#endif
> +char $2 ();
> +/* The GNU C library defines this for functions which it implements
> +to always fail with ENOSYS.  Some functions are actually named
> +something starting with __ and the normal name is an alias.  */
> +#if defined __stub_$2 || defined __stub___$2
> +choke me
> +#endif
> +
> +int
> +main ()
> +{
> +return $2 ();
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_cxx_try_link "$LINENO"; then :
> +  eval "$3=yes"
> +else
> +  eval "$3=no"
> +fi
> +rm -f core conftest.err conftest.$ac_objext \
> +conftest$ac_exeext conftest.$ac_ext
> +fi
> +eval ac_res=\$$3
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res"
>&5
> +$as_echo "$ac_res" >&6; }
> +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
> +
> +} # ac_fn_cxx_check_func
>  cat >config.log <<_ACEOF
>  This file contains any messages produced by compilers while
>  running configure, to aid debugging if configure makes a mistake.
> @@ -2621,6 +2692,10 @@ $as_echo "$as_me: creating cache $cache_file"
>&6;}
>>$cache_file
>  fi
> 
> +as_fn_append ac_func_list " random_r"
> +as_fn_append ac_func_list " srandom_r"
> +as_fn_ap

[committed] testsuite: d: Break up Wbuiltin_declaration_mismatch2.d into smaller tests

2025-03-24 Thread Iain Buclaw
Hi,

This patch splits Wbuiltin_declaration_mismatch2.d into multiple tests.
When looking at failures on ARM64, this aided in understanding which
specific tests weren't passing.

Regression tested on x86_64-linux-gnu, committed to mainline.

Regards,
Iain.

---
gcc/testsuite/ChangeLog:

* gdc.dg/Wbuiltin_declaration_mismatch2.d: Split test into ...
* gdc.dg/Wbuiltin_declaration_mismatch3.d: New test.
* gdc.dg/Wbuiltin_declaration_mismatch4.d: New test.
* gdc.dg/Wbuiltin_declaration_mismatch5.d: New test.
* gdc.dg/Wbuiltin_declaration_mismatch6.d: New test.
---
 .../gdc.dg/Wbuiltin_declaration_mismatch2.d   | 176 --
 .../gdc.dg/Wbuiltin_declaration_mismatch3.d   |  61 ++
 .../gdc.dg/Wbuiltin_declaration_mismatch4.d   |  51 +
 .../gdc.dg/Wbuiltin_declaration_mismatch5.d   |  53 ++
 .../gdc.dg/Wbuiltin_declaration_mismatch6.d   |  61 ++
 5 files changed, 226 insertions(+), 176 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch3.d
 create mode 100644 gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch4.d
 create mode 100644 gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch5.d
 create mode 100644 gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch6.d

diff --git a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d 
b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
index 0d12bcb8b07..8dcba79bfc3 100644
--- a/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
+++ b/gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d
@@ -28,183 +28,7 @@ void test_load_store()
 storeUnaligned!fake4(null, f); // { dg-warning "mismatch in return type" }
 }
 
-void test_shuffle()
-{
-shuffle!(int, int, int)(0, 0, 0); // { dg-warning "mismatch in return 
type" }
-shuffle!(double, int, int)(0, 0, 0); // { dg-warning "mismatch in return 
type" }
-shuffle!(fake4, int, int)(f, 0, 0); // { dg-warning "mismatch in return 
type" }
-
-shuffle!(int4, int, int)(0, 0, 0); // { dg-warning "mismatch in argument 
2" }
-shuffle!(int4, double, int)(0, 0, 0); // { dg-warning "mismatch in 
argument 2" }
-shuffle!(int4, fake4, int)(0, f, 0); // { dg-warning "mismatch in argument 
2" }
-
-shuffle!(int4, int4, int)(0, 0, 0); // { dg-warning "mismatch in argument 
3" }
-shuffle!(int4, int4, double)(0, 0, 0); // { dg-warning "mismatch in 
argument 3" }
-shuffle!(int4, int4, fake4)(0, 0, f); // { dg-warning "mismatch in 
argument 3" }
-
-shuffle!(int4, int4, int4)(0, 0, 0);
-shuffle!(int4, short8, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(int4, float4, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(int4, byte16, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(int4, int4, short8)(0, 0, 0); // { dg-error "mismatch in argument 
3" }
-shuffle!(int4, int4, float4)(0, 0, 0); // { dg-error "mismatch in argument 
3" }
-shuffle!(int4, int4, byte16)(0, 0, 0); // { dg-error "mismatch in argument 
3" }
-
-shuffle!(float4, int4, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(float4, short8, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(float4, float4, int4)(0, 0, 0);
-shuffle!(float4, byte16, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(float4, float4, short8)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(float4, float4, float4)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(float4, float4, byte16)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-
-shuffle!(short8, int4, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(short8, short8, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(short8, float4, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(short8, byte16, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(short8, short8, short8)(0, 0, 0);
-shuffle!(short8, short8, float4)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(short8, short8, byte16)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-
-shuffle!(byte16, int4, int4)(0, 0, 0); // { dg-error "mismatch in argument 
2" }
-shuffle!(byte16, short8, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(byte16, float4, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 2" }
-shuffle!(byte16, byte16, int4)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(byte16, byte16, short8)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(byte16, byte16, float4)(0, 0, 0); // { dg-error "mismatch in 
argument 3" }
-shuffle!(byte16, byte16, byte16)(0, 0, 0);
-}
-
-void test_shufflevector()
-{
-shufflevector!(int, int4, int, int, int, int)(0, 0, 0, 0, 0, 0); // { 
dg-warning "mismatch in argument 1" }
-shufflevector!(double, int4, int, int, int, int)(0, 0, 0, 0, 0, 

Re: [PATCH v2] RISC-V: Fix wrong LMUL when only implict zve32f.

2025-03-24 Thread Kito Cheng
On Mon, Mar 24, 2025 at 6:53 PM Robin Dapp  wrote:
>
> Hi Kito,
>
> > So valid range fractional LMUL for SEW=8, 16 32 are:
> >
> > mf8 = [8, (1/8)*32] = [8, 4] = [], no SEW is valid with mf8 for ELEN = 32
> > mf4 = [8, (1/4)*32] = [8, 8] = only SEW 8 with mf4 is valid
> > mf2 = [8, (1/2)*32] = [8, 16] = SEW 8 and 16 with mf2 are valid
> >
> > [1] 
> > https://github.com/riscvarchive/riscv-v-spec/blob/master/v-spec.adoc#342-vector-register-grouping-vlmul20
>
> Yes, so AFAIK we currently prohibit SEW/LMUL combinations/modes that would 
> lead
> to sub-element modes but we don't prevent MF8 for ELEN = 32 entirely.
>
> Isn't the issue here that an ELEN = 32 but VLEN 32 implementation could decide
> to not to implement MF8 at all (even if it didn't lead to issues with the
> proper VLEN) so we must not use it?

This does not only happen on ELEN=32 and VLEN=32, it happened on all
ELEN=32 arch, and one of our internal configurations hit this...

> That's unfortunate but in line with other
> IMHO unfortunate spec decisions like unaligned vector access so there's no way
> around it.

I didn't get the point around the unaligned vector stuff? Do you mean
the access does not align to VLEN or something else, do you mind
giving a few examples?

> What's the plan for this patch now?

As I mentioned before, our internal configuration hit this issue, so
our goal is to include this for GCC 15, also I think this also does
not affect all other targets with zve64* and v, so this should be
pretty safe changes I think. (I mean won't affect almost all other
people/core.)

>
> > I am not sure I got the point, we are using early clobber to avoid the
> > overlap constraint, that's pretty conservative way and should not lead
> > the problem here when we using LMUL=1/SEW=32 for V2SI, or are you
> > worry about we may put two V2SI within single vector register?
>
> Hmm, yeah I don't remember what I was thinking here.  It should be ok to use
> LMUL = 1, right.  What I don't see is the connection to the issue the patch is
> addressing, though.  I would expect a test that ensures we're not emitting an
> mf8 vsetvl.

Yeah, that sounds reasonable, will add a testcase in v3

>
> --
> Regards
>  Robin
>


[PATCH 0/2] cobol: Add a library spec (lingcobol.spec).

2025-03-24 Thread Iain Sandoe
This adds support for target-configured specs for library-specific
specs.  Initially, we will use this for the libm (but it's then
required by other pending patches).

The first patch adds to the driver and the library, the second makes
the spec available to in-tree testing.

tested on x86_64-linux, darwin, aarch64-linux, OK for trunk?
thanks
Iain

-

Iain Sandoe (2):
  cobol, driver, libgcobol: Add support for libgcobol.spec.
  testsuite, cobol: If libgcobol has a .spec file use it.

 gcc/cobol/gcobolspec.cc | 41 ++-
 gcc/testsuite/lib/cobol.exp |  5 +++-
 libgcobol/Makefile.am   |  2 ++
 libgcobol/Makefile.in   | 48 ++---
 libgcobol/configure | 12 +-
 libgcobol/configure.ac  | 16 +++--
 libgcobol/libgcobol.spec.in |  8 +++
 7 files changed, 82 insertions(+), 50 deletions(-)
 create mode 100644 libgcobol/libgcobol.spec.in

-- 
2.39.2 (Apple Git-143)



Re: [PATCH v2] libstdc++: Fix std::vector::append_range for overlapping ranges

2025-03-24 Thread Jonathan Wakely
On Mon, 24 Mar 2025 at 14:18, Patrick Palka  wrote:
>
> On Mon, 24 Mar 2025, Jonathan Wakely wrote:
>
> > Unlike insert_range and assign_range, the append_range function does not
> > have a precondition that the range doesn't overlap *this. That means we
> > need to avoid relocating the existing elements until after copying from
> > the range. This means I need to revert r15-8488-g3e1d760bf49d0e which
> > made the from_range_t constructor use append_range, because the
> > constructor can avoid the additional complexity needed by append_range.
> > When relocating the existing elements in append_range we can use
> > std::__relocate_a to do it more efficiently, if that's valid.
> >
> > std::vector::append_range needs similar treatment, although it's a
> > bit simpler as we know that the elements are trivially copyable and so
> > we don't need to worry about them throwing. assign_range doesn't allow
> > overlapping ranges, so can be rewritten to be more efficient than
> > calling append_range for the forward or sized range case.
> >
> > libstdc++-v3/ChangeLog:
> >
> >   * include/bits/stl_bvector.h (vector::assign_range): More
> >   efficient implementation for forward/sized ranges.
> >   (vector::append_range): Handle potentially overlapping range.
> >   * include/bits/stl_vector.h (vector(from_range_t, R&&, Alloc)):
> >   Do not use append_range for non-sized input range case.
> >   (vector::append_range)
> >   (vector::append_range): Handle potentially overlapping range.
> >   * include/bits/vector.tcc (vector::insert_range): Forward range
> >   instead of moving it.
> >   * 
> > testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc:
> >   Test overlapping ranges.
> >   * testsuite/23_containers/vector/modifiers/append_range.cc:
> >   Likewise.
> > ---
> >
> > Changed vector::assign_range to just use a loop for the
> > non-sized input range case, instead of calling append_range.
> >
> > Changed private copy ctor to deleted move ctor in RAII type.
> >
> > Testing x86_64-linux now.
> >
> >  libstdc++-v3/include/bits/stl_bvector.h   |  69 ++--
> >  libstdc++-v3/include/bits/stl_vector.h| 101 ++-
> >  libstdc++-v3/include/bits/vector.tcc  |   2 +-
> >  .../bool/modifiers/insert/append_range.cc |  50 ++
> >  .../vector/modifiers/append_range.cc  | 164 ++
> >  5 files changed, 366 insertions(+), 20 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
> > b/libstdc++-v3/include/bits/stl_bvector.h
> > index 3ee15eaa938..5addab048c9 100644
> > --- a/libstdc++-v3/include/bits/stl_bvector.h
> > +++ b/libstdc++-v3/include/bits/stl_bvector.h
> > @@ -1035,8 +1035,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >   assign_range(_Rg&& __rg)
> >   {
> > static_assert(assignable_from > ranges::range_reference_t<_Rg>>);
> > -   clear();
> > -   append_range(std::forward<_Rg>(__rg));
> > +   if constexpr (ranges::forward_range<_Rg> || 
> > ranges::sized_range<_Rg>)
> > + {
> > +   if (auto __n = size_type(ranges::distance(__rg)))
> > + {
> > +   reserve(__n);
> > +   this->_M_impl._M_finish
> > +   = ranges::copy(std::forward<_Rg>(__rg), begin()).out;
> > + }
> > +   else
> > + clear();
> > + }
> > +   else
> > + {
> > +   clear();
> > +   auto __first = ranges::begin(__rg);
> > +   const auto __last = ranges::end(__rg);
> > +   for (; __first != __last; ++__first)
> > + emplace_back(*__first);
> > + }
> >   }
> >  #endif
> >
> > @@ -1385,24 +1402,52 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >   constexpr void
> >   append_range(_Rg&& __rg)
> >   {
> > +   // N.B. append_range(r) allows r to overlap with *this,
> > +   // e.g. it could be *this | views::filter(pred) | views::to_input
> > +   // and so we must not invalidate existing elements too soon.
> > if constexpr (ranges::forward_range<_Rg> || 
> > ranges::sized_range<_Rg>)
> >   {
> > -   reserve(size() + size_type(ranges::distance(__rg)));
> > -   this->_M_impl._M_finish = ranges::copy(__rg, end()).out;
> > +   const auto __n = size_type(ranges::distance(__rg));
> > +   const auto __sz = size();
> > +
> > +   // If there are no existing elements it's safe to allocate now.
> > +   if (__sz == 0)
> > + reserve(__n);
> > +
> > +   const auto __capacity = capacity();
> > +   if ((__capacity - __sz) >= __n)
> > + {
> > +   this->_M_impl._M_finish
> > +   = ranges::copy(std::forward<_Rg>(__rg), end()).out;
> > +   return;
> > + }
> > +
> > +   vector __tmp(get_allocator());
> > +   __tmp.reserve(_M_check_len(__n, "vector::append_range"));
>

[COMMITTED 127/141] gccrs: Remove finalize import visitor

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

This visitor is not used anymore.

gcc/rust/ChangeLog:

* resolve/rust-finalize-imports-2.0.cc 
(FinalizeImports::FinalizeImports):
Remove constructor.
(FinalizeImports::go): Remove function.
(FinalizeImports::visit): Likewise.
* resolve/rust-finalize-imports-2.0.h (class FinalizeImports): Remove
FinalizeImports class.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 18 --
 gcc/rust/resolve/rust-finalize-imports-2.0.h  | 57 ---
 2 files changed, 75 deletions(-)

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index bd6002a09f4..b0e86512ac2 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -125,23 +125,5 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
   // Handle cycles ?
 }
 
-FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
- TopLevel &toplevel,
- NameResolutionContext &ctx)
-  : DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
-ctx (ctx)
-{}
-
-void
-FinalizeImports::go (AST::Crate &crate)
-{
-  for (auto &item : crate.items)
-item->accept_vis (*this);
-}
-
-void
-FinalizeImports::visit (AST::UseDeclaration &use)
-{}
-
 } // namespace Resolver2_0
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index a06fe538846..d587a5e5c46 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -49,62 +49,5 @@ private:
   NameResolutionContext &ctx;
 };
 
-// TODO: Fix documentation
-// How do we do that?
-//
-// We want to resolve in the EarlyNameResolver, but we want to declare in the
-// TopLevel Should the TopLevel declare stubs? How does rustc do it? How to do
-// that for globbing? Should we do globbing afterwards once we've declared all
-// the Uses*?
-//
-// Basically, for each use declare it in a separate map - in the
-// EarlyNameResolver resolve and fix the ForeverStack? Emptying the maps each
-// time?
-//
-// e.g. TopLevel builds a std::vector use_trees_to_resolve;
-// Early goes through and resolves the SimplePath, then replaces the NodeId 
with
-// the resolved one? Do we even need to do that?
-//
-// rustc just creates an empty definition for the use tree.
-//
-// What about globbing? std::vector globules;
-// Early goes through and visits the module's path and calls the
-// GlobbingVisitor?
-//
-// the file `imports.rs` goes through and *finalizes* imports. So we can
-// probably add a FinalizeImport pass after the TopLevel and the Early.
-// - TopLevel takes care of declaring these use trees
-// - Early takes care of resolving them to definition points
-// - Finalize takes care of mapping the use's definition point to the actual
-// definition point
-// - We need to work more on that last bit to know exactly what is being
-// inserted, but probably it's going to mutate the ForeverStack - is that okay?
-// - Oh actually maybe no!
-// - TopLevel creates a map of UseTrees with paths to resolve. This should
-// probably be an ImportKind enum or whatever
-// - Early resolves them, creates a map of SimplePath with the associated
-// definition: Map
-// - Finalizes visits all UseTrees and inserts the Definitions found for
-// each ImportKind - easy!
-// - yay!
-
-class FinalizeImports : DefaultResolver
-{
-public:
-  FinalizeImports (Early::ImportMappings &&data, TopLevel &toplevel,
-  NameResolutionContext &ctx);
-
-  void go (AST::Crate &crate);
-
-  void visit (AST::UseDeclaration &) override;
-
-private:
-  using AST::DefaultASTVisitor::visit;
-
-  Early::ImportMappings data;
-  TopLevel &toplevel;
-  NameResolutionContext &ctx;
-};
-
 } // namespace Resolver2_0
 } // namespace Rust
-- 
2.45.2



[COMMITTED 023/141] gccrs: marklive: Fix handling for lang item PathInExpressions.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* checks/lints/rust-lint-marklive.cc (MarkLive::visit): Adapt to lang 
items.
---
 gcc/rust/checks/lints/rust-lint-marklive.cc | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 4b524d710c9..6e2e2e4e447 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -22,6 +22,8 @@
 #include "rust-lint-marklive.h"
 #include "options.h"
 #include "rust-hir-full.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
 #include "rust-name-resolver.h"
 #include "rust-immutable-name-resolution-context.h"
 #include "rust-system.h"
@@ -99,15 +101,21 @@ MarkLive::visit (HIR::PathInExpression &expr)
 {
   // We should iterate every path segment in order to mark the struct which
   // is used in expression like Foo::bar(), we should mark the Foo alive.
-  expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
-return visit_path_segment (seg);
-  });
+  if (!expr.is_lang_item ())
+expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
+  return visit_path_segment (seg);
+});
 
   // after iterate the path segments, we should mark functions and associated
   // functions alive.
   NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
   NodeId ref_node_id = UNKNOWN_NODEID;
-  find_ref_node_id (ast_node_id, ref_node_id);
+
+  if (expr.is_lang_item ())
+ref_node_id
+  = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+  else
+find_ref_node_id (ast_node_id, ref_node_id);
 
   // node back to HIR
   tl::optional hid = mappings.lookup_node_to_hir (ref_node_id);
-- 
2.45.2



[COMMITTED 018/141] gccrs: mappings: Improve error message for get_lang_item_node

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::get_lang_item_node): Better 
formatting when a lang
item does not exist when it should.
---
 gcc/rust/util/rust-hir-map.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 39c3a98f16b..e58f1a2a715 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1305,8 +1305,8 @@ Mappings::get_lang_item_node (LangItem::Kind item_type)
   if (auto lookup = lookup_lang_item_node (item_type))
 return *lookup;
 
-  rust_fatal_error (UNKNOWN_LOCATION, "failed to find lang item %qs",
-   LangItem::ToString (item_type).c_str ());
+  rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs",
+   LangItem::PrettyString (item_type).c_str ());
 }
 
 void
-- 
2.45.2



[COMMITTED 002/141] gccrs: typecheck: Add basic handling for applying auto trait bounds

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Register auto 
traits in mappings.
* util/rust-hir-map.cc (Mappings::insert_auto_trait): New.
(Mappings::get_auto_traits): New.
* util/rust-hir-map.h: Declare them.
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Add auto trait 
bounds when
scanning.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Some parts of nr2.0 can't handle auto 
traits yet.
* rust/compile/auto_traits3.rs: Removed in favor of...
* rust/compile/auto_traits2.rs: ...this one.
* rust/compile/auto_traits4.rs: New test.
---
 gcc/rust/hir/rust-ast-lower-item.cc| 11 +++
 gcc/rust/typecheck/rust-tyty-bounds.cc |  4 +++
 gcc/rust/util/rust-hir-map.cc  | 12 
 gcc/rust/util/rust-hir-map.h   |  6 
 gcc/testsuite/rust/compile/auto_traits2.rs |  5 ++--
 gcc/testsuite/rust/compile/auto_traits3.rs | 34 --
 gcc/testsuite/rust/compile/auto_traits4.rs | 14 +
 gcc/testsuite/rust/compile/nr2/exclude |  3 +-
 8 files changed, 46 insertions(+), 43 deletions(-)
 delete mode 100644 gcc/testsuite/rust/compile/auto_traits3.rs
 create mode 100644 gcc/testsuite/rust/compile/auto_traits4.rs

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index ae938d98658..5dbcad59dfb 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -606,17 +606,18 @@ ASTLoweringItem::visit (AST::Trait &trait)
 mappings.get_next_hir_id (crate_num),
 mappings.get_next_localdef_id (crate_num));
 
-  auto trait_unsafety = Unsafety::Normal;
-  if (trait.is_unsafe ())
-{
-  trait_unsafety = Unsafety::Unsafe;
-}
+  auto trait_unsafety
+= trait.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
 
   HIR::Trait *hir_trait
 = new HIR::Trait (mapping, trait.get_identifier (), trait_unsafety,
  std::move (generic_params), std::move (type_param_bounds),
  where_clause, std::move (trait_items), vis,
  trait.get_outer_attrs (), trait.get_locus ());
+
+  if (trait.is_auto ())
+mappings.insert_auto_trait (hir_trait);
+
   translated = hir_trait;
 
   for (auto trait_item_id : trait_item_ids)
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 73d686b7814..3e42427e2ec 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -97,6 +97,10 @@ TypeBoundsProbe::scan ()
 
   // marker traits...
   assemble_sized_builtin ();
+
+  // add auto trait bounds
+  for (auto *auto_trait : mappings.get_auto_traits ())
+add_trait_bound (auto_trait);
 }
 
 void
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index b94591e014c..ac18e575765 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1309,5 +1309,17 @@ Mappings::get_lang_item_node (LangItem::Kind item_type)
LangItem::ToString (item_type).c_str ());
 }
 
+void
+Mappings::insert_auto_trait (HIR::Trait *trait)
+{
+  auto_traits.emplace_back (trait);
+}
+
+std::vector &
+Mappings::get_auto_traits ()
+{
+  return auto_traits;
+}
+
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 21e532812ff..8ea86466220 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -342,6 +342,9 @@ public:
   tl::optional
   lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
 
+  void insert_auto_trait (HIR::Trait *trait);
+  std::vector &get_auto_traits ();
+
 private:
   Mappings ();
 
@@ -380,6 +383,9 @@ private:
   std::map hirTraitItemsToTraitMappings;
   std::map hirPatternMappings;
 
+  // FIXME: Add documentation
+  std::vector auto_traits;
+
   // We need to have two maps here, as lang-items need to be used for both AST
   // passes and HIR passes. Thus those two maps are created at different times.
   std::map lang_item_mappings;
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs 
b/gcc/testsuite/rust/compile/auto_traits2.rs
index 7d0dcc11cd2..382d4460811 100644
--- a/gcc/testsuite/rust/compile/auto_traits2.rs
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -15,12 +15,11 @@ fn foo(a: &(dyn A + Send + Sync)) {
 struct S;
 
 impl A for S {
-fn a_method(&self) {}
+fn a_method(&self) {} // { dg-warning "unused name" }
 }
 
 fn main() {
 let s = S;
 
-foo(&s); // { dg-error "bounds not satisfied" }
- // { dg-error "mismatched type" "" { target *-*-* } .-1 }
+foo(&s);
 }
diff --git a/gcc/testsuite/rust/compile/auto_traits3.rs 
b/gcc/testsuite/rust/compile/auto_traits3.rs
deleted file mode 100644
index 81c39ecda7f..000
--- a/gcc/testsuite/rust/compile/auto_traits3.r

[COMMITTED 034/141] gccrs: Compile unit struct with constructor

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): Do
not use query system for unit struct but compile it's constructor
instead.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index a40f5542a68..103f0cb6fe8 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -180,6 +180,11 @@ ResolvePathRef::resolve_with_node_id (
}
 }
 
+  // Handle unit struct
+  if (lookup->get_kind () == TyTy::TypeKind::ADT)
+return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+
   // let the query system figure it out
   tree resolved_item = query_compile (ref, lookup, final_segment, mappings,
  expr_locus, is_qualified_path);
-- 
2.45.2



[COMMITTED 028/141] gccrs: Add unit struct to name namespace in old resolver

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

We missed the name namespace for unit struct in the old resolver.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-toplevel.h: Add struct to name namespace.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-ast-resolve-toplevel.h | 23 +---
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h 
b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 565ca922e84..6828e573618 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -242,14 +242,21 @@ public:
 auto path = prefix.append (decl);
 auto cpath = canonical_prefix.append (decl);
 
-resolver->get_type_scope ().insert (
-  path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
-  Rib::ItemType::Type,
-  [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
-   rich_location r (line_table, struct_decl.get_locus ());
-   r.add_range (locus);
-   rust_error_at (r, "redefined multiple times");
-  });
+auto duplicate_item
+  = [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+  rich_location r (line_table, struct_decl.get_locus ());
+  r.add_range (locus);
+  rust_error_at (r, "redefined multiple times");
+};
+
+resolver->get_type_scope ().insert (path, struct_decl.get_node_id (),
+   struct_decl.get_locus (), false,
+   Rib::ItemType::Type, duplicate_item);
+
+if (struct_decl.is_unit_struct ())
+  resolver->get_name_scope ().insert (path, struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ Rib::ItemType::Type, duplicate_item);
 
 NodeId current_module = resolver->peek_current_module_scope ();
 mappings.insert_module_child_item (current_module, decl);
-- 
2.45.2



[COMMITTED 112/141] gccrs: Reduce usage of rust-session-manager.h

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* util/rust-edition.cc: New file.
* util/rust-edition.h: New file.
* Make-lang.in: Add rust-edition.o to the object list.

* ast/rust-pattern.cc: Remove inclusion of
rust-session-manager.h.
* expand/rust-macro-expand.cc: Likewise.
* expand/rust-macro-builtins-helpers.h: Likewise.

* expand/rust-macro-builtins-include.cc: Include
rust-session-manager.h.
* expand/rust-macro-builtins-utility.cc: Likewise.

* lex/rust-lex.cc: Include rust-edition.h instead of
rust-session-manager.h.
(Lexer::classify_keyword): Use get_rust_edition instead of
Session and CompileOptions.

* parse/rust-parse-impl.h: Include rust-edition.h instead of
rust-session-manager.h.
(Parser::parse_async_item): Use get_rust_edition instead of
Session and CompileOptions.

* checks/errors/rust-feature.h: Include rust-edition.h instead
of rust-session-manager.h.
(class Feature): Use Rust::Edition instead of
Rust::CompileOptions::Edition.

Signed-off-by: Owen Avery 
---
 gcc/rust/Make-lang.in |  1 +
 gcc/rust/ast/rust-pattern.cc  |  1 -
 gcc/rust/checks/errors/rust-feature.h |  6 +--
 gcc/rust/expand/rust-macro-builtins-helpers.h |  1 -
 .../expand/rust-macro-builtins-include.cc |  1 +
 .../expand/rust-macro-builtins-utility.cc |  1 +
 gcc/rust/expand/rust-macro-expand.cc  |  1 -
 gcc/rust/lex/rust-lex.cc  |  6 +--
 gcc/rust/parse/rust-parse-impl.h  |  5 +--
 gcc/rust/util/rust-edition.cc | 40 ++
 gcc/rust/util/rust-edition.h  | 41 +++
 11 files changed, 91 insertions(+), 13 deletions(-)
 create mode 100644 gcc/rust/util/rust-edition.cc
 create mode 100644 gcc/rust/util/rust-edition.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 749c1123e05..4028b47fa87 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -235,6 +235,7 @@ GRS_OBJS = \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
 rust/rust-unwrap-segment.o \
+rust/rust-edition.o \
rust/rust-expand-format-args.o \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 98fd8e52f5f..fc7b6107be0 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "rust-diagnostics.h"
 #include "rust-ast-visitor.h"
 #include "rust-macro.h"
-#include "rust-session-manager.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
 #include "rust-operators.h"
diff --git a/gcc/rust/checks/errors/rust-feature.h 
b/gcc/rust/checks/errors/rust-feature.h
index e2082c5efa5..9edae6d62c3 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/rust-feature.h
@@ -19,7 +19,7 @@
 #ifndef RUST_FEATURE_H
 #define RUST_FEATURE_H
 
-#include "rust-session-manager.h"
+#include "rust-edition.h"
 #include "optional.h"
 
 namespace Rust {
@@ -66,7 +66,7 @@ private:
   Feature (Name name, State state, const char *name_str,
   const char *rustc_since,
   tl::optional issue_number = tl::nullopt,
-  const tl::optional &edition = tl::nullopt,
+  const tl::optional &edition = tl::nullopt,
   const char *description = "")
 : m_state (state), m_name (name), m_name_str (name_str),
   m_rustc_since (rustc_since), m_issue (issue_number), edition (edition),
@@ -78,7 +78,7 @@ private:
   std::string m_name_str;
   std::string m_rustc_since;
   tl::optional m_issue;
-  tl::optional edition;
+  tl::optional edition;
   std::string m_description; // TODO: Switch to optional?
 
   static const std::map name_hash_map;
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h 
b/gcc/rust/expand/rust-macro-builtins-helpers.h
index ee5cae76764..429537e210a 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -29,7 +29,6 @@
 #include "rust-macro-invoc-lexer.h"
 #include "rust-macro.h"
 #include "rust-parse.h"
-#include "rust-session-manager.h"
 #include "rust-system.h"
 #include "rust-token.h"
 namespace Rust {
diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc 
b/gcc/rust/expand/rust-macro-builtins-include.cc
index 4719b0e268e..2ab2a3a1dbb 100644
--- a/gcc/rust/expand/rust-macro-builtins-include.cc
+++ b/gcc/rust/expand/rust-macro-builtins-include.cc
@@ -20,6 +20,7 @@
 #include "rust-common.h"
 #include "rust-macro-builtins.h"
 #include "rust-macro-builtins-helpers.h"
+#include "rust-session-manager.h"
 #include "optional.h"
 namespace Rust {
 /* Expand builtin macro include_bytes!("filename"), which includes the contents
diff --git a/gcc/rust/expand/rust-macro-builtins-utility.cc 
b/gcc/rust/expand/ru

[COMMITTED 115/141] gccrs: nr2.0: Set the node id of the root node

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::ForeverStack): Set the node id of the root node
to that of the current crate.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Use the node id of the root
node during resolution of crate segments.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h   | 7 +--
 gcc/rust/resolve/rust-forever-stack.hxx | 7 +--
 gcc/testsuite/rust/compile/nr2/exclude  | 2 --
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index f1e5e8d2f2d..64e8a0f0f2c 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -547,13 +547,16 @@ template  class ForeverStack
 {
 public:
   ForeverStack ()
-// FIXME: Is that valid? Do we use the root? If yes, we should give the
-// crate's node id to ForeverStack's constructor
 : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
   cursor_reference (root)
   {
 rust_assert (root.is_root ());
 rust_assert (root.is_leaf ());
+
+// TODO: Should we be using the forever stack root as the crate scope?
+// TODO: Is this how we should be getting the crate node id?
+auto &mappings = Analysis::Mappings::get ();
+root.id = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
   }
 
   /**
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 9ca8db2c09d..c1407344b52 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -401,12 +401,7 @@ ForeverStack::find_starting_point (
   if (seg.is_crate_path_seg ())
{
  starting_point = root;
- // TODO: is this how we should be getting the crate node id?
- auto &mappings = Analysis::Mappings::get ();
- NodeId current_crate
-   = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
-
- insert_segment_resolution (outer_seg, current_crate);
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
  iterator++;
  break;
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 763387f3548..e179dc30004 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,7 +1,6 @@
 break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
-complex-path1.rs
 const_generics_3.rs
 const_generics_4.rs
 feature_rust_attri0.rs
@@ -29,7 +28,6 @@ pub_restricted_2.rs
 pub_restricted_3.rs
 redef_error2.rs
 redef_error5.rs
-self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
-- 
2.45.2



[COMMITTED 090/141] gccrs: derive(PartialEq): Add partial implementation

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

We are still missing some deriving for enums, as part of our codegen and 
nameres for rebinding struct
field patterns is missing.

gcc/rust/ChangeLog:

* expand/rust-derive-partial-eq.cc: New file.
* expand/rust-derive-partial-eq.h: New file.
* expand/rust-derive.cc (DeriveVisitor::derive): Call them.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/derive-eq-invalid.rs: Mark PartialEq def as a lang item.
* rust/compile/derive-partialeq1.rs: New test.
* rust/execute/torture/derive-partialeq1.rs: New test.
* rust/compile/nr2/exclude: Exclude all of them.
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/expand/rust-derive-partial-eq.cc | 308 ++
 gcc/rust/expand/rust-derive-partial-eq.h  |  81 +
 gcc/rust/expand/rust-derive.cc|   2 +
 .../rust/compile/derive-eq-invalid.rs |   9 +-
 .../rust/compile/derive-partialeq1.rs |  59 
 gcc/testsuite/rust/compile/nr2/exclude|   2 +
 .../rust/execute/torture/derive-partialeq1.rs |  61 
 8 files changed, 519 insertions(+), 4 deletions(-)
 create mode 100644 gcc/rust/expand/rust-derive-partial-eq.cc
 create mode 100644 gcc/rust/expand/rust-derive-partial-eq.h
 create mode 100644 gcc/testsuite/rust/compile/derive-partialeq1.rs
 create mode 100644 gcc/testsuite/rust/execute/torture/derive-partialeq1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 83ffc47ce28..5e13c6cfc3f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -98,6 +98,7 @@ GRS_OBJS = \
 rust/rust-derive-copy.o \
 rust/rust-derive-debug.o \
 rust/rust-derive-default.o \
+rust/rust-derive-partial-eq.o \
 rust/rust-derive-eq.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc 
b/gcc/rust/expand/rust-derive-partial-eq.cc
new file mode 100644
index 000..6f7ef7d8780
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -0,0 +1,308 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-partial-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-operators.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+DerivePartialEq::DerivePartialEq (location_t loc)
+  : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr
+DerivePartialEq::go (Item &item)
+{
+  item.accept_vis (*this);
+
+  rust_assert (expanded);
+
+  return std::move (expanded);
+}
+
+std::unique_ptr
+DerivePartialEq::partial_eq_impl (
+  std::unique_ptr &&eq_fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto eq = builder.type_path (LangItem::Kind::EQ);
+
+  auto trait_items = vec (std::move (eq_fn));
+
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+
+  return builder.trait_impl (eq, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
+}
+
+std::unique_ptr
+DerivePartialEq::eq_fn (std::unique_ptr &&cmp_expression,
+   std::string type_name)
+{
+  auto block = builder.block (tl::nullopt, std::move (cmp_expression));
+
+  auto self_type
+= std::unique_ptr (new TypePath (builder.type_path 
("Self")));
+
+  auto params
+= vec (builder.self_ref_param (),
+  builder.function_param (builder.identifier_pattern ("other"),
+  builder.reference_type (
+std::move (self_type;
+
+  return builder.function ("eq", std::move (params),
+  builder.single_type_path ("bool"),
+  std::move (block));
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::tuple_indexes (int idx)
+{
+  return SelfOther{
+builder.tuple_idx ("self", idx),
+builder.tuple_idx ("other", idx),
+  };
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::field_acccesses (const std::string &field_name)
+{
+  return SelfOther{
+builder.field_access (builder.identifier ("self"), field_name),
+builder.field_access (builder.identifier ("other"), 

[COMMITTED 129/141] gccrs: Insert crate name in canonical path

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Insert a new segment with the crate's
name as canonical's path prefix.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 628b8c5b6fe..59142a4094c 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -704,7 +704,12 @@ ForeverStack::to_canonical_path (NodeId id) const
   return KeepGoing::Yes;
 });
 
-auto path = Resolver::CanonicalPath::create_empty ();
+auto &mappings = Analysis::Mappings::get ();
+CrateNum crate_num = mappings.lookup_crate_num (root.id).value ();
+auto path = Resolver::CanonicalPath::new_seg (
+  root.id, mappings.get_crate_name (crate_num).value ());
+path.set_crate_num (crate_num);
+
 for (const auto &segment : segments)
   path = path.append (segment);
 
-- 
2.45.2



[COMMITTED 120/141] gccrs: Add a test for enum variant name resolution

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Highlight the fact that a value inside an enum definition refers to
a struct outside of the enum and not to the enum variant's name
directly.

gcc/testsuite/ChangeLog:

* rust/compile/enum_variant_name.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/enum_variant_name.rs | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/enum_variant_name.rs

diff --git a/gcc/testsuite/rust/compile/enum_variant_name.rs 
b/gcc/testsuite/rust/compile/enum_variant_name.rs
new file mode 100644
index 000..671fced2bb8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_variant_name.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w -frust-name-resolution-2.0" }
+struct E1;
+
+enum Test {
+E1 = {
+let x = E1;
+{
+let x = E1;
+}
+0
+},
+}
-- 
2.45.2



[COMMITTED 132/141] gccrs: nr2.0: Check compile/torture/*.rs tests

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/testsuite/ChangeLog:

* rust/compile/nr2/compile.exp: Adjust to cover tests in the
torture subdirectory.
* rust/compile/nr2/exclude: Add entries.

Signed-off-by: Owen Avery 
---
 gcc/testsuite/rust/compile/nr2/compile.exp |  6 ++
 gcc/testsuite/rust/compile/nr2/exclude | 17 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp 
b/gcc/testsuite/rust/compile/nr2/compile.exp
index f2724f6c454..35637f11ee8 100644
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ b/gcc/testsuite/rust/compile/nr2/compile.exp
@@ -14,9 +14,7 @@
 # along with GCC; see the file COPYING3.  If not see
 # .
 
-# Compile tests, no torture testing, for name resolution 2.0
-#
-# These tests raise errors in the front end; torture testing doesn't apply.
+# Run compile tests with name resolution 2.0 enabled
 
 # Load support procs.
 load_lib rust-dg.exp
@@ -44,7 +42,7 @@ namespace eval rust-nr2-ns {
 # Run tests in directories
 # Manually specifying these, in case some other test file
 # does something weird
-set test_dirs {{} {macros builtin} {macros mbe} {macros proc}}
+set test_dirs {{} {macros builtin} {macros mbe} {macros proc} {torture}}
 
 set tests_expect_ok ""
 set tests_expect_err ""
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 8aaec5d3b22..d36c24b95e3 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -50,4 +50,21 @@ for-loop2.rs
 issue-3403.rs
 derive-eq-invalid.rs
 derive-hash1.rs
+torture/alt_patterns1.rs
+torture/builtin_abort.rs
+torture/impl_block3.rs
+torture/issue-1434.rs
+torture/loop4.rs
+torture/loop8.rs
+torture/methods1.rs
+torture/methods2.rs
+torture/methods3.rs
+torture/name_resolve1.rs
+torture/nested_struct1.rs
+torture/struct_init_3.rs
+torture/uninit-intrinsic-1.rs
+torture/generics1.rs
+torture/generics10.rs
+torture/generics13.rs
+torture/generics6.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 088/141] gccrs: ast-builder: Add new methods for creating operator expressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::literal_bool): New method.
(Builder::comparison_expr): Likewise.
(Builder::boolean_operation): Likewise.
* ast/rust-ast-builder.h: Declare them.
---
 gcc/rust/ast/rust-ast-builder.cc | 46 
 gcc/rust/ast/rust-ast-builder.h  | 20 ++
 2 files changed, 66 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index f59ff19d621..82e6a5abe24 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -21,9 +21,11 @@
 #include "rust-ast.h"
 #include "rust-common.h"
 #include "rust-expr.h"
+#include "rust-keyword-values.h"
 #include "rust-path.h"
 #include "rust-item.h"
 #include "rust-path.h"
+#include "rust-pattern.h"
 #include "rust-system.h"
 #include "rust-token.h"
 #include 
@@ -39,6 +41,17 @@ Builder::literal_string (std::string &&content) const
  PrimitiveCoreType::CORETYPE_STR, {}, loc));
 }
 
+std::unique_ptr
+Builder::literal_bool (bool b) const
+{
+  auto str
+= b ? Values::Keywords::TRUE_LITERAL : Values::Keywords::FALSE_LITERAL;
+
+  return std::unique_ptr (
+new AST::LiteralExpr (std::move (str), Literal::LitType::BOOL,
+ PrimitiveCoreType::CORETYPE_BOOL, {}, loc));
+}
+
 std::unique_ptr
 Builder::call (std::unique_ptr &&path,
   std::vector> &&args) const
@@ -279,6 +292,14 @@ Builder::path_in_expression (LangItem::Kind lang_item) 
const
   return PathInExpression (lang_item, {}, loc);
 }
 
+PathInExpression
+Builder::variant_path (const std::string &enum_path,
+  const std::string &variant) const
+{
+  return PathInExpression ({path_segment (enum_path), path_segment (variant)},
+  {}, loc, false);
+}
+
 std::unique_ptr
 Builder::block (tl::optional> &&stmt,
std::unique_ptr &&tail_expr) const
@@ -331,6 +352,24 @@ Builder::deref (std::unique_ptr &&of) const
   return std::unique_ptr (new DereferenceExpr (std::move (of), {}, loc));
 }
 
+std::unique_ptr
+Builder::comparison_expr (std::unique_ptr &&lhs,
+ std::unique_ptr &&rhs,
+ ComparisonOperator op) const
+{
+  return std::make_unique (std::move (lhs), std::move (rhs), 
op,
+  loc);
+}
+
+std::unique_ptr
+Builder::boolean_operation (std::unique_ptr &&lhs,
+   std::unique_ptr &&rhs,
+   LazyBooleanOperator op) const
+{
+  return std::make_unique (std::move (lhs), std::move (rhs),
+   op, loc);
+}
+
 std::unique_ptr
 Builder::struct_struct (std::string struct_name,
std::vector> &&generics,
@@ -390,6 +429,13 @@ Builder::wildcard () const
   return std::unique_ptr (new WildcardPattern (loc));
 }
 
+std::unique_ptr
+Builder::ref_pattern (std::unique_ptr &&inner) const
+{
+  return std::make_unique (std::move (inner), false, false,
+loc);
+}
+
 std::unique_ptr
 Builder::lang_item_path (LangItem::Kind kind) const
 {
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 9fbcea182be..faf3cf74df9 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -23,6 +23,7 @@
 #include "rust-expr.h"
 #include "rust-ast.h"
 #include "rust-item.h"
+#include "rust-operators.h"
 
 namespace Rust {
 namespace AST {
@@ -62,6 +63,9 @@ public:
   /* Create a string literal expression ("content") */
   std::unique_ptr literal_string (std::string &&content) const;
 
+  /* Create a boolean literal expression (true) */
+  std::unique_ptr literal_bool (bool b) const;
+
   /* Create an identifier expression (`variable`) */
   std::unique_ptr identifier (std::string name) const;
   std::unique_ptr identifier_pattern (std::string name,
@@ -81,6 +85,16 @@ public:
   /* Create a dereference of an expression (`*of`) */
   std::unique_ptr deref (std::unique_ptr &&of) const;
 
+  /* Build a comparison expression (`lhs == rhs`) */
+  std::unique_ptr comparison_expr (std::unique_ptr &&lhs,
+std::unique_ptr &&rhs,
+ComparisonOperator op) const;
+
+  /* Build a lazy boolean operator expression (`lhs && rhs`) */
+  std::unique_ptr boolean_operation (std::unique_ptr &&lhs,
+  std::unique_ptr &&rhs,
+  LazyBooleanOperator op) const;
+
   /* Create a block with an optional tail expression */
   std::unique_ptr block (std::vector> &&stmts,
std::unique_ptr &&tail_expr
@@ -191,6 +205,10 @@ public:
*/
   PathInExpression path_in_expression (LangItem::Kind lang_item) const;
 
+  /* Create the path to an enum's variant (`Result::Ok`) */
+  PathInExpression variant

[COMMITTED 124/141] gccrs: check for recursion trait cycle with bounds checks

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We need to be careful when doing bounds check as to not create a recusive
trait resolution. This patch checks for that case and fixes a bad type
is equal check on ADT Types which was caught with a regression here.

Fixes Rust-GCC#3126

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc (TraitResolver::ResolveHirItem): 
new helper
* typecheck/rust-hir-trait-resolve.h: add helper prototype
* typecheck/rust-type-util.cc (query_type): add debug
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): check for 
recursion
* typecheck/rust-tyty.cc (VariantDef::is_equal): fix is equal check

gcc/testsuite/ChangeLog:

* rust/execute/torture/issue-3126.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 10 
 gcc/rust/typecheck/rust-hir-trait-resolve.h   |  2 +
 gcc/rust/typecheck/rust-type-util.cc  |  7 ++-
 gcc/rust/typecheck/rust-tyty-bounds.cc|  9 
 gcc/rust/typecheck/rust-tyty.cc   |  3 --
 .../rust/execute/torture/issue-3126.rs| 52 +++
 6 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/issue-3126.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 98323f63132..58a0f014926 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -107,6 +107,16 @@ TraitResolver::Lookup (HIR::TypePath &path)
   return resolver.lookup_path (path);
 }
 
+HIR::Trait *
+TraitResolver::ResolveHirItem (const HIR::TypePath &path)
+{
+  TraitResolver resolver;
+
+  HIR::Trait *lookup = nullptr;
+  bool ok = resolver.resolve_path_to_trait (path, &lookup);
+  return ok ? lookup : nullptr;
+}
+
 TraitResolver::TraitResolver () : TypeCheckBase () {}
 
 bool
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h 
b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index 916abe6c9d0..b79fe17ee3e 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -58,6 +58,8 @@ public:
 
   static TraitReference *Lookup (HIR::TypePath &path);
 
+  static HIR::Trait *ResolveHirItem (const HIR::TypePath &path);
+
 private:
   TraitResolver ();
 
diff --git a/gcc/rust/typecheck/rust-type-util.cc 
b/gcc/rust/typecheck/rust-type-util.cc
index 7a39eb53710..4abfbae3665 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -87,8 +87,11 @@ query_type (HirId reference, TyTy::BaseType **result)
   // is it an impl_type?
   if (auto impl_block_by_type = mappings.lookup_impl_block_type (reference))
 {
-  *result
-   = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type.value ());
+  // found an impl item
+  HIR::ImplBlock *impl = impl_block_by_type.value ();
+  rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
+ reference);
+  *result = TypeCheckItem::ResolveImplBlockSelf (*impl);
   context->query_completed (reference);
   return true;
 }
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 9187fc63141..d7007879228 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -20,6 +20,7 @@
 #include "rust-hir-type-bounds.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-substitution-mapper.h"
+#include "rust-hir-trait-resolve.h"
 #include "rust-type-util.h"
 
 namespace Rust {
@@ -71,6 +72,14 @@ TypeBoundsProbe::scan ()
   if (!impl->has_trait_ref ())
return true;
 
+  // can be recursive trait resolution
+  HIR::Trait *t = TraitResolver::ResolveHirItem (impl->get_trait_ref ());
+  if (t == nullptr)
+   return true;
+  DefId trait_id = t->get_mappings ().get_defid ();
+  if (context->trait_query_in_progress (trait_id))
+   return true;
+
   HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
   TyTy::BaseType *impl_type = nullptr;
   if (!query_type (impl_ty_id, &impl_type))
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 3951fa88da8..efad5f61322 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -1566,9 +1566,6 @@ VariantDef::is_equal (const VariantDef &other) const
   if (identifier.compare (other.identifier) != 0)
 return false;
 
-  if (discriminant != other.discriminant)
-return false;
-
   if (fields.size () != other.fields.size ())
 return false;
 
diff --git a/gcc/testsuite/rust/execute/torture/issue-3126.rs 
b/gcc/testsuite/rust/execute/torture/issue-3126.rs
new file mode 100644
index 000..f5051467f02
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3126.rs
@@ -0,0 +1,52 @@
+/* { dg-output "child\r*\n" }*/
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+#[lang = "size

[COMMITTED 078/146] gccrs: implement the TuplePattern and use it for function patterns

2025-03-24 Thread arthur . cohen
From: Philip Herron 

In order to handle the tuple pattern of: fn test ((x _) : (i32, i32)) -> i32 { 
x }
we need to recognize that ABI wise this function still takes a tuple as the 
parameter
to this function its just how we can address the "pattern" of the tuple changes.

So reall if this was C it would look like:

  void test (struct tuple_type __prameter)
  {
return __parameter.0
  }

The code here reuses our existing pattern code so that we generate these 
implicit
bindings of the paramter with a field access so any time x is referenced it's 
really
just emplacing __parameter.0 for the field access into the struct which is a 
tuple.

Fixes Rust-GCC#2847

gcc/rust/ChangeLog:

* backend/rust-compile-fnparam.cc (CompileFnParam::visit): compile 
tuple patterns
(CompileSelfParam::compile): update return type
(CompileFnParam::create_tmp_param_var): return Bvariable not tree to 
stop ICE
* backend/rust-compile-fnparam.h: update prototype
* backend/rust-compile-pattern.cc (CompilePatternBindings::visit): 
implement TuplePattern
* backend/rust-compile-pattern.h: update prototype

gcc/testsuite/ChangeLog:

* rust/compile/issue-2847.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-fnparam.cc | 31 ++---
 gcc/rust/backend/rust-compile-fnparam.h  |  4 +-
 gcc/rust/backend/rust-compile-pattern.cc | 86 
 gcc/rust/backend/rust-compile-pattern.h  |  2 +-
 gcc/testsuite/rust/compile/issue-2847.rs |  8 +++
 5 files changed, 117 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2847.rs

diff --git a/gcc/rust/backend/rust-compile-fnparam.cc 
b/gcc/rust/backend/rust-compile-fnparam.cc
index c00092d219e..b40065e110d 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -68,25 +68,36 @@ CompileFnParam::visit (HIR::WildcardPattern &pattern)
   compiled_param = Backend::parameter_variable (fndecl, "_", decl_type, locus);
 }
 
+void
+CompileFnParam::visit (HIR::TuplePattern &pattern)
+{
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+pattern, Backend::var_expression (compiled_param, locus), ctx);
+}
+
 void
 CompileFnParam::visit (HIR::StructPattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 void
 CompileFnParam::visit (HIR::TupleStructPattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 void
 CompileFnParam::visit (HIR::ReferencePattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 Bvariable *
@@ -102,7 +113,7 @@ CompileSelfParam::compile (Context *ctx, tree fndecl, 
HIR::SelfParam &self,
   return Backend::parameter_variable (fndecl, "self", decl_type, locus);
 }
 
-tree
+Bvariable *
 CompileFnParam::create_tmp_param_var (tree decl_type)
 {
   // generate the anon param
@@ -110,10 +121,8 @@ CompileFnParam::create_tmp_param_var (tree decl_type)
   std::string cpp_str_identifier = std::string (IDENTIFIER_POINTER 
(tmp_ident));
 
   decl_type = Backend::immutable_type (decl_type);
-  compiled_param = Backend::parameter_variable (fndecl, cpp_str_identifier,
-   decl_type, locus);
-
-  return Backend::var_expression (compiled_param, locus);
+  return Backend::parameter_variable (fndecl, cpp_str_identifier, decl_type,
+ locus);
 }
 
 } // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-fnparam.h 
b/gcc/rust/backend/rust-compile-fnparam.h
index 82a705fde7b..189216c9ba4 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -47,12 +47,12 @@ public:
   void visit (HIR::QualifiedPathInExpression &) override {}
   void visit (HIR::RangePattern &) override {}
   void visit (HIR::SlicePattern &) override {}
-  void visit (HIR::TuplePattern &) override {}
+  void visit (HIR::TuplePattern &) override;
 
 private:
   CompileFnParam (Context *ctx, tree fndecl, tree decl_type, location_t locus);
 
-  tree create_tmp_param_var (tree decl_type);
+  Bvariable *create_tmp_param_var (tree decl_type);
 
   tree fndecl;
   tree decl_type;
diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/back

[COMMITTED 122/144] rust: fix ICE during name resolution for impls on unit-types

2025-03-24 Thread arthur . cohen
From: Philip Herron 

The canonical paths need to support unit-types which are technically a
TupleType with no fields. This handles this case and adds an unreachable.

Fixes #3036

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): 
add unit-type catch
* resolve/rust-ast-resolve-type.h: likewise

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3036.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  9 +
 gcc/rust/resolve/rust-ast-resolve-type.h  |  2 ++
 gcc/testsuite/rust/compile/issue-3036.rs  | 14 ++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 4 files changed, 26 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3036.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index cee259cceb4..ec5e8a762a7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -507,6 +507,15 @@ ResolveTypeToCanonicalPath::visit (AST::NeverType &type)
   result = CanonicalPath::new_seg (type.get_node_id (), "!");
 }
 
+void
+ResolveTypeToCanonicalPath::visit (AST::TupleType &type)
+{
+  if (!type.is_unit_type ())
+rust_unreachable ();
+
+  result = CanonicalPath::new_seg (type.get_node_id (), "()");
+}
+
 ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
   : ResolverBase (), result (CanonicalPath::create_empty ())
 {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 5e382445a14..561948e85b8 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -248,6 +248,8 @@ public:
 
   void visit (AST::NeverType &type) override;
 
+  void visit (AST::TupleType &type) override;
+
 private:
   ResolveTypeToCanonicalPath ();
 
diff --git a/gcc/testsuite/rust/compile/issue-3036.rs 
b/gcc/testsuite/rust/compile/issue-3036.rs
new file mode 100644
index 000..4418ccc04cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3036.rs
@@ -0,0 +1,14 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Default: Sized {
+#[stable(feature = "rust1", since = "1.0.0")]
+fn default() -> Self;
+}
+
+impl Default for () {
+fn default() -> () {
+()
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index bfb51fd7fee..50781e56b85 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -252,3 +252,4 @@ issue-3082.rs
 issue-3139-1.rs
 issue-3139-2.rs
 issue-3139-3.rs
+issue-3036.rs
-- 
2.45.2



[COMMITTED 133/141] gccrs: Fix modules with same name as builtins causing ICE (#3315)

2025-03-24 Thread arthur . cohen
From: Liam Naddell 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h (ForeverStack): Add a dedicated prelude 
node for
the Language prelude
* resolve/rust-forever-stack.hxx (ForeverStack): Add support code for 
the
prelude node
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Move
language prelude builtins to the prelude context
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::scoped): Add code for handling
the prelude corner case
* resolve/rust-rib.h (Rib::Kind): Add a special Prelude rib type

gcc/testsuite/ChangeLog:

* rust/compile/issue-3315-1.rs: Add test for module with same name
as builtin
* rust/compile/issue-3315-2.rs: Test with utilization of i32
type
* rust/compile/nr2/exclude: issue-3315-2.rs Does not work with
NR2.0

Signed-off-by: Liam Naddell 
---
 gcc/rust/resolve/rust-forever-stack.h | 12 +++
 gcc/rust/resolve/rust-forever-stack.hxx   | 82 ---
 .../resolve/rust-late-name-resolver-2.0.cc| 33 
 .../resolve/rust-name-resolution-context.cc   |  4 +
 gcc/rust/resolve/rust-rib.h   |  5 ++
 gcc/testsuite/rust/compile/issue-3315-1.rs|  8 ++
 gcc/testsuite/rust/compile/issue-3315-2.rs|  7 ++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 8 files changed, 127 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3315-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3315-2.rs

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 22efc973197..2a4c7348728 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -548,6 +548,7 @@ template  class ForeverStack
 public:
   ForeverStack ()
 : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
+  prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
   cursor_reference (root)
   {
 rust_assert (root.is_root ());
@@ -657,6 +658,8 @@ public:
* the current map, an empty one otherwise.
*/
   tl::optional get (const Identifier &name);
+  tl::optional get_prelude (const Identifier &name);
+  tl::optional get_prelude (const std::string &name);
 
   /**
* Resolve a path to its definition in the current `ForeverStack`
@@ -721,6 +724,7 @@ private:
 {}
 
 bool is_root () const;
+bool is_prelude () const;
 bool is_leaf () const;
 
 void insert_child (Link link, Node child);
@@ -756,7 +760,15 @@ private:
   const Node &cursor () const;
   void update_cursor (Node &new_cursor);
 
+  /* The forever stack's actual nodes */
   Node root;
+  /*
+   * A special prelude node used currently for resolving language builtins
+   * It has the root node as a parent, and acts as a "special case" for name
+   * resolution
+   */
+  Node prelude;
+
   std::reference_wrapper cursor_reference;
 
   void stream_rib (std::stringstream &stream, const Rib &rib,
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 90e0ceb9f81..a6e0b30a57b 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -34,6 +34,13 @@ ForeverStack::Node::is_root () const
   return !parent.has_value ();
 }
 
+template 
+bool
+ForeverStack::Node::is_prelude () const
+{
+  return rib.kind == Rib::Kind::Prelude;
+}
+
 template 
 bool
 ForeverStack::Node::is_leaf () const
@@ -63,6 +70,16 @@ template 
 void
 ForeverStack::push_inner (Rib rib, Link link)
 {
+  if (rib.kind == Rib::Kind::Prelude)
+{
+  // If you push_inner into the prelude from outside the root, you will pop
+  // back into the root, which could screw up a traversal.
+  rust_assert (&cursor_reference.get () == &root);
+  // Prelude doesn't have an access path
+  rust_assert (!link.path);
+  update_cursor (this->prelude);
+  return;
+}
   // If the link does not exist, we create it and emplace a new `Node` with the
   // current node as its parent. `unordered_map::emplace` returns a pair with
   // the iterator and a boolean. If the value already exists, the iterator
@@ -300,6 +317,20 @@ ForeverStack::get (const Identifier &name)
   return resolved_definition;
 }
 
+template 
+tl::optional
+ForeverStack::get_prelude (const Identifier &name)
+{
+  return prelude.rib.get (name.as_string ());
+}
+
+template 
+tl::optional
+ForeverStack::get_prelude (const std::string &name)
+{
+  return prelude.rib.get (name);
+}
+
 template <>
 tl::optional inline ForeverStack::get (
   const Identifier &name)
@@ -399,7 +430,7 @@ ForeverStack::find_starting_point (
break;
 
   auto &seg = unwrap_type_segment (outer_seg);
-  auto is_self_or_crate
+  bool is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
 
   // if we're after the first path segment and meet `self` or `crate`, it's
@@ -457,7

[PATCH v2] libstdc++: Fix std::vector::append_range for overlapping ranges

2025-03-24 Thread Jonathan Wakely
Unlike insert_range and assign_range, the append_range function does not
have a precondition that the range doesn't overlap *this. That means we
need to avoid relocating the existing elements until after copying from
the range. This means I need to revert r15-8488-g3e1d760bf49d0e which
made the from_range_t constructor use append_range, because the
constructor can avoid the additional complexity needed by append_range.
When relocating the existing elements in append_range we can use
std::__relocate_a to do it more efficiently, if that's valid.

std::vector::append_range needs similar treatment, although it's a
bit simpler as we know that the elements are trivially copyable and so
we don't need to worry about them throwing. assign_range doesn't allow
overlapping ranges, so can be rewritten to be more efficient than
calling append_range for the forward or sized range case.

libstdc++-v3/ChangeLog:

* include/bits/stl_bvector.h (vector::assign_range): More
efficient implementation for forward/sized ranges.
(vector::append_range): Handle potentially overlapping range.
* include/bits/stl_vector.h (vector(from_range_t, R&&, Alloc)):
Do not use append_range for non-sized input range case.
(vector::append_range)
(vector::append_range): Handle potentially overlapping range.
* include/bits/vector.tcc (vector::insert_range): Forward range
instead of moving it.
* testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc:
Test overlapping ranges.
* testsuite/23_containers/vector/modifiers/append_range.cc:
Likewise.
---

Changed vector::assign_range to just use a loop for the
non-sized input range case, instead of calling append_range.

Changed private copy ctor to deleted move ctor in RAII type.

Testing x86_64-linux now.

 libstdc++-v3/include/bits/stl_bvector.h   |  69 ++--
 libstdc++-v3/include/bits/stl_vector.h| 101 ++-
 libstdc++-v3/include/bits/vector.tcc  |   2 +-
 .../bool/modifiers/insert/append_range.cc |  50 ++
 .../vector/modifiers/append_range.cc  | 164 ++
 5 files changed, 366 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index 3ee15eaa938..5addab048c9 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1035,8 +1035,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
assign_range(_Rg&& __rg)
{
  static_assert(assignable_from>);
- clear();
- append_range(std::forward<_Rg>(__rg));
+ if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
+   {
+ if (auto __n = size_type(ranges::distance(__rg)))
+   {
+ reserve(__n);
+ this->_M_impl._M_finish
+ = ranges::copy(std::forward<_Rg>(__rg), begin()).out;
+   }
+ else
+   clear();
+   }
+ else
+   {
+ clear();
+ auto __first = ranges::begin(__rg);
+ const auto __last = ranges::end(__rg);
+ for (; __first != __last; ++__first)
+   emplace_back(*__first);
+   }
}
 #endif
 
@@ -1385,24 +1402,52 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
constexpr void
append_range(_Rg&& __rg)
{
+ // N.B. append_range(r) allows r to overlap with *this,
+ // e.g. it could be *this | views::filter(pred) | views::to_input
+ // and so we must not invalidate existing elements too soon.
  if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
{
- reserve(size() + size_type(ranges::distance(__rg)));
- this->_M_impl._M_finish = ranges::copy(__rg, end()).out;
+ const auto __n = size_type(ranges::distance(__rg));
+ const auto __sz = size();
+
+ // If there are no existing elements it's safe to allocate now.
+ if (__sz == 0)
+   reserve(__n);
+
+ const auto __capacity = capacity();
+ if ((__capacity - __sz) >= __n)
+   {
+ this->_M_impl._M_finish
+ = ranges::copy(std::forward<_Rg>(__rg), end()).out;
+ return;
+   }
+
+ vector __tmp(get_allocator());
+ __tmp.reserve(_M_check_len(__n, "vector::append_range"));
+ __tmp._M_impl._M_finish
+  = _M_copy_aligned(cbegin(), cend(), __tmp.begin());
+ __tmp._M_impl._M_finish
+  = ranges::copy(std::forward<_Rg>(__rg), __tmp.end()).out;
+ swap(__tmp);
}
  else
{
  auto __first = ranges::begin(__rg);
  const auto __last = ranges::end(__rg);
- size_type __n = size();
- 

[COMMITTED 110/141] gccrs: lower: Error out when lowering ErrorPropagationExpr

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

Adapt functions for lowering nodes that should never reach the lowering phase 
to cause an
unreachable, and mark them as final so as it not possible to override them in 
other visitors.

gcc/rust/ChangeLog:

* hir/rust-ast-lower-base.cc: Adapt functions for ErrorPropagationExpr 
and MacroInvocation.
* hir/rust-ast-lower-base.h: Mark them as final.
* hir/rust-ast-lower-expr.cc: Remove previous definition for those 
overrides.
* hir/rust-ast-lower-expr.h: Likewise.
---
 gcc/rust/hir/rust-ast-lower-base.cc |  13 +-
 gcc/rust/hir/rust-ast-lower-base.h  | 356 ++--
 gcc/rust/hir/rust-ast-lower-expr.cc |  15 --
 gcc/rust/hir/rust-ast-lower-expr.h  |   1 -
 4 files changed, 188 insertions(+), 197 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index f38697cf316..c1fef3d7a20 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -23,6 +23,7 @@
 #include "rust-ast.h"
 #include "rust-attribute-values.h"
 #include "rust-diagnostics.h"
+#include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-system.h"
 #include "rust-attributes.h"
@@ -30,7 +31,6 @@
 namespace Rust {
 namespace HIR {
 
-// We special case lowering macro invocations as that should NEVER happen
 void
 ASTLoweringBase::visit (AST::MacroInvocation &invoc)
 {
@@ -38,6 +38,14 @@ ASTLoweringBase::visit (AST::MacroInvocation &invoc)
   rust_unreachable ();
 }
 
+void
+ASTLoweringBase::visit (AST::ErrorPropagationExpr &expr)
+{
+  rust_fatal_error (expr.get_locus (),
+   "missing desugar for question mark operator");
+  rust_unreachable ();
+}
+
 void
 ASTLoweringBase::visit (AST::Token &)
 {}
@@ -116,9 +124,6 @@ void
 ASTLoweringBase::visit (AST::DereferenceExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ErrorPropagationExpr &)
-{}
-void
 ASTLoweringBase::visit (AST::NegationExpr &)
 {}
 void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index 1bd1343bd16..b3bb174babf 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -60,202 +60,204 @@ class ASTLoweringBase : public AST::ASTVisitor
 public:
   virtual ~ASTLoweringBase () {}
 
+  // Special casing nodes that should never reach the HIR lowering stage
+  virtual void visit (AST::MacroInvocation &) override final;
+  virtual void visit (AST::ErrorPropagationExpr &) override final;
+
   // visitor impl
   // rust-ast.h
   //  virtual void visit(AttrInput& attr_input);
   //  virtual void visit(TokenTree& token_tree);
   //  virtual void visit(MacroMatch& macro_match);
-  virtual void visit (AST::Token &tok);
-  virtual void visit (AST::DelimTokenTree &delim_tok_tree);
-  virtual void visit (AST::AttrInputMetaItemContainer &input);
-  //  virtual void visit(MetaItem& meta_item);
-  //  void vsit(Stmt& stmt);
-  //  virtual void visit(Expr& expr);
-  virtual void visit (AST::IdentifierExpr &ident_expr);
-  //  virtual void visit(Pattern& pattern);
-  //  virtual void visit(Type& type);
-  //  virtual void visit(TypeParamBound& type_param_bound);
-  virtual void visit (AST::Lifetime &lifetime);
-  //  virtual void visit(GenericParam& generic_param);
-  virtual void visit (AST::LifetimeParam &lifetime_param);
-  virtual void visit (AST::ConstGenericParam &const_param);
-  //  virtual void visit(TraitItem& trait_item);
-  //  virtual void visit(InherentImplItem& inherent_impl_item);
-  //  virtual void visit(TraitImplItem& trait_impl_item);
+  virtual void visit (AST::Token &tok) override;
+  virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
+  virtual void visit (AST::AttrInputMetaItemContainer &input) override;
+  //  virtual void visit(MetaItem& meta_item) override;
+  //  void vsit(Stmt& stmt) override;
+  //  virtual void visit(Expr& expr) override;
+  virtual void visit (AST::IdentifierExpr &ident_expr) override;
+  //  virtual void visit(Pattern& pattern) override;
+  //  virtual void visit(Type& type) override;
+  //  virtual void visit(TypeParamBound& type_param_bound) override;
+  virtual void visit (AST::Lifetime &lifetime) override;
+  //  virtual void visit(GenericParam& generic_param) override;
+  virtual void visit (AST::LifetimeParam &lifetime_param) override;
+  virtual void visit (AST::ConstGenericParam &const_param) override;
+  //  virtual void visit(TraitItem& trait_item) override;
+  //  virtual void visit(InherentImplItem& inherent_impl_item) override;
+  //  virtual void visit(TraitImplItem& trait_impl_item) override;
 
   // rust-path.h
-  virtual void visit (AST::PathInExpression &path);
-  virtual void visit (AST::TypePathSegment &segment);
-  virtual void visit (AST::TypePathSegmentGeneric &segment);
-  virtual void visit (AST::TypePathSegmentFunction &segment);
-  virtual void visit (AST::TypePath &path);
-  virtual void visit (AST::QualifiedPathInExpression &path);
-  virtual void visit (AST::QualifiedPat

Re: [PATCH 06/10] testsuite: aarch64: arm: Add -mfpu=auto to arm_v8_2a_bf16_neon_ok

2025-03-24 Thread Richard Earnshaw (lists)
On 24/03/2025 14:52, Christophe Lyon wrote:
> On Mon, 24 Mar 2025 at 15:13, Richard Earnshaw (lists)
>  wrote:
>>
>> On 21/03/2025 17:30, Christophe Lyon wrote:
>>> On Fri, 21 Mar 2025 at 16:51, Richard Earnshaw (lists)
>>>  wrote:

 On 21/03/2025 15:15, Christophe Lyon wrote:
> On Fri, 21 Mar 2025 at 15:25, Richard Earnshaw (lists)
>  wrote:
>>
>> On 21/03/2025 14:05, Christophe Lyon wrote:
>>> On Fri, 21 Mar 2025 at 11:18, Richard Earnshaw (lists)
>>>  wrote:

 On 20/03/2025 16:15, Christophe Lyon wrote:
> Depending on if/how the testing flags are overridden, the first value
> we try("") might not do what we want.
>
> For instance, if the whole testsuite is executed with
> (A) -mthumb -march=armv7-m -mtune=cortex-m3 -mfloat-abi=softfp
>
> bf16_neon_ok is first compiled with
> (A) (B)
> where B = -mcpu=unset -march=armv8.2-a+bf16
>
> which is accepted, so a testcase like vld2q_lane_bf16_indices_1.c
> is compiled with:
> (A) (C) (B)
> where C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a 
> -mfpu=neon-fp16 -mfp16-format=ieee
>
> because advsimd-intrinsics.exp has set additional_flags to (C)
> via arm_neon_fp16_ok
>
> So the testcase is compiled with
> [...] -mfpu=neon-fp16 -mcpu=unset -march=armv8.2-a+bf16
> (thus -mfpu=neon-fp16) and bf16 support is disabled.
>
> The patch replaces "" with -mfpu=auto which matches the intended
> effect of -march=armv8.2-a+bf16 as added by bf16_neon_ok, and the
> testcase is now compiled with
> (A) (C) -mfpu=auto (B)
>
> However, since this effective-target is also used on aarch64 (which
> does not support -mfpu=auto), we do this only on arm.
>
> This patch improves coverage, and makes
> v{ld,st}[234]q_lane_bf16_indices_1.c pass when testsuite flags are
> overridden as described above (e.g. for M-profile).
>
>   gcc/testsuite/
>   * lib/target-supports.exp
>   (check_effective_target_arm_v8_2a_bf16_neon_ok_nocache):
>   Conditionally use -mfpu=auto.
> ---
>  gcc/testsuite/lib/target-supports.exp | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/testsuite/lib/target-supports.exp 
> b/gcc/testsuite/lib/target-supports.exp
> index e2622a445c5..09b16a14024 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -6871,12 +6871,19 @@ proc add_options_for_arm_fp16fml_neon { flags 
> } {
>  proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } {
>  global et_arm_v8_2a_bf16_neon_flags
>  set et_arm_v8_2a_bf16_neon_flags ""
> +set fpu_auto ""
>
>  if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
>   return 0;
>  }
>
> -foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" 
> "-mfloat-abi=hard -mfpu=neon-fp-armv8" } {
> +if { [istarget arm*-*-*] } {
> + set fpu_auto "-mfpu=auto"
> +}
> +
> +foreach flags [list "$fpu_auto" \

 Shouldn't we try first with "", even on Arm?  Thus
foreach flags [list "" "$fpu_auto" \
 ...

>>> I don't think so, that's why I tried to explain above.
>>> "" is acceptable / accepted in arm_v8_2a_bf16_neon_ok
>>> (this is (A) (B) above, where the important parts are:
>>> -march=armv7-m -mcpu=unset -march=armv8.2-a+bf16
>>> (so -mfpu is set to the toolchain's default)
>>
>> That's never going to work reliably.  We need to check, somewhere, the 
>> full set of options we intend to pass to the compilation.  We can't 
>> assume that separately testing if A is ok and B is ok => A + B is ok.
>>
>
> Hmmm I think I raised that problem years ago, because of the way the
> test system is designed...
>
>>>
>>> but then the actual testcase is compiled with additional flags (C)
>>> defined by the test driver using arm_neon_fp16_ok
>>> C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a
>>> -mfpu=neon-fp16 -mfp16-format=ieee
>>>
>>> so the relevant parts of (A) (C) (B) are:
>>> -march=armv7-m  -mfpu=neon -mcpu=unset -march=armv7-a -mfpu=neon-fp16
>>> -mcpu=unset -march=armv8.2-a+bf16
>>> which can be simplified into
>>> -mfpu=neon-fp16 -march=armv8.2-a+bf16
>>>
>>> I think we need to start with -mfpu=auto instead of "", so that when
>>> -march=armv8.2-a+bf16 takes effect, we have cancelled any other -mfpu.
>>>
>>
>> Ideally a test shouldn't add any options 

[COMMITTED 134/141] gccrs: emit an error for type or const parameters on foreign items

2025-03-24 Thread arthur . cohen
From: Ryutaro Okada <1015ry...@gmail.com>

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-implitem.cc 
(TypeCheckTopLevelExternItem::visit):
emit an error for type or const parameters on foreign items

gcc/testsuite/ChangeLog:

* rust/compile/extern_generics.rs: New test.

Signed-off-by: Ryutaro Okada <1015ry...@gmail.com>
---
 gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 11 +++
 gcc/testsuite/rust/compile/extern_generics.rs  |  8 
 2 files changed, 19 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/extern_generics.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 7d31d3653ce..a5ae54bf493 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -86,9 +86,20 @@ TypeCheckTopLevelExternItem::visit 
(HIR::ExternalFunctionItem &function)
case HIR::GenericParam::GenericKind::CONST:
  // FIXME: Skipping Lifetime and Const completely until better
  // handling.
+ if (parent.get_abi () != Rust::ABI::INTRINSIC)
+   {
+ rust_error_at (function.get_locus (), ErrorCode::E0044,
+"foreign items may not have const parameters");
+   }
  break;
 
  case HIR::GenericParam::GenericKind::TYPE: {
+   if (parent.get_abi () != Rust::ABI::INTRINSIC)
+ {
+   rust_error_at (
+ function.get_locus (), ErrorCode::E0044,
+ "foreign items may not have type parameters");
+ }
auto param_type
  = TypeResolveGenericParam::Resolve (*generic_param);
context->insert_type (generic_param->get_mappings (),
diff --git a/gcc/testsuite/rust/compile/extern_generics.rs 
b/gcc/testsuite/rust/compile/extern_generics.rs
new file mode 100644
index 000..26f97a64ff5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/extern_generics.rs
@@ -0,0 +1,8 @@
+#[lang="sized"]
+trait Sized {}
+
+
+// E0044
+fn main() {
+extern "C" { fn some_func(x: T); } // { dg-error "foreign items may not 
have type parameters .E0044." }
+}
\ No newline at end of file
-- 
2.45.2



[COMMITTED 116/141] gccrs: Add rib kind debug representation

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Rib kind had no string representation, and thus were not used in the
debug string representation.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Output rib kind.
* resolve/rust-rib.h: Add function to get string representation from
a rib kind.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 10 ++---
 gcc/rust/resolve/rust-rib.h | 29 +
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index c1407344b52..9e66c802d5f 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -781,13 +781,17 @@ ForeverStack::stream_rib (std::stringstream &stream, 
const Rib &rib,
 const std::string &next,
 const std::string &next_next) const
 {
+  std::string rib_kind = Rib::kind_to_string (rib.kind);
+  stream << next << "rib [" << rib_kind << "]: {";
   if (rib.get_values ().empty ())
 {
-  stream << next << "rib: {},\n";
+  stream << "}\n";
   return;
 }
-
-  stream << next << "rib: {\n";
+  else
+{
+  stream << "\n";
+}
 
   for (const auto &kv : rib.get_values ())
 stream << next_next << kv.first << ": " << kv.second.to_string () << "\n";
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index 2eb8de8f0ef..767547f985f 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -175,6 +175,35 @@ public:
 ConstParamType,
   } kind;
 
+  static std::string kind_to_string (Rib::Kind kind)
+  {
+switch (kind)
+  {
+  case Rib::Kind::Normal:
+   return "Normal";
+  case Rib::Kind::Module:
+   return "Module";
+  case Rib::Kind::Function:
+   return "Function";
+  case Rib::Kind::ConstantItem:
+   return "ConstantItem";
+  case Rib::Kind::TraitOrImpl:
+   return "TraitOrImpl";
+  case Rib::Kind::Item:
+   return "Item";
+  case Rib::Kind::Closure:
+   return "Closure";
+  case Rib::Kind::MacroDefinition:
+   return "Macro definition";
+  case Rib::Kind::ForwardTypeParamBan:
+   return "Forward type param ban";
+  case Rib::Kind::ConstParamType:
+   return "Const Param Type";
+  default:
+   rust_unreachable ();
+  }
+  }
+
   Rib (Kind kind);
   Rib (Kind kind, std::string identifier, NodeId id);
   Rib (Kind kind, std::unordered_map values);
-- 
2.45.2



[COMMITTED 097/141] gccrs: Remove some member functions from SingleASTNode

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* ast/rust-ast.h
(SingleASTNode::take_trait_item): Remove.
(SingleASTNode::take_impl_item): Remove.
(SingleASTNode::take_trait_impl_item): Remove.
* expand/rust-expand-visitor.cc
(ExpandVisitor::visit): Replace calls to aforementioned
functions with calls to SingleASTNode::take_assoc_item.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast.h| 17 -
 gcc/rust/expand/rust-expand-visitor.cc |  7 ---
 2 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 42be097f056..4d7d23d23cc 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1996,13 +1996,6 @@ public:
 return std::move (item);
   }
 
-  std::unique_ptr take_trait_item ()
-  {
-rust_assert (!is_error ());
-return std::unique_ptr (
-  static_cast (assoc_item.release ()));
-  }
-
   std::unique_ptr take_external_item ()
   {
 rust_assert (!is_error ());
@@ -2015,16 +2008,6 @@ public:
 return std::move (assoc_item);
   }
 
-  std::unique_ptr take_impl_item ()
-  {
-return take_assoc_item ();
-  }
-
-  std::unique_ptr take_trait_impl_item ()
-  {
-return take_assoc_item ();
-  }
-
   std::unique_ptr take_type ()
   {
 rust_assert (!is_error ());
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 2830d200f72..1d131b18180 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -865,7 +865,7 @@ ExpandVisitor::visit (AST::Trait &trait)
 
   std::function (AST::SingleASTNode)>
 extractor
-= [] (AST::SingleASTNode node) { return node.take_trait_item (); };
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::TRAIT,
 trait.get_trait_items (), extractor);
@@ -892,7 +892,8 @@ ExpandVisitor::visit (AST::InherentImpl &impl)
 expand_where_clause (impl.get_where_clause ());
 
   std::function (AST::SingleASTNode)>
-extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); 
};
+extractor
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::IMPL,
 impl.get_impl_items (), extractor);
@@ -920,7 +921,7 @@ ExpandVisitor::visit (AST::TraitImpl &impl)
 
   std::function (AST::SingleASTNode)>
 extractor
-= [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
 impl.get_impl_items (), extractor);
-- 
2.45.2



[COMMITTED 092/141] gccrs: derive(PartialEq): Also derive StructuralPartialEq

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-partial-eq.cc: Adapt signatures to generate two 
impls.
* expand/rust-derive-partial-eq.h: Likewise.
* expand/rust-derive.cc (DeriveVisitor::derive): Adapt to multiple item 
generation.

gcc/testsuite/ChangeLog:

* rust/compile/derive-eq-invalid.rs: Declare StructuralPartialEq.
* rust/compile/derive-partialeq1.rs: Likewise.
* rust/execute/torture/derive-partialeq1.rs: Likewise.
---
 gcc/rust/expand/rust-derive-partial-eq.cc | 43 +++
 gcc/rust/expand/rust-derive-partial-eq.h  | 10 +++--
 gcc/rust/expand/rust-derive.cc|  2 +-
 .../rust/compile/derive-eq-invalid.rs |  6 +++
 .../rust/compile/derive-partialeq1.rs |  3 ++
 .../rust/execute/torture/derive-partialeq1.rs |  3 ++
 6 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc 
b/gcc/rust/expand/rust-derive-partial-eq.cc
index 6f7ef7d8780..ff66faabc78 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.cc
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -27,35 +27,40 @@
 
 namespace Rust {
 namespace AST {
-DerivePartialEq::DerivePartialEq (location_t loc)
-  : DeriveVisitor (loc), expanded (nullptr)
-{}
+DerivePartialEq::DerivePartialEq (location_t loc) : DeriveVisitor (loc) {}
 
-std::unique_ptr
+std::vector>
 DerivePartialEq::go (Item &item)
 {
   item.accept_vis (*this);
 
-  rust_assert (expanded);
-
   return std::move (expanded);
 }
 
-std::unique_ptr
-DerivePartialEq::partial_eq_impl (
+std::vector>
+DerivePartialEq::partialeq_impls (
   std::unique_ptr &&eq_fn, std::string name,
   const std::vector> &type_generics)
 {
   auto eq = builder.type_path (LangItem::Kind::EQ);
+  auto speq = builder.type_path (LangItem::Kind::STRUCTURAL_PEQ);
 
   auto trait_items = vec (std::move (eq_fn));
 
-  auto generics
+  // no extra bound on StructuralPeq
+  auto peq_generics
 = setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+  auto speq_generics = setup_impl_generics (name, type_generics);
+
+  auto peq = builder.trait_impl (eq, std::move (peq_generics.self_type),
+std::move (trait_items),
+std::move (peq_generics.impl));
+
+  auto structural_peq
+= builder.trait_impl (speq, std::move (speq_generics.self_type), {},
+ std::move (speq_generics.impl));
 
-  return builder.trait_impl (eq, std::move (generics.self_type),
-std::move (trait_items),
-std::move (generics.impl));
+  return vec (std::move (peq), std::move (structural_peq));
 }
 
 std::unique_ptr
@@ -137,7 +142,7 @@ DerivePartialEq::visit_tuple (TupleStruct &item)
   auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
 
   expanded
-= partial_eq_impl (std::move (fn), type_name, item.get_generic_params ());
+= partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
 }
 
 void
@@ -153,7 +158,7 @@ DerivePartialEq::visit_struct (StructStruct &item)
   auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
 
   expanded
-= partial_eq_impl (std::move (fn), type_name, item.get_generic_params ());
+= partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
 }
 
 MatchCase
@@ -250,11 +255,12 @@ void
 DerivePartialEq::visit_enum (Enum &item)
 {
   auto cases = std::vector ();
+  auto type_name = item.get_identifier ().as_string ();
 
   for (auto &variant : item.get_variants ())
 {
   auto variant_path
-   = builder.variant_path (item.get_identifier ().as_string (),
+   = builder.variant_path (type_name,
variant->get_identifier ().as_string ());
 
   switch (variant->get_enum_item_kind ())
@@ -290,11 +296,10 @@ DerivePartialEq::visit_enum (Enum &item)
 builder.identifier ("other"))),
 std::move (cases));
 
-  auto fn = eq_fn (std::move (match), item.get_identifier ().as_string ());
+  auto fn = eq_fn (std::move (match), type_name);
 
   expanded
-= partial_eq_impl (std::move (fn), item.get_identifier ().as_string (),
-  item.get_generic_params ());
+= partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
 }
 
 void
diff --git a/gcc/rust/expand/rust-derive-partial-eq.h 
b/gcc/rust/expand/rust-derive-partial-eq.h
index 2bc18d2b98a..ac963a63c8a 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.h
+++ b/gcc/rust/expand/rust-derive-partial-eq.h
@@ -30,12 +30,16 @@ class DerivePartialEq : DeriveVisitor
 public:
   DerivePartialEq (location_t loc);
 
-  std::unique_ptr go (Item &item);
+  std::vector> go (Item &item);
 
 private:
-  std:

[COMMITTED 101/141] gccrs: hir-dump: Fix more segfaults in the HIR dump

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc: Check unique_ptr members are present before
visiting them.
* hir/tree/rust-hir-path.h: Add `has_{type, trait}` methods to
QualifiedPathInType.
---
 gcc/rust/hir/rust-hir-dump.cc | 19 +--
 gcc/rust/hir/tree/rust-hir-path.h |  9 -
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 686127750b4..d4958410013 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -315,6 +315,14 @@ Dump::do_functionparam (FunctionParam &e)
 void
 Dump::do_pathpattern (PathPattern &e)
 {
+  if (e.get_path_kind () == PathPattern::Kind::LangItem)
+{
+  put_field ("segments", "#[lang = \""
+  + LangItem::ToString (e.get_lang_item ())
+  + "\"]");
+  return;
+}
+
   std::string str = "";
 
   for (const auto &segment : e.get_segments ())
@@ -405,9 +413,12 @@ void
 Dump::do_qualifiedpathtype (QualifiedPathType &e)
 {
   do_mappings (e.get_mappings ());
-  visit_field ("type", e.get_type ());
+  if (e.has_type ())
+visit_field ("type", e.get_type ());
+  else
+put_field ("type", "none");
 
-  if (e.has_as_clause ())
+  if (e.has_trait ())
 visit_field ("trait", e.get_trait ());
 }
 
@@ -527,6 +538,8 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
 
   if (e.has_return_type ())
 visit_field ("return_type", e.get_return_type ());
+  else
+put_field ("return_type", "none");
 
   if (e.has_where_clause ())
 put_field ("where_clause", e.get_where_clause ().as_string ());
@@ -1306,6 +1319,8 @@ Dump::visit (BreakExpr &e)
 
   if (e.has_break_expr ())
 visit_field ("break_expr ", e.get_expr ());
+  else
+put_field ("break_expr", "none");
 
   end ("BreakExpr");
 }
diff --git a/gcc/rust/hir/tree/rust-hir-path.h 
b/gcc/rust/hir/tree/rust-hir-path.h
index c46f81e981c..3ce2662c802 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -733,13 +733,20 @@ public:
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
+  bool has_type () { return type != nullptr; }
+  bool has_trait () { return trait != nullptr; }
+
   Type &get_type ()
   {
 rust_assert (type);
 return *type;
   }
 
-  TypePath &get_trait () { return *trait; }
+  TypePath &get_trait ()
+  {
+rust_assert (trait);
+return *trait;
+  }
 
   bool trait_has_generic_args () const;
 
-- 
2.45.2



[COMMITTED 108/141] gccrs: Adjust unknown macro error message

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc
(Early::visit): Adjust error produced when macro resolution
fails.
* resolve/rust-early-name-resolver.cc
(EarlyNameResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro43.rs: Adjust expected errors.
* rust/compile/macros/mbe/macro44.rs: Likewise.
* rust/compile/nested_macro_use2.rs: Likewise.
* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 3 ++-
 gcc/rust/resolve/rust-early-name-resolver.cc | 3 ++-
 gcc/testsuite/rust/compile/macros/mbe/macro43.rs | 2 +-
 gcc/testsuite/rust/compile/macros/mbe/macro44.rs | 2 +-
 gcc/testsuite/rust/compile/nested_macro_use2.rs  | 2 +-
 gcc/testsuite/rust/compile/nr2/exclude   | 2 --
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 764be45e34c..b894d130ccf 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -280,7 +280,8 @@ Early::visit (AST::MacroInvocation &invoc)
   if (!definition.has_value ())
 {
   collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
-   "could not resolve macro invocation"));
+   "could not resolve macro invocation %qs",
+   path.as_string ().c_str ()));
   return;
 }
 
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index a8df631200c..fc9a26ccac0 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -477,7 +477,8 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
   bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node);
   if (!found)
 {
-  rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
+  rust_error_at (invoc.get_locus (), ErrorCode::E0433,
+"could not resolve macro invocation %qs",
 seg.get ().c_str ());
   return;
 }
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
index 992bc77cedf..fbc36a9d6e5 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
@@ -48,7 +48,7 @@ macro_rules! nonzero_integers {
 
 }
 
-impl_nonzero_fmt! { // { dg-error "unknown macro" }
+impl_nonzero_fmt! { // { dg-error "could not resolve macro 
invocation" }
 (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
 }
 )+
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
index dabac6f7844..0cfd98718b4 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
@@ -16,7 +16,7 @@ mod foo {
 }
 
 fn bar_f() {
-baz!(); // { dg-error "unknown macro" }
+baz!(); // { dg-error "could not resolve macro invocation" }
 }
 }
 
diff --git a/gcc/testsuite/rust/compile/nested_macro_use2.rs 
b/gcc/testsuite/rust/compile/nested_macro_use2.rs
index 46595008710..7bb6154c28c 100644
--- a/gcc/testsuite/rust/compile/nested_macro_use2.rs
+++ b/gcc/testsuite/rust/compile/nested_macro_use2.rs
@@ -8,5 +8,5 @@ mod foo {
 }
 
 fn main() {
-baz!(); // { dg-error "unknown macro: .baz." }
+baz!(); // { dg-error "could not resolve macro invocation .baz." }
 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6dba0f71705..02da99de52f 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -21,11 +21,9 @@ issue-855.rs
 iterators1.rs
 lookup_err1.rs
 macros/mbe/macro43.rs
-macros/mbe/macro44.rs
 macros/mbe/macro6.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
-nested_macro_use2.rs
 not_find_value_in_scope.rs
 privacy5.rs
 privacy8.rs
-- 
2.45.2



[COMMITTED 135/141] gccrs: nr2.0: Fix test self-path2.rs

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-path.cc
(ResolvePath::resolve_path): Adjust the error message for a lower
self segment in the middle of a path.
* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove self-path2.rs
* rust/compile/self-path2.rs: Adjust expected errors.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-ast-resolve-path.cc | 14 +++---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  4 ++--
 gcc/testsuite/rust/compile/nr2/exclude|  1 -
 gcc/testsuite/rust/compile/self-path2.rs  |  4 ++--
 4 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc 
b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 256159bc5cc..656b7e64bb7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -68,8 +68,8 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
   if (in_middle_of_path && segment.is_lower_self_seg ())
{
  rust_error_at (segment.get_locus (), ErrorCode::E0433,
-"failed to resolve: %qs in paths can only be used "
-"in start position",
+"leading path segment %qs can only be used at the "
+"beginning of a path",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -192,7 +192,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
  else
{
  rust_error_at (segment.get_locus (),
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -212,7 +212,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
   else if (is_first_segment)
{
  rust_error_at (segment.get_locus (), ErrorCode::E0433,
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -331,7 +331,7 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
  else
{
  rust_error_at (segment.get_locus (),
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -379,7 +379,7 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
   if (resolved_node_id == UNKNOWN_NODEID)
{
  rust_error_at (segment.get_locus (),
-"cannot find simple path segment %qs in this scope",
+"cannot find simple path segment %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index af63898a5d2..87643d775ff 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -176,8 +176,8 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId 
&resolved_node_id)
  if (in_middle_of_path && segment->is_lower_self_seg ())
{
  rust_error_at (segment->get_locus (), ErrorCode::E0433,
-"failed to resolve: %qs in paths can only be used "
-"in start position",
+"leading path segment %qs can only be used at the "
+"beginning of a path",
 segment->as_string ().c_str ());
  return false;
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index a4bac9ac836..a2a833f9073 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -28,7 +28,6 @@ pub_restricted_2.rs
 pub_restricted_3.rs
 redef_error2.rs
 redef_error5.rs
-self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
 undeclared_label.rs
diff --git a/gcc/testsuite/rust/compile/self-path2.rs 
b/gcc/testsuite/rust/compile/self-path2.rs
index b9b82cae5a6..6441c3328f9 100644
--- a/gcc/testsuite/rust/compile/self-path2.rs
+++ b/gcc/testsuite/rust/compile/self-path2.rs
@@ -11,11 +11,11 @@ fn baz() {
 crate::bar();
 
 crate::self::foo();
-// { dg-error "failed to resolve: .self. in p

[COMMITTED 140/141] gccrs: nr2.0: Fix StructExprFieldIdentifier handling

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Add visitor for StructExprFieldIdentifier.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 28 +++
 .../resolve/rust-late-name-resolver-2.0.h |  1 +
 gcc/testsuite/rust/compile/nr2/exclude|  8 --
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 09aa5fc44e6..cf7b7dcd03f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -259,6 +259,34 @@ Late::visit (AST::IdentifierExpr &expr)
   // toplevel instead insert a name in ctx.values? (like it currently does)
 }
 
+void
+Late::visit (AST::StructExprFieldIdentifier &expr)
+{
+  tl::optional resolved = tl::nullopt;
+
+  if (auto value = ctx.values.get (expr.get_field_name ()))
+{
+  resolved = value;
+}
+  // seems like we don't need a type namespace lookup
+  else
+{
+  rust_error_at (expr.get_locus (), "could not resolve struct field: %qs",
+expr.get_field_name ().as_string ().c_str ());
+  return;
+}
+
+  if (resolved->is_ambiguous ())
+{
+  rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+expr.as_string ().c_str ());
+  return;
+}
+
+  ctx.map_usage (Usage (expr.get_node_id ()),
+Definition (resolved->get_node_id ()));
+}
+
 void
 Late::visit (AST::PathInExpression &expr)
 {
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 31303eb4fb2..ac376b5cb6f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -46,6 +46,7 @@ public:
 
   // resolutions
   void visit (AST::IdentifierExpr &) override;
+  void visit (AST::StructExprFieldIdentifier &) override;
   void visit (AST::BreakExpr &) override;
   void visit (AST::PathInExpression &) override;
   void visit (AST::TypePath &) override;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 59964fc90e2..fed7bde6307 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -23,7 +23,6 @@ pub_restricted_1.rs
 pub_restricted_2.rs
 pub_restricted_3.rs
 sizeof-stray-infer-var-bug.rs
-struct-expr-parse.rs
 undeclared_label.rs
 use_1.rs
 while_break_expr.rs
@@ -40,15 +39,8 @@ derive-eq-invalid.rs
 derive-hash1.rs
 torture/alt_patterns1.rs
 torture/builtin_abort.rs
-torture/impl_block3.rs
-torture/issue-1434.rs
 torture/loop4.rs
 torture/loop8.rs
-torture/methods1.rs
-torture/methods2.rs
-torture/methods3.rs
 torture/name_resolve1.rs
-torture/nested_struct1.rs
-torture/struct_init_3.rs
 torture/uninit-intrinsic-1.rs
 # please don't delete the trailing newline
-- 
2.45.2



  1   2   3   >