[gcc r16-61] Skip g++.dg/eh/pr119507.C on arm eabi

2025-04-21 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:6e0ffa9e8f36223700ff0cef30ba14305e8a8074

commit r16-61-g6e0ffa9e8f36223700ff0cef30ba14305e8a8074
Author: Andrew Pinski 
Date:   Mon Apr 21 20:52:38 2025 -0700

Skip g++.dg/eh/pr119507.C on arm eabi

arm eabi emits the exception table using the handlerdata directive
and does not use a comdat section for comdat functions. So this
testcase should be skipped for arm eabi.

Pushed as obvious after a quick test.

gcc/testsuite/ChangeLog:

* g++.dg/eh/pr119507.C: Skip for arm eabi.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/testsuite/g++.dg/eh/pr119507.C | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/testsuite/g++.dg/eh/pr119507.C 
b/gcc/testsuite/g++.dg/eh/pr119507.C
index 50afa75a43f8..c68536ff671b 100644
--- a/gcc/testsuite/g++.dg/eh/pr119507.C
+++ b/gcc/testsuite/g++.dg/eh/pr119507.C
@@ -1,4 +1,6 @@
 // { dg-do compile { target comdat_group } }
+// ARM EABI has its own exception handling data handling and does not use 
gcc_except_table
+// { dg-skip-if "!TARGET_EXCEPTION_DATA" { arm_eabi } }
 // Force off function sections
 // Force on exceptions
 // { dg-options "-fno-function-sections -fexceptions" }


[gcc r16-59] [riscv] vec_dup immediate constants in pred_broadcast expand [PR118182]

2025-04-21 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:14fa625bcb91028cb97f3575d2e394401bbb4a3a

commit r16-59-g14fa625bcb91028cb97f3575d2e394401bbb4a3a
Author: Alexandre Oliva 
Date:   Mon Apr 21 22:48:55 2025 -0300

[riscv] vec_dup immediate constants in pred_broadcast expand [PR118182]

pr118182-2.c fails on gcc-14 because it lacks the late_combine passes,
particularly the one that runs after register allocation.

Even in the trunk, the predicate broadcast for the add reduction is
expanded and register-allocated as _zvfh, taking up an unneeded scalar
register to hold the constant to be vec_duplicated.

It is the late combine pass after register allocation that substitutes
this unneeded scalar register into the vec_duplicate, resolving to the
_zero or _imm insns.

It's easy enough and more efficient to expand pred_broadcast to the
insns that take the already-duplicated vector constant, when the
operands satisfy the predicates of the _zero or _imm insns.


for  gcc/ChangeLog

PR target/118182
* config/riscv/vector.md (@pred_broadcast): Expand to
_zero and _imm variants without vec_duplicate.

Diff:
---
 gcc/config/riscv/vector.md | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 51eb64fb1226..3ab4d76e6c6a 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -2136,18 +2136,34 @@
 (match_operand 7 "const_int_operand")
 (reg:SI VL_REGNUM)
 (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (vec_duplicate:V_VLS
-   (match_operand: 3 "direct_broadcast_operand"))
+ ;; (vec_duplicate:V_VLS ;; wrapper activated by wrap_vec_dup below.
+ (match_operand: 3 "direct_broadcast_operand") ;; )
  (match_operand:V_VLS 2 "vector_merge_operand")))]
   "TARGET_VECTOR"
 {
   /* Transform vmv.v.x/vfmv.v.f (avl = 1) into vmv.s.x since vmv.s.x/vfmv.s.f
  has better chances to do vsetvl fusion in vsetvl pass.  */
+  bool wrap_vec_dup = true;
+  rtx vec_cst = NULL_RTX;
   if (riscv_vector::splat_to_scalar_move_p (operands))
 {
   operands[1] = riscv_vector::gen_scalar_move_mask (mode);
   operands[3] = force_reg (mode, operands[3]);
 }
+  else if (immediate_operand (operands[3], mode)
+  && (vec_cst = gen_const_vec_duplicate (mode, operands[3]))
+  && (/* -> pred_broadcast_zero */
+  (vector_least_significant_set_mask_operand (operands[1],
+  mode)
+   && vector_const_0_operand (vec_cst, mode))
+  || (/* pred_broadcast_imm */
+  vector_all_trues_mask_operand (operands[1], mode)
+  && vector_const_int_or_double_0_operand (vec_cst,
+   mode
+{
+  operands[3] = vec_cst;
+  wrap_vec_dup = false;
+}
   /* Handle vmv.s.x instruction (Wb1 mask) which has memory scalar.  */
   else if (satisfies_constraint_Wdm (operands[3]))
 {
@@ -2191,6 +2207,8 @@
 ;
   else
 operands[3] = force_reg (mode, operands[3]);
+  if (wrap_vec_dup)
+operands[3] = gen_rtx_VEC_DUPLICATE (mode, operands[3]);
 })
 
 (define_insn_and_split "*pred_broadcast"


[gcc r16-60] [testsuite] [ppc] require ifunc for target_clones test

2025-04-21 Thread Alexandre Oliva via Gcc-cvs
https://gcc.gnu.org/g:958312c6575620a5895fc914ff3c5bf9af7547c9

commit r16-60-g958312c6575620a5895fc914ff3c5bf9af7547c9
Author: Alexandre Oliva 
Date:   Mon Apr 21 22:48:57 2025 -0300

[testsuite] [ppc] require ifunc for target_clones test

gcc.target/powerpc/power11-3.c uses target_clones, that depends on
ifunc.  Require ifunc support.


for  gcc/testsuite/ChangeLog

* gcc.target/powerpc/power11-3.c: Require ifunc support.

Diff:
---
 gcc/testsuite/gcc.target/powerpc/power11-3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.target/powerpc/power11-3.c 
b/gcc/testsuite/gcc.target/powerpc/power11-3.c
index fa1aedd04299..56bf88185983 100644
--- a/gcc/testsuite/gcc.target/powerpc/power11-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/power11-3.c
@@ -1,5 +1,6 @@
 /* { dg-do compile }  */
 /* { dg-options "-mdejagnu-cpu=power8 -O2" }  */
+/* { dg-require-ifunc "" } */
 
 /* Check if we can set the power11 target via a target_clones attribute.  */


[gcc/devel/rust/master] rust: Use error_operand_p in rust-gcc.cc

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:4b64c35a8f6093eb3851f9149e2465117c392492

commit 4b64c35a8f6093eb3851f9149e2465117c392492
Author: Andrew Pinski 
Date:   Wed Mar 19 17:30:00 2025 -0700

rust: Use error_operand_p in rust-gcc.cc

Just a simple cleanupof the code to use error_operand_p
instead of directly comparing against error_mark_node.

This also moves some cdoe around when dealing with error_operand_p
just to be faster and/or slightly tighten up the code slightly.

gcc/rust/ChangeLog:

* rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
(pointer_type): Likewise.
(reference_type): Likewise.
(immutable_type): Likewise.
(function_type): Likewise.
(function_type_variadic): Likewise.
Cleanup the check for receiver.type first.
(function_ptr_type): Use error_operand_p.
(fill_in_fields): Likewise.
(fill_in_array): Likewise.
(named_type): Likewise.
(type_size): Likewise.
(type_alignment): Likewise.
(type_field_alignment): Likewise.
(type_field_offset): Likewise.
(zero_expression): Likewise.
(float_constant_expression): Likewise.
(convert_expression): Likewise.
(struct_field_expression): Likewise.
(compound_expression): Likewise.
(conditional_expression): Likewise.
(negation_expression): Likewise.
(arithmetic_or_logical_expression): Likewise.
(arithmetic_or_logical_expression_checked): Likewise.
(comparison_expression): Likewise.
(lazy_boolean_expression): Likewise.
(constructor_expression): Likewise.
(array_constructor_expression): Likewise.
(array_index_expression): Likewise.
(call_expression): Likewise.
(init_statement): Likewise.
(assignment_statement): Likewise.
(return_statement): Likewise.
(exception_handler_statement): Likewise.
(if_statement): Likewise.
(compound_statement): Likewise.
Tighten up the code, removing t variable.
(statement_list): Use error_operand_p.
(block): Likewise.
(block_add_statements): Likewise.
(convert_tree): Likewise.
(global_variable): Likewise.
(global_variable_set_init): Likewise.
(local_variable): Likewise.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
(function): Likewise. Tighten up the code.
(function_defer_statement): Use error_operand_p.
(function_set_parameters): Use error_operand_p.
(write_global_definitions): Use error_operand_p.
Tighten up the code around the loop.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/rust/rust-gcc.cc | 189 ---
 1 file changed, 88 insertions(+), 101 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index d2251dccdb82..7ab3ad479986 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
 tree
 Bvariable::get_tree (location_t location) const
 {
-  if (this->t_ == error_mark_node)
+  if (error_operand_p (this->t_))
 return error_mark_node;
 
   TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
 tree
 pointer_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_pointer_type (to_type);
   return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
 tree
 reference_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_reference_type (to_type);
   return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
 tree
 immutable_type (tree base)
 {
-  if (base == error_mark_node)
+  if (error_operand_p (base))
 return error_mark_node;
   tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
   return constified;
@@ -472,7 +472,7 @@ function_type (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 {
   tree t = receiver.type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -482,7 +482,7 @@ function_type (const typed_identifier &receiver,
p != parameters.end (); ++p)
 {
   tree t = p->type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -502,11 +502,11 @@ function_type (const typed_identifier &receiver,
   gcc_assert (result_struct != NULL)

[gcc/devel/rust/master] rust: Use FLOAT_TYPE_P instead of manual checking

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:2a46a5a37a7364951e0578605e2f763ba0a2cde4

commit 2a46a5a37a7364951e0578605e2f763ba0a2cde4
Author: Andrew Pinski 
Date:   Wed Mar 19 17:29:59 2025 -0700

rust: Use FLOAT_TYPE_P instead of manual checking

This moves is_floating_point over to using FLOAT_TYPE_P instead
of manually checking. Note before it would return true for all
COMPLEX_TYPE but complex types' inner type could be integral.

Also fixes up the comment to be in more of the GNU style.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/rust/ChangeLog:

* rust-gcc.cc (is_floating_point): Use FLOAT_TYPE_P
instead of manually checking the type.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/rust/rust-gcc.cc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 3b0cd5b9afcf..d2251dccdb82 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1021,12 +1021,12 @@ operator_to_tree_code (LazyBooleanOperator op)
 }
 }
 
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+   False otherwise.  */
 bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
 {
-  auto tree_type = TREE_CODE (TREE_TYPE (t));
-  return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+  return FLOAT_TYPE_P (TREE_TYPE (exp));
 }
 
 // Return an expression for the negation operation OP EXPR.


[gcc/devel/rust/master] rust: use range for inside rust-gcc.cc [PR119341]

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f20261115987df04a9e62dd9e857561fb1530c8e

commit f20261115987df04a9e62dd9e857561fb1530c8e
Author: Andrew Pinski 
Date:   Wed Mar 19 17:30:01 2025 -0700

rust: use range for inside rust-gcc.cc [PR119341]

There are some places inside rust-gcc.cc which are candidates
to use range for instead of iterators directly. This changes
the locations I saw and makes the code slightly more readable.

gcc/rust/ChangeLog:

PR rust/119341
* rust-gcc.cc (function_type): Use range fors.
(function_type_variadic): Likewise.
(fill_in_fields): Likewise.
(statement_list): Likewise.
(block): Likewise.
(block_add_statements): Likewise.
(function_set_parameters): Likewise.
(write_global_definitions): Likewise.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/rust/rust-gcc.cc | 57 +++-
 1 file changed, 21 insertions(+), 36 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 7ab3ad479986..85743c472cf5 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -478,10 +478,9 @@ function_type (const typed_identifier &receiver,
   pp = &TREE_CHAIN (*pp);
 }
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
@@ -527,10 +526,9 @@ function_type_variadic (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 args[offs++] = receiver.type;
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   args[offs++] = t;
@@ -609,14 +607,13 @@ fill_in_fields (tree fill, const 
std::vector &fields,
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
-  for (std::vector::const_iterator p = fields.begin ();
-   p != fields.end (); ++p)
+  for (const auto &p : fields)
 {
-  tree name_tree = get_identifier_from_string (p->name);
-  tree type_tree = p->type;
+  tree name_tree = get_identifier_from_string (p.name);
+  tree type_tree = p.type;
   if (error_operand_p (type_tree))
return error_mark_node;
-  tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+  tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
   DECL_CONTEXT (field) = fill;
   *pp = field;
   pp = &DECL_CHAIN (field);
@@ -1741,10 +1738,8 @@ tree
 statement_list (const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree t : statements)
 {
-  tree t = (*p);
   if (error_operand_p (t))
return error_mark_node;
   append_to_statement_list (t, &stmt_list);
@@ -1798,10 +1793,9 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
 }
 
   tree *pp = &BLOCK_VARS (block_tree);
-  for (std::vector::const_iterator pv = vars.begin ();
-   pv != vars.end (); ++pv)
+  for (Bvariable *bv : vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
 }
@@ -1821,10 +1815,8 @@ void
 block_add_statements (tree bind_tree, const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree s : statements)
 {
-  tree s = (*p);
   if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
 }
@@ -2268,10 +2260,9 @@ function_set_parameters (tree function,
 
   tree params = NULL_TREE;
   tree *pp = ¶ms;
-  for (std::vector::const_iterator pv = param_vars.begin ();
-   pv != param_vars.end (); ++pv)
+  for (Bvariable *bv : param_vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   gcc_assert (!error_operand_p (*pp));
   pp = &DECL_CHAIN (*pp);
 }
@@ -2297,10 +2288,9 @@ write_global_definitions (const std::vector 
&type_decls,
 
   // Convert all non-erroneous declarations into Gimple form.
   size_t i = 0;
-  for (std::vector::const_iterator p = variable_decls.begin ();
-   p != variable_decls.end (); ++p)
+  for (Bvariable *bv : variable_decls)
 {
-  tree v = (*p)->get_decl ();
+  tree v = bv->get_decl ();
   if (error_operand_p (v))
continue;
   defs[i] = v;
@@ -2308,10 +2298,8 @@ write_global_definitions (const std::vector 
&type_decls,
   ++i;
 }
 
-  for (std::vector::const_iterator p = type_decls.begin ();
-   p != typ

[gcc/devel/rust/master] typecheck: Properly select methods when dealing with specialization

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:b9fdd60c28472f8163f7952bee2473e1d8e6981e

commit b9fdd60c28472f8163f7952bee2473e1d8e6981e
Author: Arthur Cohen 
Date:   Thu Apr 3 16:22:10 2025 +0200

typecheck: Properly select methods when dealing with specialization

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (is_default_fn): New.
(emit_ambiguous_resolution_error): New.
(handle_multiple_candidates): Properly handle multiple candidates in
the case of specialization.
(TypeCheckExpr::visit): Call `handle_multiple_candidates`.

gcc/testsuite/ChangeLog:

* rust/execute/torture/min_specialization2.rs: New test.
* rust/execute/torture/min_specialization3.rs: New test.

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc | 129 +
 .../rust/execute/torture/min_specialization2.rs|  31 +
 .../rust/execute/torture/min_specialization3.rs|  36 ++
 3 files changed, 172 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 00e36ee48a26..d01e4f8b60d6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "optional.h"
+#include "rust-hir-expr.h"
 #include "rust-system.h"
 #include "rust-tyty-call.h"
 #include "rust-hir-type-check-struct-field.h"
@@ -1154,6 +1156,94 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
   infered = lookup->get_field_type ();
 }
 
+bool
+is_default_fn (const MethodCandidate &candidate)
+{
+  if (candidate.candidate.is_impl_candidate ())
+{
+  auto *item = candidate.candidate.item.impl.impl_item;
+
+  if (item->get_impl_item_type () == HIR::ImplItem::FUNCTION)
+   {
+ auto &fn = static_cast (*item);
+
+ return fn.is_default ();
+   }
+}
+
+  return false;
+}
+
+void
+emit_ambiguous_resolution_error (HIR::MethodCallExpr &expr,
+std::set &candidates)
+{
+  rich_location r (line_table, expr.get_method_name ().get_locus ());
+  std::string rich_msg = "multiple "
++ expr.get_method_name ().get_segment ().as_string ()
++ " found";
+
+  // We have to filter out default candidates
+  for (auto &c : candidates)
+if (!is_default_fn (c))
+  r.add_range (c.candidate.locus);
+
+  r.add_fixit_replace (rich_msg.c_str ());
+
+  rust_error_at (r, ErrorCode::E0592, "duplicate definitions with name %qs",
+expr.get_method_name ().get_segment ().as_string ().c_str ());
+}
+
+// We are allowed to have multiple candidates if they are all specializable
+// functions or if all of them except one are specializable functions.
+// In the later case, we just return a valid candidate without erroring out
+// about ambiguity. If there are two or more specialized functions, then we
+// error out.
+//
+// FIXME: The first case is not handled at the moment, so we error out
+tl::optional
+handle_multiple_candidates (HIR::MethodCallExpr &expr,
+   std::set &candidates)
+{
+  auto all_default = true;
+  tl::optional found = tl::nullopt;
+
+  for (auto &c : candidates)
+{
+  if (!is_default_fn (c))
+   {
+ all_default = false;
+
+ // We haven't found a final candidate yet, so we can select
+ // this one. However, if we already have a candidate, then
+ // that means there are multiple non-default candidates - we
+ // must error out
+ if (!found)
+   {
+ found = c;
+   }
+ else
+   {
+ emit_ambiguous_resolution_error (expr, candidates);
+ return tl::nullopt;
+   }
+   }
+}
+
+  // None of the candidates were a non-default (specialized) function, so we
+  // error out
+  if (all_default)
+{
+  rust_sorry_at (expr.get_locus (),
+"cannot resolve method calls to non-specialized methods "
+"(all function candidates are %qs)",
+"default");
+  return tl::nullopt;
+}
+
+  return found;
+}
+
 void
 TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
 {
@@ -1181,34 +1271,25 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   return;
 }
 
-  if (candidates.size () > 1)
-{
-  rich_location r (line_table, expr.get_method_name ().get_locus ());
-  std::string rich_msg
-   = "multiple " + expr.get_method_name ().get_segment ().as_string ()
- + " found";
+  tl::optional candidate = *candidates.begin ();
 
-  for (auto &c : candidates)
-   r.add_range (c.candidate.locus);
+  if (candidates.size () > 1)
+candidate = handle_multiple_candidates (expr, candidates);
 
-  r.add_fixit_replace (rich_msg.c_str ());
+ 

[gcc/devel/rust/master] session: Desugar question mark operator after expansion instead.

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:688b8d8b0e24aa7e2a7f741355d696f60337f956

commit 688b8d8b0e24aa7e2a7f741355d696f60337f956
Author: Arthur Cohen 
Date:   Fri Apr 4 14:21:00 2025 +0200

session: Desugar question mark operator after expansion instead.

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Call the 
visitor later in the pipeline.

Diff:
---
 gcc/rust/rust-session-manager.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index cbdc8ba0f51f..5563d103ff5e 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -611,7 +611,6 @@ Session::compile_crate (const char *filename)
 return;
 
   AST::CollectLangItems ().go (parsed_crate);
-  AST::DesugarQuestionMark ().go (parsed_crate);
 
   auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
   // expansion pipeline stage
@@ -619,6 +618,7 @@ Session::compile_crate (const char *filename)
   expansion (parsed_crate, name_resolution_ctx);
 
   AST::DesugarForLoops ().go (parsed_crate);
+  AST::DesugarQuestionMark ().go (parsed_crate);
 
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
   if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))


[gcc/devel/rust/master] expansion: Desugar doc comments into attributes before expansion

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:486ca997e9924ad52bee8e4c4a6028fcab5f25b5

commit 486ca997e9924ad52bee8e4c4a6028fcab5f25b5
Author: Arthur Cohen 
Date:   Tue Apr 8 16:20:18 2025 +0200

expansion: Desugar doc comments into attributes before expansion

gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc (MacroExpander::expand_decl_macro): 
Call into
TokenTreeDesugar.
* expand/rust-token-tree-desugar.cc: New file.
* expand/rust-token-tree-desugar.h: New file.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro-issue3709-1.rs: New test.
* rust/compile/macros/mbe/macro-issue3709-2.rs: New test.

Diff:
---
 gcc/rust/Make-lang.in  |  1 +
 gcc/rust/expand/rust-macro-expand.cc   |  6 +-
 gcc/rust/expand/rust-token-tree-desugar.cc | 72 +++
 gcc/rust/expand/rust-token-tree-desugar.h  | 55 +++
 .../rust/compile/macros/mbe/macro-issue3693.rs | 10 +++
 .../rust/compile/macros/mbe/macro-issue3709-1.rs   | 10 +++
 .../rust/compile/macros/mbe/macro-issue3709-2.rs   | 81 ++
 7 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index c024f241b5d3..5ae50d23f8f7 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -115,6 +115,7 @@ GRS_OBJS = \
 rust/rust-macro-builtins-format-args.o \
 rust/rust-macro-builtins-location.o \
 rust/rust-macro-builtins-include.o \
+rust/rust-token-tree-desugar.o \
rust/rust-fmt.o \
 rust/rust-hir.o \
 rust/rust-hir-map.o \
diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index c22db1c8aeb6..e7407a495517 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -28,6 +28,7 @@
 #include "rust-cfg-strip.h"
 #include "rust-early-name-resolver.h"
 #include "rust-proc-macro.h"
+#include "rust-token-tree-desugar.h"
 
 namespace Rust {
 
@@ -78,7 +79,10 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
* trees.
*/
 
-  AST::DelimTokenTree &invoc_token_tree = invoc.get_delim_tok_tree ();
+  AST::DelimTokenTree &invoc_token_tree_sugar = invoc.get_delim_tok_tree ();
+
+  // We must first desugar doc comments into proper attributes
+  auto invoc_token_tree = AST::TokenTreeDesugar ().go (invoc_token_tree_sugar);
 
   // find matching arm
   AST::MacroRule *matched_rule = nullptr;
diff --git a/gcc/rust/expand/rust-token-tree-desugar.cc 
b/gcc/rust/expand/rust-token-tree-desugar.cc
new file mode 100644
index ..3b471805924a
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.cc
@@ -0,0 +1,72 @@
+// 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-token-tree-desugar.h"
+#include "rust-ast.h"
+#include "rust-token.h"
+
+namespace Rust {
+namespace AST {
+
+DelimTokenTree
+TokenTreeDesugar::go (DelimTokenTree &tts)
+{
+  tts.accept_vis (*this);
+
+  return DelimTokenTree (tts.get_delim_type (), std::move (desugared),
+tts.get_locus ());
+}
+
+void
+TokenTreeDesugar::append (TokenPtr &&new_token)
+{
+  desugared.emplace_back (std::make_unique (std::move (new_token)));
+}
+
+void
+TokenTreeDesugar::append (std::unique_ptr &&new_token)
+{
+  desugared.emplace_back (std::move (new_token));
+}
+
+void
+TokenTreeDesugar::visit (Token &tts)
+{
+  if (tts.get_id () == TokenId::OUTER_DOC_COMMENT
+  || tts.get_id () == TokenId::INNER_DOC_COMMENT)
+{
+  append (Rust::Token::make (TokenId::HASH, tts.get_locus ()));
+
+  if (tts.get_id () == TokenId::INNER_DOC_COMMENT)
+   append (Rust::Token::make (EXCLAM, tts.get_locus ()));
+
+  append (Rust::Token::make (TokenId::LEFT_SQUARE, tts.get_locus ()));
+  append (Rust::Token::make_identifier (tts.get_locus (), "doc"));
+  append (Rust::Token::make (TokenId::EQUAL, tts.get_locus ()));
+  append (Rust::Token::make_string (tts.get_locus (),
+   std::string (tts.get_str (;
+  append (Rust::Token::make (TokenId::RIGHT_SQUARE, tts.get_locus ()));
+}
+  else
+{
+  append (tts.clone_token ());
+}
+}
+
+}; // namespace AST
+}; // namespace 

[gcc/devel/rust/master] format_args: Allow extraneous commas, improve safety

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:0c6c73c5317111c5ec9cf465b3f6e37fe250a449

commit 0c6c73c5317111c5ec9cf465b3f6e37fe250a449
Author: Arthur Cohen 
Date:   Wed Apr 9 14:42:08 2025 +0200

format_args: Allow extraneous commas, improve safety

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-format-args.cc 
(format_args_parse_arguments): Improve safety,
allow extra commas after end of argument list.

gcc/testsuite/ChangeLog:

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

Diff:
---
 gcc/rust/expand/rust-macro-builtins-format-args.cc |  7 
 .../rust/compile/format_args_extra_comma.rs| 47 ++
 2 files changed, 54 insertions(+)

diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc 
b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index 3015225f47ce..bb01eba9873b 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -55,6 +55,8 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
   if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
 format_expr = parser.parse_literal_expr ();
 
+  rust_assert (format_expr);
+
   // TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
   // macro invocation, what do we do here? return a tl::unexpected?
   auto format_str = static_cast (*format_expr)
@@ -81,6 +83,11 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
 {
   parser.skip_token (COMMA);
 
+  // Check in case of an extraneous comma in the args list, which is
+  // allowed - format_args!("fmt", arg, arg2,)
+  if (parser.peek_current_token ()->get_id () == last_token_id)
+   break;
+
   if (parser.peek_current_token ()->get_id () == IDENTIFIER
  && parser.peek (1)->get_id () == EQUAL)
{
diff --git a/gcc/testsuite/rust/compile/format_args_extra_comma.rs 
b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
new file mode 100644
index ..fcc435c074c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
@@ -0,0 +1,47 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+() => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+pub mod fmt {
+pub struct Formatter;
+pub struct Result;
+
+pub struct Arguments<'a>;
+
+impl<'a> Arguments<'a> {
+pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> 
Arguments<'a> {
+Arguments
+}
+}
+
+pub struct ArgumentV1<'a>;
+
+impl<'a> ArgumentV1<'a> {
+pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) 
-> ArgumentV1 {
+ArgumentV1
+}
+}
+
+pub trait Display {
+fn fmt(&self, _: &mut Formatter) -> Result;
+}
+
+impl Display for i32 {
+fn fmt(&self, _: &mut Formatter) -> Result {
+// { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+Result
+}
+}
+}
+}
+
+fn main() {
+let _formatted = format_args!("extra commas {} {}", 15, 14,);
+}


[gcc/devel/rust/master] Fix const checking of enum discriminants

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f8c661350e1591ce430c4b8e1c5fe33e32230aba

commit f8c661350e1591ce430c4b8e1c5fe33e32230aba
Author: Owen Avery 
Date:   Sat Apr 5 17:20:44 2025 -0400

Fix const checking of enum discriminants

gcc/rust/ChangeLog:

* checks/errors/rust-const-checker.cc
(ConstChecker::visit): Visit the enum items of enums.
* resolve/rust-ast-resolve-item.cc
(ResolveItem::visit): Resolve enum discriminants during nr1.0.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/checks/errors/rust-const-checker.cc | 3 +++
 gcc/rust/resolve/rust-ast-resolve-item.cc| 2 ++
 gcc/testsuite/rust/compile/enum_discriminant2.rs | 9 +
 3 files changed, 14 insertions(+)

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 80b63982c12d..81594c00beb4 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -646,6 +646,9 @@ ConstChecker::visit (Enum &enum_item)
 {
   check_default_const_generics (enum_item.get_generic_params (),
ConstGenericCtx::Enum);
+
+  for (auto &item : enum_item.get_variants ())
+item->accept_vis (*this);
 }
 
 void
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 89cf0f3c07e3..fc226cf28c0a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -356,6 +356,8 @@ ResolveItem::visit (AST::EnumItemDiscriminant &item)
   auto cpath = canonical_prefix.append (decl);
 
   mappings.insert_canonical_path (item.get_node_id (), cpath);
+
+  ResolveExpr::go (item.get_expr (), path, cpath);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/enum_discriminant2.rs 
b/gcc/testsuite/rust/compile/enum_discriminant2.rs
new file mode 100644
index ..351dfbb6f85d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant2.rs
@@ -0,0 +1,9 @@
+fn test() -> isize {
+1
+}
+
+enum Foo {
+Bar = test() // { dg-error "only functions marked as .const." }
+}
+
+fn main() {}


[gcc/devel/rust/master] ast: Support outer attributes for AST::RangeExpr

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:4d09dd4abab3b0f4b9ceeaf434001ae2b41eb7e0

commit 4d09dd4abab3b0f4b9ceeaf434001ae2b41eb7e0
Author: Arthur Cohen 
Date:   Wed Apr 9 14:44:56 2025 +0200

ast: Support outer attributes for AST::RangeExpr

gcc/rust/ChangeLog:

* ast/rust-expr.h (class RangeExpr): Add empty outer attributes and 
allow getting them
and setting them.

Diff:
---
 gcc/rust/ast/rust-expr.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 84cdfdb46780..69538df63e5c 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -3004,6 +3004,10 @@ class RangeExpr : public ExprWithoutBlock
 {
   location_t locus;
 
+  // Some visitors still check for attributes on RangeExprs, and they will need
+  // to be supported in the future - so keep that for now
+  std::vector empty_attributes = {};
+
 protected:
   // outer attributes not allowed before range expressions
   RangeExpr (location_t locus) : locus (locus) {}
@@ -3013,15 +3017,11 @@ public:
 
   std::vector &get_outer_attrs () override final
   {
-// RangeExpr cannot have any outer attributes
-rust_assert (false);
+return empty_attributes;
   }
 
   // should never be called - error if called
-  void set_outer_attrs (std::vector /* new_attrs */) override
-  {
-rust_assert (false);
-  }
+  void set_outer_attrs (std::vector /* new_attrs */) override {}
 
   Expr::Kind get_expr_kind () const override { return Expr::Kind::Range; }
 };


[gcc/devel/rust/master] ast: Add get_locus() to DelimTokenTree

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:64d4e0f1e587d167f7734acad8dbf48be1e33fa3

commit 64d4e0f1e587d167f7734acad8dbf48be1e33fa3
Author: Arthur Cohen 
Date:   Wed Apr 9 14:44:11 2025 +0200

ast: Add get_locus() to DelimTokenTree

gcc/rust/ChangeLog:

* ast/rust-ast.h (DelimTokenTree::get_locus): New function.

Diff:
---
 gcc/rust/ast/rust-ast.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 71facfff2671..3f41034a7317 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1018,6 +1018,7 @@ public:
   }
 
   DelimType get_delim_type () const { return delim_type; }
+  location_t get_locus () const { return locus; }
 };
 
 /* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr


[gcc/devel/rust/master] rust: Add comment inside block [PR119342]

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:7ef77dad7cdd8d4b2b558a190b03a4e39557feab

commit 7ef77dad7cdd8d4b2b558a190b03a4e39557feab
Author: Andrew Pinski 
Date:   Wed Mar 19 17:30:02 2025 -0700

rust: Add comment inside block [PR119342]

Inside a BLOCK node, all of the variables of the scope/block
are chained together and that connects them to the block.
This just adds a comment to that effect as reading the code
it is not so obvious why they need to be chained together.

gcc/rust/ChangeLog:

PR rust/119342
* rust-gcc.cc (block): Add comment on why chaining
the variables of the scope toether.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/rust/rust-gcc.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 85743c472cf5..524cee71a6e8 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1792,6 +1792,8 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
   *pp = block_tree;
 }
 
+  // Chain the variables of the scope together so they are all connected
+  // to the block.
   tree *pp = &BLOCK_VARS (block_tree);
   for (Bvariable *bv : vars)
 {


[gcc/devel/rust/master] nr2.0: Do not resolve modules this run if they are unloaded

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:fd6257bc2894124c328757ff08221580f6ea105b

commit fd6257bc2894124c328757ff08221580f6ea105b
Author: Arthur Cohen 
Date:   Fri Apr 4 14:18:33 2025 +0200

nr2.0: Do not resolve modules this run if they are unloaded

Instead, mark the visitor as dirty and wait for the next round of the fixed 
point to take care of
them. This avoids issues with module items being loaded while not being 
stripped yet.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): 
Return if module
is unloaded.

Diff:
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 2c0cc660601b..e276d65323e3 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -113,7 +113,17 @@ TopLevel::visit (AST::Module &module)
   // This was copied from the old early resolver method
   // 'accumulate_escaped_macros'
   if (module.get_kind () == AST::Module::UNLOADED)
-module.load_items ();
+{
+  module.load_items ();
+
+  // If the module was previously unloaded, then we don't want to visit it
+  // this time around as the CfgStrip hasn't run on its inner items yet.
+  // Skip it for now, mark the visitor as dirty and try again
+
+  dirty = true;
+
+  return;
+}
 
   DefaultResolver::visit (module);


[gcc/devel/rust/master] gccrs: Fix segv in unsafe chcker

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:5ac41dce35b947f5d1f904b39958ebf6f1b538cf

commit 5ac41dce35b947f5d1f904b39958ebf6f1b538cf
Author: Philip Herron 
Date:   Fri Apr 4 16:35:13 2025 +0100

gccrs: Fix segv in unsafe chcker

Trait constants were missing type resolution step, this adds that
as if it was a normal constant. The unsafe checker was missing a
null check.

Fixes Rust-GCC#3612

gcc/rust/ChangeLog:

* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): add 
null check
* hir/tree/rust-hir-item.h: add has_type helper
* typecheck/rust-hir-trait-resolve.cc 
(TraitItemReference::resolve_item):
add missing type checking

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 

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

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


[gcc/devel/rust/master] Add `#[track_caller]` as known attribute

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:ecb649973a3b176f6a723c2f3d78c23ee121163d

commit ecb649973a3b176f6a723c2f3d78c23ee121163d
Author: beamandala 
Date:   Thu Mar 20 17:34:48 2025 -0500

Add `#[track_caller]` as known attribute

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc 
(MacroBuiltin::builtin_transcribers):
Add entry for track_caller.
* util/rust-attribute-values.h: add `TRACK_CALLER` attribute.
* util/rust-attributes.cc: add `track_caller` attribute definition.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Bhavesh Mandalapu 

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 1 +
 gcc/rust/util/rust-attribute-values.h  | 1 +
 gcc/rust/util/rust-attributes.cc   | 3 ++-
 gcc/testsuite/rust/compile/track_caller.rs | 6 ++
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 1231e9fbb703..d5b6dec4a71f 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -137,6 +137,7 @@ std::unordered_map
 {"cfg_accessible", MacroBuiltin::sorry},
 {"rustc_const_stable", MacroBuiltin::sorry},
 {"rustc_const_unstable", MacroBuiltin::sorry},
+{"track_caller", MacroBuiltin::sorry},
 /* Derive builtins do not need a real transcriber, but still need one. It
should however never be called since builtin derive macros get expanded
differently, and benefit from knowing on what kind of items they are
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 75dc9e141109..409f6fb7ccb6 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -58,6 +58,7 @@ public:
   static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
   static constexpr auto &MAY_DANGLE = "may_dangle";
   static constexpr auto &PRELUDE_IMPORT = "prelude_import";
+  static constexpr auto &TRACK_CALLER = "track_caller";
 };
 } // namespace Values
 } // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 079e17793db6..28d99f1d0a05 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -75,7 +75,8 @@ static const BuiltinAttrDefinition __definitions[]
  // assuming we keep these for static analysis
  {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
  {Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
- {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}};
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+ {Attrs::TRACK_CALLER, CODE_GENERATION}};
 
 BuiltinAttributeMappings *
 BuiltinAttributeMappings::get ()
diff --git a/gcc/testsuite/rust/compile/track_caller.rs 
b/gcc/testsuite/rust/compile/track_caller.rs
new file mode 100644
index ..fd1d84295887
--- /dev/null
+++ b/gcc/testsuite/rust/compile/track_caller.rs
@@ -0,0 +1,6 @@
+#[track_caller]
+fn foo() {}
+
+fn main() {
+foo();
+}


[gcc/devel/rust/master] install.texi: Mention Rust requirement for building gccrs

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:8934acdd481febd8978f05bd262dabc4e68587b6

commit 8934acdd481febd8978f05bd262dabc4e68587b6
Author: Arthur Cohen 
Date:   Tue Apr 1 13:00:56 2025 +0200

install.texi: Mention Rust requirement for building gccrs

Addresses PR#117869

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117869

gcc/ChangeLog:

* doc/install.texi: Add requirements for building gccrs.

Diff:
---
 gcc/doc/install.texi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index d8414fdbdc94..c6ef78e9491e 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -312,6 +312,12 @@ documentation including the target @code{SYSTEM} 
definition module.
 If Python3 is unavailable Modula-2 documentation will include a target
 independent version of the SYSTEM modules.
 
+@item @anchor{gccrs-prerequisite}gccrs
+
+The official Rust compiler and Rust build system (cargo) are required for
+building various parts of the gccrs frontend, until gccrs can compile them
+by itself. The minimum supported Rust version is 1.49.
+
 @item A ``working'' POSIX compatible shell, or GNU bash
 
 Necessary when running @command{configure} because some


[gcc/devel/rust/master] ci: Update warnings for new location in install.texi

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:a283cdcf85e2f4bafe9d02ee6117bf46fcbb5a82

commit a283cdcf85e2f4bafe9d02ee6117bf46fcbb5a82
Author: Arthur Cohen 
Date:   Mon Apr 14 10:58:25 2025 +0200

ci: Update warnings for new location in install.texi

ChangeLog:

* .github/glibcxx_ubuntu64b_log_expected_warnings: Change line 
number
for warning from 2230 to 2236.
* .github/log_expected_warnings: Likewise.

Diff:
---
 .github/glibcxx_ubuntu64b_log_expected_warnings | 2 +-
 .github/log_expected_warnings   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/glibcxx_ubuntu64b_log_expected_warnings 
b/.github/glibcxx_ubuntu64b_log_expected_warnings
index 214a64aadcae..2aec0ddaff0c 100644
--- a/.github/glibcxx_ubuntu64b_log_expected_warnings
+++ b/.github/glibcxx_ubuntu64b_log_expected_warnings
@@ -128,5 +128,5 @@ gengtype-lex.cc:357:15: warning: this statement may fall 
through [-Wimplicit-fal
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
-install.texi:2230: warning: `.' or `,' must follow @xref, not f
+install.texi:2236: warning: `.' or `,' must follow @xref, not f
 libtool: install: warning: remember to run `libtool --finish 
/usr/local/libexec/gcc/x86_64-pc-linux-gnu/14.0.1'
diff --git a/.github/log_expected_warnings b/.github/log_expected_warnings
index 9829eb2709cf..731fcaa556ea 100644
--- a/.github/log_expected_warnings
+++ b/.github/log_expected_warnings
@@ -150,5 +150,5 @@ gengtype-lex.cc:357:15: warning: this statement may fall 
through [-Wimplicit-fal
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
 gengtype-lex.cc:357:15: warning: this statement may fall through 
[-Wimplicit-fallthrough=]
-install.texi:2230: warning: `.' or `,' must follow @xref, not f
+install.texi:2236: warning: `.' or `,' must follow @xref, not f
 libtool: install: warning: remember to run `libtool --finish 
/usr/local/libexec/gcc/x86_64-pc-linux-gnu/14.0.1'


[gcc/devel/rust/master] gccrs: Implement typecheck for zero-variant enums

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:2c109a2e8a97980b293edb7dc3609556473c7f3d

commit 2c109a2e8a97980b293edb7dc3609556473c7f3d
Author: Zhi Heng 
Date:   Thu Apr 3 20:23:46 2025 +0800

gccrs: Implement typecheck for zero-variant enums

gcc/rust/ChangeLog:

* typecheck/rust-tyty.h: Add new `ReprKind` enum to
`ReprOptions`.
* typecheck/rust-hir-type-check-base.cc: Handle setting of
`repr_kind`.
* typecheck/rust-hir-type-check-item.cc: New check for
zero-variant enums.

Signed-off-by: Yap Zhi Heng 

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

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

[gcc/devel/rust/master] attributes: Add missing attributes used in `core`

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:43b413664f9a482eb9cb44d2842d613c2a0a4b69

commit 43b413664f9a482eb9cb44d2842d613c2a0a4b69
Author: Arthur Cohen 
Date:   Fri Apr 4 14:20:04 2025 +0200

attributes: Add missing attributes used in `core`

gcc/rust/ChangeLog:

* util/rust-attribute-values.h: Add missing attributes.
* util/rust-attributes.cc: Likewise.
* util/rust-attributes.h (enum CompilerPass): Mention adding 
something for const
functions.

Diff:
---
 gcc/rust/util/rust-attribute-values.h | 24 
 gcc/rust/util/rust-attributes.cc  | 20 +++-
 gcc/rust/util/rust-attributes.h   |  2 ++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 409f6fb7ccb6..1d69b7af239b 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -40,12 +40,14 @@ public:
   static constexpr auto &NO_MANGLE = "no_mangle";
   static constexpr auto &REPR = "repr";
   static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro";
+  static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency";
   static constexpr auto &PATH = "path";
   static constexpr auto &MACRO_USE = "macro_use";
   static constexpr auto &MACRO_EXPORT = "macro_export";
   static constexpr auto &PROC_MACRO = "proc_macro";
   static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
   static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
+
   static constexpr auto &TARGET_FEATURE = "target_feature";
   // From now on, these are reserved by the compiler and gated through
   // #![feature(rustc_attrs)]
@@ -54,11 +56,33 @@ public:
 = "rustc_inherit_overflow_checks";
   static constexpr auto &STABLE = "stable";
   static constexpr auto &UNSTABLE = "unstable";
+
+  static constexpr auto &RUSTC_PROMOTABLE = "rustc_promotable";
   static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable";
   static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
+
+  static constexpr auto &RUSTC_SPECIALIZATION_TRAIT
+= "rustc_specialization_trait";
+  static constexpr auto &RUSTC_UNSAFE_SPECIALIZATION_MARKER
+= "rustc_unsafe_specialization_marker";
+  static constexpr auto &RUSTC_RESERVATION_IMPL = "rustc_reservation_impl";
+  static constexpr auto &RUSTC_PAREN_SUGAR = "rustc_paren_sugar";
+  static constexpr auto &RUSTC_NONNULL_OPTIMIZATION_GUARANTEED
+= "rustc_nonnull_optimization_guaranteed";
+
+  static constexpr auto &RUSTC_LAYOUT_SCALAR_VALID_RANGE_START
+= "rustc_layout_scalar_valid_range_start";
+
   static constexpr auto &MAY_DANGLE = "may_dangle";
   static constexpr auto &PRELUDE_IMPORT = "prelude_import";
   static constexpr auto &TRACK_CALLER = "track_caller";
+
+  static constexpr auto &RUSTC_DIAGNOSTIC_ITEM = "rustc_diagnostic_item";
+  static constexpr auto &RUSTC_ON_UNIMPLEMENTED = "rustc_on_unimplemented";
+
+  static constexpr auto &FUNDAMENTAL = "fundamental";
+
+  static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive";
 };
 } // namespace Values
 } // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 28d99f1d0a05..0442ff1d5258 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -57,6 +57,7 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::NO_MANGLE, CODE_GENERATION},
  {Attrs::REPR, CODE_GENERATION},
  {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
+ {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
  {Attrs::PATH, EXPANSION},
  {Attrs::MACRO_USE, NAME_RESOLUTION},
  {Attrs::MACRO_EXPORT, NAME_RESOLUTION},
@@ -72,11 +73,28 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
  {Attrs::STABLE, STATIC_ANALYSIS},
  {Attrs::UNSTABLE, STATIC_ANALYSIS},
+
  // assuming we keep these for static analysis
+ {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
  {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
  {Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
  {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
- {Attrs::TRACK_CALLER, CODE_GENERATION}};
+ {Attrs::TRACK_CALLER, CODE_GENERATION},
+ {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
+ {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
+ {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
+ {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
+ {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
+
+ {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
+
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+
+ {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
+ {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
+
+ {Attrs::FUNDAMENTAL, TYPE_CHECK},
+ {Attrs::NON_EXHAUSTIVE, TYPE_CHECK}};
 
 BuiltinAttributeMappings *
 BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/ut

[gcc/devel/rust/master] expansion: Only add fragments if the matcher succeeded

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:780ebba8a9152598e0fde0528c2fc63d9f474fcd

commit 780ebba8a9152598e0fde0528c2fc63d9f474fcd
Author: Arthur Cohen 
Date:   Tue Apr 8 14:41:16 2025 +0200

expansion: Only add fragments if the matcher succeeded

gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc (MacroExpander::match_n_matches): Do 
not
insert fragments and substack fragments if the matcher failed.

gcc/testsuite/ChangeLog:

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

Diff:
---
 gcc/rust/expand/rust-macro-expand.cc   | 15 ++--
 .../rust/compile/macros/mbe/macro-issue3708.rs | 80 ++
 2 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index 78297570791b..c22db1c8aeb6 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -621,9 +621,10 @@ MacroExpander::match_n_matches (Parser 
&parser,
// matched fragment get the offset in the token stream
size_t offs_end = source.get_offs ();
 
-   sub_stack.insert_metavar (
- MatchedFragment (fragment->get_ident ().as_string (),
-  offs_begin, offs_end));
+   if (valid_current_match)
+ sub_stack.insert_metavar (
+   MatchedFragment (fragment->get_ident ().as_string (),
+offs_begin, offs_end));
  }
  break;
 
@@ -650,15 +651,15 @@ MacroExpander::match_n_matches (Parser 
&parser,
}
   auto old_stack = sub_stack.pop ();
 
-  // nest metavars into repetitions
-  for (auto &ent : old_stack)
-   sub_stack.append_fragment (ent.first, std::move (ent.second));
-
   // If we've encountered an error once, stop trying to match more
   // repetitions
   if (!valid_current_match)
break;
 
+  // nest metavars into repetitions
+  for (auto &ent : old_stack)
+   sub_stack.append_fragment (ent.first, std::move (ent.second));
+
   match_amount++;
 
   // Break early if we notice there's too many expressions already
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
new file mode 100644
index ..e5b38bb0da7e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
@@ -0,0 +1,80 @@
+// { dg-additional-options "-frust-name-resolution-2.0 
-frust-compile-until=lowering" }
+
+macro_rules! impl_fn_for_zst {
+($(
+$( #[$attr: meta] )*
+struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+$body: block;
+)+) => {
+$(
+$( #[$attr] )*
+struct $Name;
+
+impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+#[inline]
+extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, 
)*)) -> $ReturnTy {
+$body
+}
+}
+
+impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+#[inline]
+extern "rust-call" fn call_mut(
+&mut self,
+($( $arg, )*): ($( $ArgTy, )*)
+) -> $ReturnTy {
+Fn::call(&*self, ($( $arg, )*))
+}
+}
+
+impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+type Output = $ReturnTy;
+
+#[inline]
+extern "rust-call" fn call_once(self, ($( $arg, )*): ($( 
$ArgTy, )*)) -> $ReturnTy {
+Fn::call(&self, ($( $arg, )*))
+}
+}
+)+
+}
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "fn"]
+pub trait Fn: FnMut {
+/// Performs the call operation.
+#[unstable(feature = "fn_traits", issue = "29625")]
+extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut: FnOnce {
+/// Performs the call operation.
+#[unstable(feature = "fn_traits", issue = "29625")]
+extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce {
+/// The returned type after the call operator is used.
+#[lang = "fn_once_output"]
+#[stable(feature = "fn_once_output", since = "1.12.0")]
+type Output;
+
+/// Performs the call operation.
+#[unstable(feature = "fn_traits", issue = "29625")]
+extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+impl_fn_for_zst! {
+#[derive(Copy)]
+struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () {
+};
+}


[gcc/devel/rust/master] Parse and lower llvm asm node

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:3e8955884cd816e43a52a0dda31399c01d2d8761

commit 3e8955884cd816e43a52a0dda31399c01d2d8761
Author: Pierre-Emmanuel Patry 
Date:   Tue Apr 15 11:38:29 2025 +0200

Parse and lower llvm asm node

Add a new HIR LlvmInlineAsm HIR node as well as some structures to
represent it's options and operands. Lower AST::LlvmInlineAsm node to it
and then create a tree from that node.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Remove 
unreachable
code.
* ast/rust-expr.h (struct LlvmOperand): Add LlvmOperand struct to
represent input and outputs.
(class LlvmInlineAsm): Add input, output and clobber operands.
(struct TupleTemplateStr): Add locus getter.
* backend/rust-compile-block.h: Add visit for LlvmInlineAsm.
* backend/rust-compile-expr.cc (CompileExpr::visit): Add llvm inline
asm stmt compilation.
* backend/rust-compile-expr.h: Add function prototype.
* backend/rust-compile-asm.h (class CompileLlvmAsm): Add llvm asm 
hir
not to gimple.
* backend/rust-compile-asm.cc (CompileLlvmAsm::CompileLlvmAsm): Add
constructor.
(CompileLlvmAsm::construct_operands): Add function to construct 
operand
tree.
(CompileLlvmAsm::construct_clobbers): Add function to construct 
clobber
tree.
(CompileLlvmAsm::tree_codegen_asm): Generate the whole tree for a 
given
llvm inline assembly node.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
(ExprStmtBuilder::visit):
Add visit function.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Add function
prototype.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Add visit
function.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit):
Likewise.
* checks/errors/privacy/rust-privacy-reporter.h: Add visit function
prototype.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): Add 
visit
function.
* checks/errors/rust-const-checker.h: Add visit function prototype.
* checks/errors/rust-hir-pattern-analysis.cc 
(PatternChecker::visit):
Add visit function.
* checks/errors/rust-hir-pattern-analysis.h: Add visit function
prototype.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Add
visit function.
* checks/errors/rust-unsafe-checker.h: Add function prototype.
* expand/rust-macro-builtins-asm.cc (parse_llvm_templates): Parse
templates.
(parse_llvm_arguments): Add function to parse non template tokens.
(parse_llvm_operands): Add function to parse operands, either input 
or
output.
(parse_llvm_outputs): Add function to parse and collect llvm asm
outputs.
(parse_llvm_inputs): Likewise with inputs.
(parse_llvm_clobbers): Add function to parse llvm asm clobbers.
(parse_llvm_options): Add function to parse llvm asm options.
(parse_llvm_asm): Add function to parse llvm asm.
* expand/rust-macro-builtins-asm.h (class LlvmAsmContext): Add 
context
for llvm asm parser.
(parse_llvm_outputs): Add function prototype.
(parse_llvm_inputs): Likewise.
(parse_llvm_clobbers): Likewise.
(parse_llvm_options): Likewise.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Lower AST 
llvm
asm node to HIR.
* hir/rust-ast-lower-expr.h: Add function prototype.
* hir/rust-hir-dump.cc (Dump::visit): Add visit function.
* hir/rust-hir-dump.h: Add function prototype.
* hir/tree/rust-hir-expr-abstract.h: Add HIR llvm asm node kind.
* hir/tree/rust-hir-expr.h (struct LlvmOperand): Add LlvmOperand 
type
to represent input and outputs.
(class LlvmInlineAsm): Add LlvmInlineAsm hir node.
* hir/tree/rust-hir-full-decls.h (class LlvmInlineAsm): Add
LlvmInlineAsm hir node forward declaration.
* hir/tree/rust-hir-visitor.h: Add visit functions for LlvmInlineAsm
hir node.
* hir/tree/rust-hir.cc (LlvmInlineAsm::accept_vis): Add hir node
visitor related functions.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Type check input and output operands.
* typecheck/rust-hir-type-check-expr.h: Add function prototype.
* ast/rust-ast-visitor.cc (Default

[gcc/devel/rust/master] gccrs: Fix ICE when handling case of unknown field in HIR::FieldAccess

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f81ec04bfde4e771998b44dd5c685069d1229652

commit f81ec04bfde4e771998b44dd5c685069d1229652
Author: Philip Herron 
Date:   Thu Apr 17 13:50:55 2025 +0100

gccrs: Fix ICE when handling case of unknown field in HIR::FieldAccess

We were wrongly adding the assertion that this must not be an enum but
this is a pointless assertion we only care that there are variant in the
ADT and if the field exists in the first variant.

Fixes Rust-GCC#3581

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): fix 
bad assertion

gcc/testsuite/ChangeLog:

* rust/compile/nonexistent-field.rs: fix bad error message
* rust/compile/issue-3581-1.rs: New test.
* rust/compile/issue-3581-2.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 18 --
 gcc/testsuite/rust/compile/issue-3581-1.rs  | 12 
 gcc/testsuite/rust/compile/issue-3581-2.rs  |  9 +
 gcc/testsuite/rust/compile/nonexistent-field.rs |  2 +-
 4 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index b960e73abd92..115aba7047b6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1142,27 +1142,25 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
   bool is_valid_type = struct_base->get_kind () == TyTy::TypeKind::ADT;
   if (!is_valid_type)
 {
-  rust_error_at (expr.get_locus (),
-"expected algebraic data type got: [%s]",
-struct_base->as_string ().c_str ());
+  rust_error_at (expr.get_locus (), "expected algebraic data type got %qs",
+struct_base->get_name ().c_str ());
   return;
 }
 
   TyTy::ADTType *adt = static_cast (struct_base);
-  rust_assert (!adt->is_enum ());
-  rust_assert (adt->number_of_variants () == 1);
-
+  rust_assert (adt->number_of_variants () > 0);
   TyTy::VariantDef *vaiant = adt->get_variants ().at (0);
 
   TyTy::StructFieldType *lookup = nullptr;
   bool found = vaiant->lookup_field (expr.get_field_name ().as_string (),
 &lookup, nullptr);
-  if (!found)
+  if (!found || adt->is_enum ())
 {
-  rust_error_at (expr.get_locus (), ErrorCode::E0609,
-"no field %qs on type %qs",
+  rich_location r (line_table, expr.get_locus ());
+  r.add_range (expr.get_field_name ().get_locus ());
+  rust_error_at (r, ErrorCode::E0609, "no field %qs on type %qs",
 expr.get_field_name ().as_string ().c_str (),
-adt->as_string ().c_str ());
+adt->get_name ().c_str ());
   return;
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-3581-1.rs 
b/gcc/testsuite/rust/compile/issue-3581-1.rs
new file mode 100644
index ..eb2f5f033d50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-1.rs
@@ -0,0 +1,12 @@
+enum Foo {
+Bar,
+}
+
+struct Baz;
+
+fn main() {
+Foo::Bar.a;
+// { dg-error "no field .a. on type .Foo. .E0609." "" { target *-*-* } .-1 
}
+Baz.a;
+// { dg-error "no field .a. on type .Baz. .E0609." "" { target *-*-* } .-1 
}
+}
diff --git a/gcc/testsuite/rust/compile/issue-3581-2.rs 
b/gcc/testsuite/rust/compile/issue-3581-2.rs
new file mode 100644
index ..505978444652
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3581-2.rs
@@ -0,0 +1,9 @@
+enum A {
+X { inner: i32 },
+Y,
+}
+
+pub fn test() {
+let _ = A::Y.inner;
+// { dg-error "no field .inner. on type .A. .E0609." "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/nonexistent-field.rs 
b/gcc/testsuite/rust/compile/nonexistent-field.rs
index e20c49d3ebf4..9bcfb2fe84fb 100644
--- a/gcc/testsuite/rust/compile/nonexistent-field.rs
+++ b/gcc/testsuite/rust/compile/nonexistent-field.rs
@@ -6,7 +6,7 @@ fn main() {
 
 let s = StructWithFields { x: 0 };
 s.foo;
-// { dg-error "no field .foo. on type .StructWithFields.StructWithFields 
.x.u32... .E0609." "" { target *-*-* } .-1 }
+// { dg-error "no field .foo. on type .StructWithFields. .E0609." "" { 
target *-*-* } .-1 }
 
 let numbers = (1, 2, 3);
 numbers.3;


[gcc/devel/rust/master] nr2.0: Handle StructPatternFieldIdent

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:5a2d06037c7e0b0f06543db17b8376b6a6fceeb3

commit 5a2d06037c7e0b0f06543db17b8376b6a6fceeb3
Author: Owen Avery 
Date:   Thu Apr 17 14:02:45 2025 -0400

nr2.0: Handle StructPatternFieldIdent

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Handle StructPatternFieldIdent.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 8 
 gcc/rust/resolve/rust-late-name-resolver-2.0.h  | 1 +
 gcc/testsuite/rust/compile/nr2/exclude  | 1 -
 3 files changed, 9 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 c140fa07f9b8..6ac249b4cf22 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -172,6 +172,14 @@ Late::visit (AST::IdentifierPattern &identifier)
  identifier.get_node_id ());
 }
 
+void
+Late::visit (AST::StructPatternFieldIdent &field)
+{
+  // We do want to ignore duplicated data because some situations rely on it.
+  std::ignore = ctx.values.insert_shadowable (field.get_identifier (),
+ field.get_node_id ());
+}
+
 void
 Late::visit (AST::SelfParam ¶m)
 {
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 52079cc42c9e..34f3c28fee4f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -42,6 +42,7 @@ public:
   // TODO: Do we need this?
   // void visit (AST::Method &) override;
   void visit (AST::IdentifierPattern &) override;
+  void visit (AST::StructPatternFieldIdent &) override;
   void visit (AST::SelfParam &) override;
 
   // resolutions
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 4772517c47e4..5c52a3cababa 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -16,7 +16,6 @@ derive_clone_enum3.rs
 derive-debug1.rs
 derive-default1.rs
 derive-eq-invalid.rs
-derive-hash1.rs
 torture/alt_patterns1.rs
 torture/name_resolve1.rs
 issue-3568.rs


[gcc/devel/rust/master] gccrs: Add test case to show ICE is fixed

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:838b583c6600758d2a2f537c8379ff69e336a848

commit 838b583c6600758d2a2f537c8379ff69e336a848
Author: Philip Herron 
Date:   Thu Apr 17 16:29:05 2025 +0100

gccrs: Add test case to show ICE is fixed

Fixes Rust-GCC#3662

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 

Diff:
---
 gcc/testsuite/rust/compile/issue-3662.rs | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/testsuite/rust/compile/issue-3662.rs 
b/gcc/testsuite/rust/compile/issue-3662.rs
new file mode 100644
index ..88baa2e25745
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3662.rs
@@ -0,0 +1,8 @@
+pub fn rlib() {
+let _ = ((-1 as i8) << 8 - 1) as f32;
+let _ = 0u8 as char;
+let _ = true > false;
+let _ = true >= false;
+let _ = true < false;
+let _ = true >= false;
+}


[gcc/devel/rust/master] gccrs: Fix ICE in struct expressions

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:e77b7c22ab159f967fc2e0bca59468d0df08a023

commit e77b7c22ab159f967fc2e0bca59468d0df08a023
Author: Philip Herron 
Date:   Thu Apr 17 14:38:04 2025 +0100

gccrs: Fix ICE in struct expressions

The error handling here was done long ago when we didnt know how to do
any error handling very well. This removed bad fatal_errors and adds in
some nice rich_location error diagnostics instead.

Fixes Rust-GCC#3628

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-struct-field.h: keep reference to 
parent expression
* typecheck/rust-hir-type-check-struct.cc 
(TypeCheckStructExpr::TypeCheckStructExpr):
update ctor
(TypeCheckStructExpr::resolve): remove bad rust_fatal_errors
(TypeCheckStructExpr::visit): cleanup errors

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro-issue2983_2984.rs: cleanup error 
diagnotics
* rust/compile/struct_init1.rs: likewise
* rust/compile/issue-3628.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 .../typecheck/rust-hir-type-check-struct-field.h   |  3 ++
 gcc/rust/typecheck/rust-hir-type-check-struct.cc   | 54 +++---
 gcc/testsuite/rust/compile/issue-3628.rs   | 10 
 .../compile/macros/mbe/macro-issue2983_2984.rs |  5 +-
 gcc/testsuite/rust/compile/struct_init1.rs |  6 +--
 5 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h 
b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
index 1d4d1fa5e147..9d0ee7ada6ef 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h
@@ -60,6 +60,9 @@ private:
   TyTy::BaseType *resolved_field_value_expr;
   std::set fields_assigned;
   std::map adtFieldIndexToField;
+
+  // parent
+  HIR::Expr &parent;
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc 
b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
index 1931f08ff4d2..d8aabc37da26 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc
@@ -28,7 +28,7 @@ TypeCheckStructExpr::TypeCheckStructExpr (HIR::Expr &e)
   : TypeCheckBase (),
 resolved (new TyTy::ErrorType (e.get_mappings ().get_hirid ())),
 struct_path_resolved (nullptr),
-variant (&TyTy::VariantDef::get_error_node ())
+variant (&TyTy::VariantDef::get_error_node ()), parent (e)
 {}
 
 TyTy::BaseType *
@@ -65,7 +65,7 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields 
&struct_expr)
 
   if (base_unify->get_kind () != struct_path_ty->get_kind ())
{
- rust_fatal_error (
+ rust_error_at (
struct_expr.get_struct_base ().get_base ().get_locus (),
"incompatible types for base struct reference");
  return;
@@ -82,7 +82,16 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields 
&struct_expr)
   bool ok = context->lookup_variant_definition (
struct_expr.get_struct_name ().get_mappings ().get_hirid (),
&variant_id);
-  rust_assert (ok);
+  if (!ok)
+   {
+ rich_location r (line_table, struct_expr.get_locus ());
+ r.add_range (struct_expr.get_struct_name ().get_locus ());
+ rust_error_at (
+   struct_expr.get_struct_name ().get_locus (), ErrorCode::E0574,
+   "expected a struct, variant or union type, found enum %qs",
+   struct_path_resolved->get_name ().c_str ());
+ return;
+   }
 
   ok = struct_path_resolved->lookup_variant_by_id (variant_id, &variant);
   rust_assert (ok);
@@ -118,29 +127,14 @@ TypeCheckStructExpr::resolve (HIR::StructExprStructFields 
&struct_expr)
  break;
}
 
-  if (!ok)
-   {
- return;
-   }
-
-  if (resolved_field_value_expr == nullptr)
-   {
- rust_fatal_error (field->get_locus (),
-   "failed to resolve type for field");
- ok = false;
- break;
-   }
-
-  context->insert_type (field->get_mappings (), resolved_field_value_expr);
+  if (ok)
+   context->insert_type (field->get_mappings (),
+ resolved_field_value_expr);
 }
 
-  // something failed setting up the fields
+  // something failed setting up the fields and error's emitted
   if (!ok)
-{
-  rust_error_at (struct_expr.get_locus (),
-"constructor type resolution failure");
-  return;
-}
+return;
 
   // check the arguments are all assigned and fix up the ordering
   std::vector missing_field_names;
@@ -271,8 +265,11 @@ TypeCheckStructExpr::visit 
(HIR::StructExprFieldIdentifierValue &field)
   &field_index);
   if (!ok)
 {
-  rust_error_at (field.get_locus (), "unknown field");
-  return true;
+ 

[gcc/devel/rust/master] nr2.0: Remove unnecessary copy of Node

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f220fe8cf73f56421f2f5659054006e38c3cd2b1

commit f220fe8cf73f56421f2f5659054006e38c3cd2b1
Author: Owen Avery 
Date:   Thu Apr 17 19:23:12 2025 -0400

nr2.0: Remove unnecessary copy of Node

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx
(ForeverStack::resolve_path): Pass instance of Node to lambda by
reference instead of by value.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/resolve/rust-forever-stack.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index e9024b564ca7..947b72fc21f3 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -676,7 +676,7 @@ ForeverStack::resolve_path (
 insert_segment_resolution);
  })
.and_then ([this, &segments, &insert_segment_resolution] (
-Node final_node) -> tl::optional {
+Node &final_node) -> tl::optional {
  // leave resolution within impl blocks to type checker
  if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;


[gcc/devel/rust/master] gccrs: Add test case to show ice is fixed

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:0a34f7bb91855ac95c51219c89d4049c4d69f7b3

commit 0a34f7bb91855ac95c51219c89d4049c4d69f7b3
Author: Philip Herron 
Date:   Fri Apr 18 11:37:55 2025 +0100

gccrs: Add test case to show ice is fixed

Fixes Rust-GCC#3652

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 does not error on the T it should 
require Self::T
* rust/compile/issue-3652.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/testsuite/rust/compile/issue-3652.rs | 7 +++
 gcc/testsuite/rust/compile/nr2/exclude   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/gcc/testsuite/rust/compile/issue-3652.rs 
b/gcc/testsuite/rust/compile/issue-3652.rs
new file mode 100644
index ..537ca9f881a2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3652.rs
@@ -0,0 +1,7 @@
+trait Foo {
+type T;
+fn foo() -> T<::T>;
+// { dg-error "could not resolve type path .T. .E0412." "" { target *-*-* 
} .-1 }
+}
+
+fn foo() {}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 5c52a3cababa..e5911b2a6ac0 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -21,4 +21,5 @@ torture/name_resolve1.rs
 issue-3568.rs
 issue-3663.rs
 issue-3671.rs
+issue-3652.rs
 # please don't delete the trailing newline


[gcc/devel/rust/master] gccrs: Fix ICE with empty generic arguments

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:4d70c16011e809a6732a0c34f1fc23ca75851476

commit 4d70c16011e809a6732a0c34f1fc23ca75851476
Author: Philip Herron 
Date:   Thu Apr 17 15:53:58 2025 +0100

gccrs: Fix ICE with empty generic arguments

We have an assertion when accessing generic args if there are any which
is really useful so this adds the missing guards for the case where
they are specified but empty.

Fixes Rust-GCC#3649

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): add guard
* expand/rust-expand-visitor.cc (ExpandVisitor::visit): add guard

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 is missing error for this
* rust/compile/issue-3649.rs: New test.

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/ast/rust-ast-visitor.cc | 3 ++-
 gcc/rust/expand/rust-expand-visitor.cc   | 3 ++-
 gcc/testsuite/rust/compile/issue-3649.rs | 2 ++
 gcc/testsuite/rust/compile/nr2/exclude   | 1 +
 4 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 577410215405..4d4e89c78258 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -108,7 +108,8 @@ DefaultASTVisitor::visit (GenericArgsBinding &binding)
 void
 DefaultASTVisitor::visit (AST::TypePathSegmentGeneric &segment)
 {
-  visit (segment.get_generic_args ());
+  if (segment.has_generic_args ())
+visit (segment.get_generic_args ());
 }
 
 void
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index b5e65b5f6414..c6c1ba4e7b03 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -489,7 +489,8 @@ ExpandVisitor::visit (AST::PathInExpression &path)
 void
 ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
 {
-  expand_generic_args (segment.get_generic_args ());
+  if (segment.has_generic_args ())
+expand_generic_args (segment.get_generic_args ());
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/issue-3649.rs 
b/gcc/testsuite/rust/compile/issue-3649.rs
new file mode 100644
index ..b85b193312ef
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3649.rs
@@ -0,0 +1,2 @@
+struct T(Box<>);
+// { dg-error "could not resolve type path .Box. .E0412." "" { target *-*-* } 
.-1 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e5911b2a6ac0..12e63d884a38 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -22,4 +22,5 @@ issue-3568.rs
 issue-3663.rs
 issue-3671.rs
 issue-3652.rs
+issue-3649.rs
 # please don't delete the trailing newline


[gcc/devel/rust/master] Disable parallel testing for 'rust/compile/nr2/compile.exp' [PR119508]

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:2753c6f3b86b9532ce2e0c580c59d0413b68e139

commit 2753c6f3b86b9532ce2e0c580c59d0413b68e139
Author: Thomas Schwinge 
Date:   Sat Apr 19 15:49:34 2025 +0200

Disable parallel testing for 'rust/compile/nr2/compile.exp' [PR119508]

..., using the standard idiom.  This '*.exp' file doesn't adhere to the
parallel testing protocol as defined in 'gcc/testsuite/lib/gcc-defs.exp'.

This also restores proper behavior for '*.exp' files executing after (!) 
this
one, which erroneously caused hundreds or even thousands of individual test
cases get duplicated vs. skipped, randomly, depending on the '-jN' level.

PR testsuite/119508
gcc/testsuite/
* rust/compile/nr2/compile.exp: Disable parallel testing.

(cherry picked from commit 79d2c3089f480738613b7d338d86d8be710f8158)

Diff:
---
 gcc/testsuite/rust/compile/nr2/compile.exp | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp 
b/gcc/testsuite/rust/compile/nr2/compile.exp
index 4d91dd004a3d..9e15cdd7253a 100644
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ b/gcc/testsuite/rust/compile/nr2/compile.exp
@@ -19,6 +19,15 @@
 # Load support procs.
 load_lib rust-dg.exp
 
+# These tests don't run runtest_file_p consistently if it
+# doesn't return the same values, so disable parallelization
+# of this *.exp file.  The first parallel runtest to reach
+# this will run all the tests serially.
+if ![gcc_parallel_test_run_p compile] {
+return
+}
+gcc_parallel_test_enable 0
+
 # Initialize `dg'.
 dg-init
 
@@ -136,3 +145,5 @@ namespace eval rust-nr2-ns {
 
 # All done.
 dg-finish
+
+gcc_parallel_test_enable 1


[gcc/devel/rust/master] Adjust segment start position errors

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:47d55fe8cb022d11b7899f8e93761a61ee38c583

commit 47d55fe8cb022d11b7899f8e93761a61ee38c583
Author: Owen Avery 
Date:   Thu Apr 17 16:51:21 2025 -0400

Adjust segment start position errors

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-path.cc
(ResolvePath::resolve_path): Adjust error messages.
* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Likewise.
* resolve/rust-forever-stack.hxx
(check_leading_kw_at_start): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/issue-3568.rs: Adjust expected errors.
* rust/compile/name_resolution9.rs: Likewise.
* rust/compile/self-path2.rs: Likewise.

Signed-off-by: Owen Avery 

Diff:
---
 gcc/rust/resolve/rust-ast-resolve-path.cc  | 8 
 gcc/rust/resolve/rust-ast-resolve-type.cc  | 3 +--
 gcc/rust/resolve/rust-forever-stack.hxx| 7 +++
 gcc/testsuite/rust/compile/issue-3568.rs   | 2 +-
 gcc/testsuite/rust/compile/name_resolution9.rs | 4 ++--
 gcc/testsuite/rust/compile/self-path2.rs   | 4 ++--
 6 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc 
b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 530926d5d97a..fb6715d9528a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -68,8 +68,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
   if (in_middle_of_path && segment.is_lower_self_seg ())
{
  rust_error_at (segment.get_locus (), ErrorCode::E0433,
-"leading path segment %qs can only be used at the "
-"beginning of a path",
+"%qs in paths can only be used in start position",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -372,8 +371,9 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
{
  if (!is_first_segment)
{
- rust_error_at (segment.get_locus (),
-"% can only be used in start position");
+ rust_error_at (
+   segment.get_locus (), ErrorCode::E0433,
+   "% in paths can only be used in start position");
  return UNKNOWN_NODEID;
}
  if (module_scope_id == crate_scope_id)
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 135504ed9b5e..8df6b952ca06 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -176,8 +176,7 @@ 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,
-"leading path segment %qs can only be used at the "
-"beginning of a path",
+"%qs in paths can only be used in start position",
 segment->as_string ().c_str ());
  return false;
}
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 947b72fc21f3..6d92e2b30bcf 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -401,10 +401,9 @@ static inline bool
 check_leading_kw_at_start (const S &segment, bool condition)
 {
   if (condition)
-rust_error_at (
-  segment.get_locus (), ErrorCode::E0433,
-  "leading path segment %qs can only be used at the beginning of a path",
-  segment.as_string ().c_str ());
+rust_error_at (segment.get_locus (), ErrorCode::E0433,
+  "%qs in paths can only be used in start position",
+  segment.as_string ().c_str ());
 
   return condition;
 }
diff --git a/gcc/testsuite/rust/compile/issue-3568.rs 
b/gcc/testsuite/rust/compile/issue-3568.rs
index 222a174ef381..fef43b5d1e40 100644
--- a/gcc/testsuite/rust/compile/issue-3568.rs
+++ b/gcc/testsuite/rust/compile/issue-3568.rs
@@ -4,4 +4,4 @@ mod foo {
 }
 
 pub use foo::super::foo::S as T;
-// { dg-error ".super. can only be used in start position" "" { target *-*-* } 
.-1 }
+// { dg-error ".super. in paths can only be used in start position" "" { 
target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/name_resolution9.rs 
b/gcc/testsuite/rust/compile/name_resolution9.rs
index 93adb46d278a..792b3bdd6b5c 100644
--- a/gcc/testsuite/rust/compile/name_resolution9.rs
+++ b/gcc/testsuite/rust/compile/name_resolution9.rs
@@ -6,11 +6,11 @@ pub mod foo {
 super::super::super::foo!(); // { dg-error "too many leading 
.super. keywords" }
  // { dg-error "could not resolve 
macro invocation" "" { target *-*-* } .-1 }
 
-  

[gcc/devel/rust/master] gccrs: prealloc the initilizer vector

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:ad951b9c2696a62fddf2502e3b68352a81264f7c

commit ad951b9c2696a62fddf2502e3b68352a81264f7c
Author: Philip Herron 
Date:   Thu Apr 17 16:19:35 2025 +0100

gccrs: prealloc the initilizer vector

There are two cases when initilizing an array, this is the
const context which means we need to build the array ctor,
which means using lots of memory, its super inefficient
because we are using a big wrapper over the GCC internals here
but preallocating the vectors here causes a:

  terminate called after throwing an instance of 'std::bad_alloc'

So this is a handy error condition to rely on for this senario.

Fixes Rust-GCC#3713
Fixes Rust-GCC#3727

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::array_copied_expr): 
prealloc the vector

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 1e09c6c155ae..339317d81747 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1972,8 +1972,12 @@ CompileExpr::array_copied_expr (location_t expr_locus,
   if (ctx->const_context_p ())
 {
   size_t idx = 0;
+
   std::vector indexes;
   std::vector constructor;
+
+  indexes.reserve (len);
+  constructor.reserve (len);
   for (unsigned HOST_WIDE_INT i = 0; i < len; i++)
{
  constructor.push_back (translated_expr);


[gcc/devel/rust/master] gccrs: Add test case to show issue is fixed

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:701094f4908d9b31e9c712c04f02c443576cf903

commit 701094f4908d9b31e9c712c04f02c443576cf903
Author: Philip Herron 
Date:   Thu Apr 17 16:04:55 2025 +0100

gccrs: Add test case to show issue is fixed

This was already fixed in: bb01719f0e1 but we require fn_once lang item
to be defined as we are working on libcore support still.

Fixes Rust-GCC#3711

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 

Diff:
---
 gcc/testsuite/rust/compile/issue-3711.rs | 17 +
 1 file changed, 17 insertions(+)

diff --git a/gcc/testsuite/rust/compile/issue-3711.rs 
b/gcc/testsuite/rust/compile/issue-3711.rs
new file mode 100644
index ..a3f9c39b4c58
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3711.rs
@@ -0,0 +1,17 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce {
+#[lang = "fn_once_output"]
+type Output;
+
+extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn returns_closure() -> _ {
+// { dg-error "the type placeholder ._. is not allowed within types on 
item signatures .E0121." "" { target *-*-* } .-1 }
+|| 0
+}
+
+fn main() {}


[gcc/devel/rust/master] Add execute test for black_box intrinsic

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:78fcf63b606343f6fe837b933b8fadccf0f49e87

commit 78fcf63b606343f6fe837b933b8fadccf0f49e87
Author: Pierre-Emmanuel Patry 
Date:   Thu Apr 17 17:53:15 2025 +0200

Add execute test for black_box intrinsic

gcc/testsuite/ChangeLog:

* rust/execute/black_box.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/testsuite/rust/execute/black_box.rs | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/gcc/testsuite/rust/execute/black_box.rs 
b/gcc/testsuite/rust/execute/black_box.rs
new file mode 100644
index ..7a9920eba947
--- /dev/null
+++ b/gcc/testsuite/rust/execute/black_box.rs
@@ -0,0 +1,30 @@
+/* { dg-output "Value is: 42\r*\n" } */
+#![feature(rustc_attrs)]
+
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! llvm_asm {
+() => {};
+}
+
+pub fn black_box(mut dummy: T) -> T {
+unsafe {
+llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+}
+
+dummy
+}
+
+fn main() {
+let dummy: i32 = 42;
+let result = black_box(dummy);
+unsafe {
+printf("Value is: %i\n\0" as *const str as *const i8, result);
+}
+}


[gcc/devel/rust/master] gccrs: Fix ICE when checking shift's which are behind array refs

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:50a90f12af84ba2d203a0510bbeb41a383981303

commit 50a90f12af84ba2d203a0510bbeb41a383981303
Author: Philip Herron 
Date:   Wed Apr 16 17:13:04 2025 +0100

gccrs: Fix ICE when checking shift's which are behind array refs

I copied a bad form of this check from the c front-end this updates it
to ensure the rhs is an INTEGER_CST and the lhs needs checked in the first
place.

Fixes Rust-GCC#3664

gcc/rust/ChangeLog:

* rust-gcc.cc (arithmetic_or_logical_expression): Ensure this is an 
integer

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/rust-gcc.cc | 1 +
 gcc/testsuite/rust/compile/issue-3664.rs | 5 +
 2 files changed, 6 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 524cee71a6e8..990c78675487 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1109,6 +1109,7 @@ arithmetic_or_logical_expression 
(ArithmeticOrLogicalOperator op, tree left,
   rust_error_at (location, "division by zero");
 }
   else if (op == ArithmeticOrLogicalOperator::LEFT_SHIFT
+  && TREE_CODE (right) == INTEGER_CST
   && (compare_tree_int (right, TYPE_PRECISION (TREE_TYPE (ret))) >= 0))
 {
   rust_error_at (location, "left shift count >= width of type");
diff --git a/gcc/testsuite/rust/compile/issue-3664.rs 
b/gcc/testsuite/rust/compile/issue-3664.rs
new file mode 100644
index ..c52a75805afd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3664.rs
@@ -0,0 +1,5 @@
+const ARR: [usize; 1] = [2];
+
+pub fn l8() {
+let _ = 5 << ARR[0];
+}


[gcc/devel/rust/master] gccrs: Implement integer representation for enums

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:654d79b98a67834fb33a51d05c452a1ff729e1d3

commit 654d79b98a67834fb33a51d05c452a1ff729e1d3
Author: Zhi Heng 
Date:   Thu Apr 3 23:02:59 2025 +0800

gccrs: Implement integer representation for enums

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc: Set enum representing
type properly if repr is an integer type.
* typecheck/rust-hir-type-check-item.cc: Update comments.

Signed-off-by: Yap Zhi Heng 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 13 ++---
 gcc/rust/typecheck/rust-hir-type-check-item.cc |  2 +-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index f066ddc4fd31..51c1ae78ec0f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -308,7 +308,7 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
   repr.pack = 0;
   repr.align = 0;
 
-  // FIXME handle repr types
+  // FIXME handle non-integer repr types
   bool ok = context->lookup_builtin ("isize", &repr.repr);
   rust_assert (ok);
 
@@ -353,8 +353,10 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  // manually parsing the string "packed(2)" here.
 
  size_t oparen = inline_option.find ('(', 0);
- bool is_pack = false, is_align = false, is_c = false,
-  is_integer = false;
+ bool is_pack = false;
+ bool is_align = false;
+ bool is_c = false;
+ bool is_integer = false;
  unsigned char value = 1;
 
  if (oparen == std::string::npos)
@@ -409,6 +411,11 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  else if (is_integer)
{
  repr.repr_kind = TyTy::ADTType::ReprKind::INT;
+ bool ok = context->lookup_builtin (inline_option, &repr.repr);
+ if (!ok)
+   {
+ rust_error_at (attr.get_locus (), "Invalid repr type");
+   }
}
 
  delete meta_items;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 7491cb47f5a7..a29f0432397a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -355,7 +355,7 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
   variants.push_back (field_type);
 }
 
-  // Check for zero-variant enum compatibility before processing repr attribute
+  // Check for zero-variant enum compatibility
   if (enum_decl.is_zero_variant ())
 {
   if (repr.repr_kind == TyTy::ADTType::ReprKind::INT


[gcc/devel/rust/master] gccrs: Update comments in repr parsing code

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:a59e57efe221ef6296a8b5fcb5290733e15a3d20

commit a59e57efe221ef6296a8b5fcb5290733e15a3d20
Author: Yap Zhi Heng 
Date:   Fri Apr 4 19:37:03 2025 +0800

gccrs: Update comments in repr parsing code

gcc/rust/ChangeLog:

* typecheck/rust-tyty.h: Remove extra redundant comment.
* typecheck/rust-hir-type-check-base.cc: Update comment on repr
handling.

Signed-off-by: Yap Zhi Heng 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 3 ++-
 gcc/rust/typecheck/rust-tyty.h | 1 -
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 51c1ae78ec0f..2f0b86a0a6ce 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -308,7 +308,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
   repr.pack = 0;
   repr.align = 0;
 
-  // FIXME handle non-integer repr types
+  // Default repr for enums is isize, but we now check for other repr in the
+  // attributes.
   bool ok = context->lookup_builtin ("isize", &repr.repr);
   rust_assert (ok);
 
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index cd7bf24585ee..e1370e0964db 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -719,7 +719,6 @@ public:
 ALIGN,
 PACKED,
 // TRANSPARENT,
-// PACKED,
 // SIMD,
 // ...
   };


[gcc/devel/rust/master] Add gimple test for black box intrinsic

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:d85328baf00510fce8b5d3843f731023e12944b1

commit d85328baf00510fce8b5d3843f731023e12944b1
Author: Pierre-Emmanuel Patry 
Date:   Thu Apr 17 18:28:52 2025 +0200

Add gimple test for black box intrinsic

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/testsuite/rust/compile/black_box.rs | 28 
 1 file changed, 28 insertions(+)

diff --git a/gcc/testsuite/rust/compile/black_box.rs 
b/gcc/testsuite/rust/compile/black_box.rs
new file mode 100644
index ..80615af5b5d1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/black_box.rs
@@ -0,0 +1,28 @@
+// { dg-options "-fdump-tree-gimple" }
+#![feature(rustc_attrs)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[rustc_builtin_macro]
+macro_rules! llvm_asm {
+() => {};
+}
+
+pub fn black_box(mut dummy: T) -> T {
+unsafe {
+// { dg-final { scan-tree-dump-times {memory} 1 gimple } }
+llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
+}
+
+dummy
+}
+
+fn my_function(a: i32) -> i32 {
+a
+}
+
+fn main() {
+let dummy: i32 = 42;
+let _ = black_box(my_function(dummy));
+}


[gcc/devel/rust/master] gccrs: Add check for placeholder (infer) type in return position

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:bb01719f0e1665a777b2b475e5feaafd01aa3ac8

commit bb01719f0e1665a777b2b475e5feaafd01aa3ac8
Author: Philip Herron 
Date:   Wed Apr 16 20:38:17 2025 +0100

gccrs: Add check for placeholder (infer) type in return position

It is not allowed to have a declared inference variable in the return
position of a function as this may never get infered you need good points
of truth.

Ideally if we get a student for GSoC 25 we will get the Default Hir Visitor
so that we can grab the HIR::InferredType locus instead of using the ref
location lookups.

Fixes Rust-GCC#402

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): add 
diagnostic
* typecheck/rust-tyty.cc (BaseType::contains_infer): new helper to 
grab first infer var
* typecheck/rust-tyty.h: prototype

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 32 ++
 gcc/rust/typecheck/rust-tyty.cc| 85 ++
 gcc/rust/typecheck/rust-tyty.h |  3 +
 gcc/testsuite/rust/compile/issue-402.rs| 14 +
 4 files changed, 134 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index a29f0432397a..e3889949c42e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -649,6 +649,38 @@ TypeCheckItem::visit (HIR::Function &function)
   context->switch_to_fn_body ();
   auto block_expr_ty = TypeCheckExpr::Resolve (function.get_definition ());
 
+  // emit check for
+  // error[E0121]: the type placeholder `_` is not allowed within types on item
+  const auto placeholder = ret_type->contains_infer ();
+  if (placeholder != nullptr && function.has_return_type ())
+{
+  // FIXME
+  // this will be a great place for the Default Hir Visitor we want to
+  // grab the locations of the placeholders (HIR::InferredType) their
+  // location, for now maybe we can use their hirid to lookup the location
+  location_t placeholder_locus
+   = mappings.lookup_location (placeholder->get_ref ());
+  location_t type_locus = function.get_return_type ().get_locus ();
+  rich_location r (line_table, placeholder_locus);
+
+  bool have_expected_type
+   = block_expr_ty != nullptr && !block_expr_ty->is ();
+  if (!have_expected_type)
+   {
+ r.add_range (type_locus);
+   }
+  else
+   {
+ std::string fixit
+   = "replace with the correct type " + block_expr_ty->get_name ();
+ r.add_fixit_replace (type_locus, fixit.c_str ());
+   }
+
+  rust_error_at (r, ErrorCode::E0121,
+"the type placeholder %<_%> is not allowed within types "
+"on item signatures");
+}
+
   location_t fn_return_locus = function.has_function_return_type ()
 ? function.get_return_type ().get_locus ()
 : function.get_locus ();
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 28c99a986ad6..4da51ffdbfd1 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -682,6 +682,91 @@ BaseType::debug () const
  debug_str ().c_str ());
 }
 
+const TyTy::BaseType *
+BaseType::contains_infer () const
+{
+  const TyTy::BaseType *x = destructure ();
+
+  if (auto fn = x->try_as ())
+{
+  for (const auto ¶m : fn->get_params ())
+   {
+ auto infer = param.get_type ()->contains_infer ();
+ if (infer)
+   return infer;
+   }
+  return fn->get_return_type ()->contains_infer ();
+}
+  else if (auto fn = x->try_as ())
+{
+  for (const auto ¶m : fn->get_params ())
+   {
+ auto infer = param.get_tyty ()->contains_infer ();
+ if (infer)
+   return infer;
+   }
+  return fn->get_return_type ()->contains_infer ();
+}
+  else if (auto adt = x->try_as ())
+{
+  for (auto &variant : adt->get_variants ())
+   {
+ bool is_num_variant
+   = variant->get_variant_type () == VariantDef::VariantType::NUM;
+ if (is_num_variant)
+   continue;
+
+ for (auto &field : variant->get_fields ())
+   {
+ const BaseType *field_type = field->get_field_type ();
+ auto infer = (field_type->contains_infer ());
+ if (infer)
+   return infer;
+   }
+   }
+  return nullptr;
+}
+  else if (auto arr = x->try_as ())
+{
+  return arr->get_element_type ()->contains_infer ();
+}
+  else if (auto slice = x->try_as ())
+{
+  return slice->get_element_type ()->contains_infer ();
+}
+  else if (auto ptr

[gcc/devel/rust/master] Add llvmInlineAsm node

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:435b346f47ffa467bb6cfa1717ab9f2283b18d46

commit 435b346f47ffa467bb6cfa1717ab9f2283b18d46
Author: Pierre-Emmanuel Patry 
Date:   Thu Apr 10 13:05:15 2025 +0200

Add llvmInlineAsm node

InlineAsm node does not support memory clobbers.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Make visitor
unreachable.
* ast/rust-ast-collector.h: Add visit for LlvmInlineAsmNode.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit
function for the default ast visitor.
* ast/rust-ast-visitor.h: Add function prototype.
* ast/rust-ast.cc (LlvmInlineAsm::accept_vis): Add accept_vis to
LlvmInlineAsm node.
* ast/rust-ast.h: Add LlvmInlineAsm node kind.
* ast/rust-expr.h (class LlvmInlineAsm): Add LlvmInlineAsm node.
* expand/rust-derive.h: Add visit function for LlvmInlineAsm node.
* expand/rust-macro-builtins-asm.cc 
(MacroBuiltin::llvm_asm_handler):
Add handler for llvm inline assembly nodes.
(parse_llvm_asm): Add function to parse llvm assembly nodes.
* expand/rust-macro-builtins-asm.h (parse_llvm_asm): Add function
prototypes.
* expand/rust-macro-builtins.cc (inline_llvm_asm_maker): Add macro
transcriber.
* expand/rust-macro-builtins.h: Add transcriber function prototype.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add visit
function for LlvmInlineAsm node.
* hir/rust-ast-lower-base.h: Add visit function prototype.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add visit
function for LlvmInlineAsm node.
* resolve/rust-ast-resolve-base.h: Add visit function prototype.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc | 10 ++-
 gcc/rust/ast/rust-ast-collector.h  |  1 +
 gcc/rust/ast/rust-ast-visitor.cc   |  4 +++
 gcc/rust/ast/rust-ast-visitor.h|  2 ++
 gcc/rust/ast/rust-ast.cc   |  6 
 gcc/rust/ast/rust-ast.h|  1 +
 gcc/rust/ast/rust-expr.h   | 48 ++
 gcc/rust/expand/rust-derive.h  |  1 +
 gcc/rust/expand/rust-macro-builtins-asm.cc | 21 +
 gcc/rust/expand/rust-macro-builtins-asm.h  |  7 +
 gcc/rust/expand/rust-macro-builtins.cc | 11 ++-
 gcc/rust/expand/rust-macro-builtins.h  |  4 +++
 gcc/rust/hir/rust-ast-lower-base.cc|  4 +++
 gcc/rust/hir/rust-ast-lower-base.h |  1 +
 gcc/rust/resolve/rust-ast-resolve-base.cc  |  4 +++
 gcc/rust/resolve/rust-ast-resolve-base.h   |  1 +
 16 files changed, 124 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 9a7164c3dac9..289f8601813c 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1520,7 +1520,15 @@ TokenCollector::visit (AsyncBlockExpr &expr)
 
 void
 TokenCollector::visit (InlineAsm &expr)
-{}
+{
+  rust_unreachable ();
+}
+
+void
+TokenCollector::visit (LlvmInlineAsm &expr)
+{
+  rust_unreachable ();
+}
 
 // rust-item.h
 
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index 3266caf66faf..b0f1ff5fd7f1 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -303,6 +303,7 @@ public:
   void visit (AwaitExpr &expr);
   void visit (AsyncBlockExpr &expr);
   void visit (InlineAsm &expr);
+  void visit (LlvmInlineAsm &expr);
   // rust-item.h
   void visit (TypeParam ¶m);
   void visit (LifetimeWhereClauseItem &item);
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 1a3fd65ce800..32e1d1f39a7b 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -713,6 +713,10 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
 }
 }
 
+void
+DefaultASTVisitor::visit (AST::LlvmInlineAsm &expr)
+{}
+
 void
 DefaultASTVisitor::visit (AST::TypeParam ¶m)
 {
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 20f735d7cc68..50cf1bf81482 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -131,6 +131,7 @@ public:
   virtual void visit (AwaitExpr &expr) = 0;
   virtual void visit (AsyncBlockExpr &expr) = 0;
   virtual void visit (InlineAsm &expr) = 0;
+  virtual void visit (LlvmInlineAsm &expr) = 0;
 
   // rust-item.h
   virtual void visit (TypeParam ¶m) = 0;
@@ -314,6 +315,7 @@ public:
   virtual void visit (AST::AwaitExpr &expr) override;
   virtual void visit (AST::AsyncBlockExpr &expr) override;
   virtual void visit (InlineAsm &expr) override;
+  virtual void visit (LlvmInlineAsm &expr) override;
 
   virtual void visit (AST::TypeParam ¶m) override;
   virtual voi

[gcc/devel/rust/master] gccrs: Fix crash in hir dump as labels are optional

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:95615a1ab48f1493fef21bb9f5f465f02ff527e4

commit 95615a1ab48f1493fef21bb9f5f465f02ff527e4
Author: Philip Herron 
Date:   Wed Apr 16 17:00:28 2025 +0100

gccrs: Fix crash in hir dump as labels are optional

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): add guard for optional label

Signed-off-by: Philip Herron 

Diff:
---
 gcc/rust/hir/rust-hir-dump.cc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 468d85527961..c4523e646b2c 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1284,7 +1284,9 @@ Dump::visit (BlockExpr &e)
   do_expr (e);
   do_inner_attrs (e);
   put_field ("tail_reachable", std::to_string (e.is_tail_reachable ()));
-  put_field ("label", e.get_label ().as_string ());
+
+  if (e.has_label ())
+put_field ("label", e.get_label ().as_string ());
 
   visit_collection ("statements", e.get_statements ());


[gcc/devel/rust/master] Emit error with old asm syntax in new asm blocks

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:56ccda1142cc2dc3a3e057d81d26d6a641732900

commit 56ccda1142cc2dc3a3e057d81d26d6a641732900
Author: Pierre-Emmanuel Patry 
Date:   Wed Apr 9 17:41:24 2025 +0200

Emit error with old asm syntax in new asm blocks

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_asm_arg): Emit error
message.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 021cd734308d..96ff0ea849fd 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -671,6 +671,14 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
 {
   token = parser.peek_current_token ();
 
+  if (token->get_id () == COLON || token->get_id () == SCOPE_RESOLUTION)
+   {
+ rust_error_at (
+   token->get_locus (),
+   "the legacy LLVM-style % syntax is no longer supported");
+ return tl::unexpected (COMMITTED);
+   }
+
   // We accept a comma token here.
   if (token->get_id () != COMMA
  && inline_asm_ctx.consumed_comma_without_formatted_string)


[gcc/devel/rust/master] Add LlvmInlineAsm node dump

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:f7952fe9d3b661b42bc15de28c0037bf936a658f

commit f7952fe9d3b661b42bc15de28c0037bf936a658f
Author: Pierre-Emmanuel Patry 
Date:   Thu Apr 17 14:27:11 2025 +0200

Add LlvmInlineAsm node dump

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Dump llvm 
inline
asm tokens.

Signed-off-by: Pierre-Emmanuel Patry 

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc | 39 +-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index ca096682354f..c584d8ab8d54 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1524,7 +1524,44 @@ TokenCollector::visit (InlineAsm &expr)
 
 void
 TokenCollector::visit (LlvmInlineAsm &expr)
-{}
+{
+  push (Rust::Token::make_identifier (expr.get_locus (), "llvm_asm"));
+  push (Rust::Token::make (EXCLAM, expr.get_locus ()));
+  push (Rust::Token::make (LEFT_PAREN, expr.get_locus ()));
+  for (auto &template_str : expr.get_templates ())
+push (Rust::Token::make_string (template_str.get_locus (),
+   std::move (template_str.symbol)));
+
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+  for (auto output : expr.get_outputs ())
+{
+  push (Rust::Token::make_string (expr.get_locus (),
+ std::move (output.constraint)));
+  visit (output.expr);
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+  for (auto input : expr.get_inputs ())
+{
+  push (Rust::Token::make_string (expr.get_locus (),
+ std::move (input.constraint)));
+  visit (input.expr);
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+  for (auto &clobber : expr.get_clobbers ())
+{
+  push (Rust::Token::make_string (expr.get_locus (),
+ std::move (clobber.symbol)));
+  push (Rust::Token::make (COMMA, expr.get_locus ()));
+}
+  push (Rust::Token::make (COLON, expr.get_locus ()));
+  // Dump options
+
+  push (Rust::Token::make (RIGHT_PAREN, expr.get_locus ()));
+}
 
 // rust-item.h


[gcc/devel/rust/master] nr2.0: Only insert derive macros if they exist

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:5bd41f967706556524cd1de172d03e7351402405

commit 5bd41f967706556524cd1de172d03e7351402405
Author: Arthur Cohen 
Date:   Wed Apr 9 14:48:55 2025 +0200

nr2.0: Only insert derive macros if they exist

This causes an assertion failure when compiling core with nr2.0, but should
probably be improved. I'm not sure how this code enables built-in derive
macros to be resolved so this is a temporary fix.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc 
(Early::visit_attributes): Remove assertion.

Diff:
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 7 +++
 1 file changed, 3 insertions(+), 4 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 d5f85b7d16ce..ef13aeacdd63 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -325,10 +325,9 @@ Early::visit_attributes (std::vector 
&attrs)
  auto pm_def = mappings.lookup_derive_proc_macro_def (
definition->get_node_id ());
 
- rust_assert (pm_def.has_value ());
-
- mappings.insert_derive_proc_macro_invocation (trait,
-   pm_def.value ());
+ if (pm_def.has_value ())
+   mappings.insert_derive_proc_macro_invocation (trait,
+ pm_def.value ());
}
}
   else if (Analysis::BuiltinAttributeMappings::get ()


[gcc/devel/rust/master] attributes: Handle external tool annotations like rustfmt::

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:6068e7aac646703fb563785b6d93f913180970a9

commit 6068e7aac646703fb563785b6d93f913180970a9
Author: Arthur Cohen 
Date:   Wed Apr 9 15:17:38 2025 +0200

attributes: Handle external tool annotations like rustfmt::

gcc/rust/ChangeLog:

* util/rust-attribute-values.h: Add RUSTFMT value.
* util/rust-attributes.cc: Define the attribute.
* util/rust-attributes.h (enum CompilerPass): Add EXTERNAL variant.
* expand/rust-macro-builtins.cc: Fix formatting.

Diff:
---
 gcc/rust/expand/rust-macro-builtins.cc | 1 -
 gcc/rust/util/rust-attribute-values.h  | 2 ++
 gcc/rust/util/rust-attributes.cc   | 3 ++-
 gcc/rust/util/rust-attributes.h| 5 -
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index d5b6dec4a71f..d8013c108515 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -83,7 +83,6 @@ const BiMap MacroBuiltin::builtins 
= {{
   {"Ord", BuiltinMacro::Ord},
   {"PartialOrd", BuiltinMacro::PartialOrd},
   {"Hash", BuiltinMacro::Hash},
-
 }};
 
 AST::MacroTranscriberFunc
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 1d69b7af239b..6e0aa48b26f5 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -83,6 +83,8 @@ public:
   static constexpr auto &FUNDAMENTAL = "fundamental";
 
   static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive";
+
+  static constexpr auto &RUSTFMT = "rustfmt";
 };
 } // namespace Values
 } // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 0442ff1d5258..2c1bd195b528 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -94,7 +94,8 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
 
  {Attrs::FUNDAMENTAL, TYPE_CHECK},
- {Attrs::NON_EXHAUSTIVE, TYPE_CHECK}};
+ {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
+ {Attrs::RUSTFMT, EXTERNAL}};
 
 BuiltinAttributeMappings *
 BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index e7e50835f58c..16e4847da99e 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -40,7 +40,10 @@ enum CompilerPass
   HIR_LOWERING,
   TYPE_CHECK,
   STATIC_ANALYSIS,
-  CODE_GENERATION
+  CODE_GENERATION,
+
+  // External Rust tooling attributes, like #[rustfmt::skip]
+  EXTERNAL,
 
   // Do we need to add something here for const fns?
 };


[gcc/devel/rust/master] lang-items: Add ManuallyDrop

2025-04-21 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:daf5dbc0272d57b772d579233268545c3a485e18

commit daf5dbc0272d57b772d579233268545c3a485e18
Author: Arthur Cohen 
Date:   Tue Apr 8 17:04:09 2025 +0200

lang-items: Add ManuallyDrop

gcc/rust/ChangeLog:

* util/rust-lang-item.h: Add new manually_drop lang item.
* util/rust-lang-item.cc: Likewise.

Diff:
---
 gcc/rust/util/rust-lang-item.cc | 1 +
 gcc/rust/util/rust-lang-item.h  | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 4b552e2b0b2c..0bd74b2bad9c 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -118,6 +118,7 @@ const BiMap 
Rust::LangItem::lang_items = {{
 
   {"discriminant_kind", Kind::DISCRIMINANT_KIND},
   {"discriminant_type", Kind::DISCRIMINANT_TYPE},
+  {"manually_drop", Kind::MANUALLY_DROP},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 1aaa88728e9c..c7dff939c18f 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -150,6 +150,8 @@ public:
 
 DISCRIMINANT_TYPE,
 DISCRIMINANT_KIND,
+
+MANUALLY_DROP,
   };
 
   static const BiMap lang_items;


[gcc r16-48] Add assert to array_slice::begin/end

2025-04-21 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:d508d24282c6a8172be2abcb2223232f452b667f

commit r16-48-gd508d24282c6a8172be2abcb2223232f452b667f
Author: Andrew Pinski 
Date:   Thu Jan 9 12:53:27 2025 -0800

Add assert to array_slice::begin/end

So while debugging PR 118320, I found it was useful to have
an assert inside array_slice::begin/end that the array slice isvalid
rather than getting an segfault. This adds an assert that is only
enabled for checking.

OK? Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

* vec.h (array_slice::begin): Assert that the
slice is valid.
(array_slice::end): Likewise.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/vec.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/vec.h b/gcc/vec.h
index 915df06f03e9..eae4b0feb4bc 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -2395,11 +2395,11 @@ public:
   array_slice (vec *v)
 : m_base (v ? v->address () : nullptr), m_size (v ? v->length () : 0) {}
 
-  iterator begin () { return m_base; }
-  iterator end () { return m_base + m_size; }
+  iterator begin () {  gcc_checking_assert (is_valid ()); return m_base; }
+  iterator end () {  gcc_checking_assert (is_valid ()); return m_base + 
m_size; }
 
-  const_iterator begin () const { return m_base; }
-  const_iterator end () const { return m_base + m_size; }
+  const_iterator begin () const { gcc_checking_assert (is_valid ()); return 
m_base; }
+  const_iterator end () const { gcc_checking_assert (is_valid ()); return 
m_base + m_size; }
 
   value_type &front ();
   value_type &back ();


[gcc r16-49] except: Don't use the cached value of the gcc_except_table section for comdat functions [PR119507]

2025-04-21 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:49926c2c657dd867f7329df6e250913fd1425475

commit r16-49-g49926c2c657dd867f7329df6e250913fd1425475
Author: Andrew Pinski 
Date:   Fri Mar 28 17:25:56 2025 -0700

except: Don't use the cached value of the gcc_except_table section for 
comdat functions [PR119507]

This has been broken since GCC started to put the comdat functions' 
gcc_except_table into their
own section; r0-118218-g3e6011cfebedfb. What would happen is after a 
non-comdat function is processed,
the cached value would always be used even for comdat function. Instead we 
should create a new
section for comdat functions.

OK? Bootstrapped and tested on x86_64-linux-gnu.

PR middle-end/119507

gcc/ChangeLog:

* except.cc (switch_to_exception_section): Don't use the cached 
section if
the current function is in comdat.

gcc/testsuite/ChangeLog:

* g++.dg/eh/pr119507.C: New test.

Signed-off-by: Andrew Pinski 

Diff:
---
 gcc/except.cc  |  9 -
 gcc/testsuite/g++.dg/eh/pr119507.C | 17 +
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/gcc/except.cc b/gcc/except.cc
index 205811c65673..0fe1e0934891 100644
--- a/gcc/except.cc
+++ b/gcc/except.cc
@@ -2949,7 +2949,14 @@ switch_to_exception_section (const char * ARG_UNUSED 
(fnname))
 {
   section *s;
 
-  if (exception_section)
+  if (exception_section
+  /* Don't use the cached section for comdat if it will be different. */
+#ifdef HAVE_LD_EH_GC_SECTIONS
+  && !(targetm_common.have_named_sections
+  && DECL_COMDAT_GROUP (current_function_decl)
+  && HAVE_COMDAT_GROUP)
+#endif
+ )
 s = exception_section;
   else
 {
diff --git a/gcc/testsuite/g++.dg/eh/pr119507.C 
b/gcc/testsuite/g++.dg/eh/pr119507.C
new file mode 100644
index ..50afa75a43f8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/pr119507.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target comdat_group } }
+// Force off function sections
+// Force on exceptions
+// { dg-options "-fno-function-sections -fexceptions" }
+// PR middle-end/119507
+
+
+inline int comdat() { try { throw 1; } catch (int) { return 1; } return 0; }
+int another_func_with_exception() { try { throw 1; } catch (int) { return 1; } 
return 0; }
+inline int comdat1() { try { throw 1; } catch (int) { return 1; } return 0; }
+int foo() { return comdat() + comdat1(); }
+
+// Make sure the gcc puts the exception table for both comdat and comdat1 in 
their own section
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table._Z6comdatv" 1 } }
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table._Z7comdat1v" 1 } }
+// There should be 3 exception tables, 
+// { dg-final { scan-assembler-times ".section\[\t 
\]\[^\n\]*.gcc_except_table" 3 } }


[gcc r16-51] [PATCH 30/61] MSA: Make MSA and microMIPS R5 unsupported

2025-04-21 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:727a43e0a66052235706379239359807230054e0

commit r16-51-g727a43e0a66052235706379239359807230054e0
Author: Matthew Fortune 
Date:   Mon Apr 21 09:49:58 2025 -0600

[PATCH 30/61] MSA: Make MSA and microMIPS R5 unsupported

There are no platforms nor simulators for MSA and microMIPS R5 so
turning off this support for now.

gcc/ChangeLog:

* config/mips/mips.cc (mips_option_override): Error out for
-mmicromips -mmsa.

Diff:
---
 gcc/config/mips/mips.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 24a28dcf817f..0d3d0263f2d4 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -20678,6 +20678,9 @@ mips_option_override (void)
  "-mcompact-branches=never");
 }
 
+  if (is_micromips && TARGET_MSA)
+error ("unsupported combination: %s", "-mmicromips -mmsa");
+
   /* Require explicit relocs for MIPS R6 onwards.  This enables simplification
  of the compact branch and jump support through the backend.  */
   if (!TARGET_EXPLICIT_RELOCS && mips_isa_rev >= 6)


[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: c++ version, propagate dead phis

2025-04-21 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:65a8a2615bb6057578feb2f8760b7841ffebd787

commit 65a8a2615bb6057578feb2f8760b7841ffebd787
Author: Ondřej Machota 
Date:   Mon Apr 21 22:47:07 2025 +0200

rtl-ssa-dce: c++ version, propagate dead phis

Diff:
---
 gcc/dce.cc | 482 -
 1 file changed, 449 insertions(+), 33 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index c626d19f0747..0a210b008e41 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1347,7 +1347,30 @@ struct offset_bitmap {
 }
 };
 
-bool is_rtx_prelive(const_rtx insn) {
+class rtl_ssa_dce
+{
+public:
+  unsigned int execute (function *);
+
+private:
+  bool is_rtx_body_prelive(const_rtx);
+  bool can_delete_call(const_rtx);
+  bool is_rtx_prelive(const_rtx);
+  bool is_prelive(insn_info *);
+  void mark_prelive_insn(insn_info *, auto_vec&);
+  auto_vec mark_prelive();
+  void mark();
+  // void propagate_dead_phis();
+  void reset_dead_debug_insn(insn_info *);
+  void reset_dead_debug();
+  void sweep();
+
+  std::unordered_set m_marked;
+  std::unordered_set m_marked_phis;
+};
+
+bool
+rtl_ssa_dce::is_rtx_body_prelive(const_rtx insn) {
   switch (GET_CODE(insn)) {
 case PREFETCH:
 case UNSPEC:
@@ -1359,7 +1382,35 @@ bool is_rtx_prelive(const_rtx insn) {
   }
 }
 
-bool is_rtx_insn_prelive(rtx_insn *insn) {
+bool
+rtl_ssa_dce::can_delete_call (const_rtx insn)
+{
+  if (cfun->can_delete_dead_exceptions)
+return true;
+  if (!insn_nothrow_p (insn))
+return false;
+  // if (can_alter_cfg)
+  return true;
+
+  // UD_DCE ignores this and works...
+  /* If we can't alter cfg, even when the call can't throw exceptions, it
+ might have EDGE_ABNORMAL_CALL edges and so we shouldn't delete such
+ calls.  */
+  // gcc_assert (CALL_P (insn));
+  // if (BLOCK_FOR_INSN (insn) && BB_END (BLOCK_FOR_INSN (insn)) == insn)
+  //   {
+  // edge e;
+  // edge_iterator ei;
+
+  // FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
+   // if ((e->flags & EDGE_ABNORMAL_CALL) != 0)
+   //   return false;
+  //   }
+  // return true;
+}
+
+bool
+rtl_ssa_dce::is_rtx_prelive(const_rtx insn) {
   gcc_assert(insn != nullptr);
 
   if (CALL_P (insn)
@@ -1381,8 +1432,8 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
   gcc_assert(GET_CODE(insn) == INSN);
 
   /* Don't delete insns that may throw if we cannot do so.  */
-  if (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn))
-  return true;
+  if (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn)  && 
can_alter_cfg)
+return true;
  
   /* Callee-save restores are needed.  */
   if (RTX_FRAME_RELATED_P (insn) && crtl->shrink_wrapped_separate 
@@ -1391,11 +1442,301 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
 
   rtx body = PATTERN(insn);
   switch (GET_CODE(body)) {
+// Clobbers are handled inside is_prelive
 case CLOBBER: // gcc/gcc/testsuite/gcc.c-torture/compile/2605-1.c
 case USE:
 case VAR_LOCATION:
   return true;
 
+case PARALLEL:
+  for (int i = XVECLEN (body, 0) - 1; i >= 0; i--)
+if (is_rtx_body_prelive (XVECEXP (body, 0, i)))
+  return true;
+  return false;
+
+default:
+  return is_rtx_body_prelive (body);
+  }
+}
+
+bool
+rtl_ssa_dce::is_prelive(insn_info *insn) {
+  // Phi insns and debug insns are never prelive, bb head and end contain 
+  // artificial uses that we need to mark as prelive
+  if (insn->is_bb_head() || insn->is_bb_end())
+return true;
+
+  if (insn->is_artificial() || insn->is_debug_insn())
+return false;
+
+  gcc_assert (insn->is_real());
+  for (def_info *def : insn->defs()) {
+// The purpose of this pass is not to eliminate memory stores...
+if (def->is_mem())
+  return true;
+
+gcc_assert(def->is_reg());
+
+/* gcc.c-torture/execute/2503-1.c - flags register is unused. Not all
+   hard registers should be marked... */
+ 
+/* this ignores clobbers, which is probably fine */
+if (def->kind() == access_kind::CLOBBER)
+  return true;
+
+gcc_assert (def->kind() == access_kind::SET);
+
+/* needed by gcc.c-torture/execute/pr51447.c */
+if (HARD_REGISTER_NUM_P (def->regno())
+&& global_regs[def->regno()])
+  return true;
+
+unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
+if (picreg != INVALID_REGNUM
+&& fixed_regs[picreg]
+&& def->regno() == picreg)
+  return true;
+  }
+
+  return is_rtx_prelive(insn->rtl());
+}
+
+void
+rtl_ssa_dce::mark_prelive_insn(insn_info *insn, auto_vec 
&worklist) {
+  if (dump_file)
+fprintf(dump_file, "Insn %d marked as prelive\n", insn->uid());
+
+  m_marked.emplace(insn);
+  for (use_info *use : insn->uses()) {
+set_info* set = use->def();
+if (set)
+  worklist.safe_push(set);
+  }
+}
+
+auto_vec
+rtl_ssa_dce::mark_prelive() {
+  if (dump_file)
+fprintf(dump_file, "DCE: prelive phase\n");
+
+  auto_vec worklist;
+  for (insn_info *insn : crtl->ssa->all_insns()) {
+if (is_prelive(

[gcc r16-56] c++: new size folding [PR118775]

2025-04-21 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:e7523a40cb1787d52a638cf8a4f9eeb5212f770f

commit r16-56-ge7523a40cb1787d52a638cf8a4f9eeb5212f770f
Author: Jason Merrill 
Date:   Sun Apr 20 12:31:35 2025 -0400

c++: new size folding [PR118775]

r15-7893 added a workaround for a case where we weren't registering (long)&a
as invalid in a constant-expression, because build_new_1 had folded away the
CONVERT_EXPR that we rely on to diagnose that problem.  In general we want
to defer most folding until cp_fold_function, so let's fold less here.  We
mainly want to expose constant size so we can treat it differently, and we
already did any constexpr evaluation when initializing cst_outer_nelts, so
fold_to_constant seems like the right choice.

PR c++/118775

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_call_expression): Add assert.
(fold_to_constant): Handle processing_template_decl.
* init.cc (build_new_1): Use fold_to_constant.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/constexpr-new24.C: Adjust diagnostic.

Diff:
---
 gcc/cp/constexpr.cc  | 10 ++
 gcc/cp/init.cc   |  4 ++--
 gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C |  4 ++--
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index be73e707aaf4..79b7d02f8770 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -2956,12 +2956,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, 
tree t,
  gcc_assert (arg0);
  if (new_op_p)
{
- /* FIXME: We should not get here; the VERIFY_CONSTANT above
-should have already caught it.  But currently a conversion
-from pointer type to arithmetic type is only considered
-non-constant for CONVERT_EXPRs, not NOP_EXPRs.  */
  if (!tree_fits_uhwi_p (arg0))
{
+ /* We should not get here; the VERIFY_CONSTANT above
+should have already caught it.  */
+ gcc_checking_assert (false);
  if (!ctx->quiet)
error_at (loc, "cannot allocate array: size not constant");
  *non_constant_p = true;
@@ -9490,6 +9489,9 @@ fold_simple (tree t)
 tree
 fold_to_constant (tree t)
 {
+  if (processing_template_decl)
+return t;
+
   tree r = fold (t);
   if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
 return r;
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index e589e45e8916..062a4938a44c 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3405,7 +3405,7 @@ build_new_1 (vec **placement, tree type, 
tree nelts,
errval = throw_bad_array_new_length ();
   if (outer_nelts_check != NULL_TREE)
size = build3 (COND_EXPR, sizetype, outer_nelts_check, size, errval);
-  size = cp_fully_fold (size);
+  size = fold_to_constant (size);
   /* Create the argument list.  */
   vec_safe_insert (*placement, 0, size);
   /* Do name-lookup to find the appropriate operator.  */
@@ -3462,7 +3462,7 @@ build_new_1 (vec **placement, tree type, 
tree nelts,
outer_nelts_check = NULL_TREE;
}
 
-  size = cp_fully_fold (size);
+  size = fold_to_constant (size);
   /* If size is zero e.g. due to type having zero size, try to
 preserve outer_nelts for constant expression evaluation
 purposes.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
index ee62f18922c5..17c9f548d987 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
@@ -6,14 +6,14 @@ int a;
 constexpr char *
 f1 ()
 {
-  constexpr auto p = new char[(long int) &a]; // { dg-error "size not 
constant" }
+  constexpr auto p = new char[(long int) &a]; // { dg-error "conversion from 
pointer" }
   return p;
 }
 
 constexpr char *
 f2 ()
 {
-  auto p = new char[(long int) &a];  // { dg-error "size not constant" }
+  auto p = new char[(long int) &a];  // { dg-error "conversion from pointer" }
   return p;
 }


[gcc r16-55] c++: static constexpr strictness [PR99456]

2025-04-21 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:e6ae0de72ef696c4016cc66c53a4aa49a1e900a6

commit r16-55-ge6ae0de72ef696c4016cc66c53a4aa49a1e900a6
Author: Jason Merrill 
Date:   Wed Mar 5 16:42:32 2025 -0500

c++: static constexpr strictness [PR99456]

r11-7740 limited constexpr rejection of conversion from pointer to integer
to manifestly constant-evaluated contexts; it should instead check whether
we're in strict mode.

The comment for that commit noted that making this change regressed other
tests, which turned out to be because maybe_constant_init_1 was not being
properly strict for variables declared constexpr/constinit.

PR c++/99456

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_constant_expression): Check strict
instead of manifestly_const_eval.
(maybe_constant_init_1): Be strict for static constexpr vars.

Diff:
---
 gcc/cp/constexpr.cc | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index f56c5c42c821..be73e707aaf4 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8479,7 +8479,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, 
tree t,
if (TREE_CODE (t) == CONVERT_EXPR
&& ARITHMETIC_TYPE_P (type)
&& INDIRECT_TYPE_P (TREE_TYPE (op))
-   && ctx->manifestly_const_eval == mce_true)
+   && ctx->strict)
  {
if (!ctx->quiet)
  error_at (loc,
@@ -9747,16 +9747,26 @@ maybe_constant_init_1 (tree t, tree decl, bool 
allow_non_constant,
 {
   /* [basic.start.static] allows constant-initialization of variables with
 static or thread storage duration even if it isn't required, but we
-shouldn't bend the rules the same way for automatic variables.  */
+shouldn't bend the rules the same way for automatic variables.
+
+But still enforce the requirements of constexpr/constinit.
+[dcl.constinit] "If a variable declared with the constinit specifier
+has dynamic initialization, the program is ill-formed, even if the
+implementation would perform that initialization as a static
+initialization."  */
   bool is_static = (decl && DECL_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
+  bool strict = (!is_static
+|| (decl && DECL_P (decl)
+&& (DECL_DECLARED_CONSTEXPR_P (decl)
+|| DECL_DECLARED_CONSTINIT_P (decl;
   if (is_static)
manifestly_const_eval = mce_true;
 
   if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
return fold_to_constant (t);
 
-  t = cxx_eval_outermost_constant_expr (t, allow_non_constant, !is_static,
+  t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
manifestly_const_eval,
false, decl);
 }


[gcc r16-57] c++: reorder constexpr checks

2025-04-21 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:9ac98b5742ebce41d7da9fda10852a0bc958f1cb

commit r16-57-g9ac98b5742ebce41d7da9fda10852a0bc958f1cb
Author: Jason Merrill 
Date:   Tue Mar 11 11:16:26 2025 -0400

c++: reorder constexpr checks

My proposed change to stop setting TREE_STATIC on constexpr heap
pseudo-variables led to a diagnostic regression because we would get the
generic "not constant" diagnostic before the "allocated storage" diagnostic.
So let's move the generic verify_constant down a bit.

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_outermost_constant_expr): Move
verify_constant later.

Diff:
---
 gcc/cp/constexpr.cc | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 79b7d02f8770..8a11e6265f23 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9227,11 +9227,6 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
   if (r == void_node && !constexpr_dtor && ctx.ctor)
 r = ctx.ctor;
 
-  if (!constexpr_dtor)
-verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
-  else
-DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
-
   unsigned int i;
   tree cleanup;
   /* Evaluate the cleanups.  */
@@ -9250,15 +9245,6 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
   non_constant_p = true;
 }
 
-  if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
-{
-  if (!allow_non_constant)
-   error ("%qE is not a constant expression because it refers to "
-  "an incompletely initialized variable", t);
-  TREE_CONSTANT (r) = false;
-  non_constant_p = true;
-}
-
   if (!non_constant_p && cxx_dialect >= cxx20
   && !global_ctx.heap_vars.is_empty ())
 {
@@ -9315,6 +9301,21 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
   non_constant_p = true;
 }
 
+  if (!non_constant_p && !constexpr_dtor)
+verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
+
+  /* After verify_constant because reduced_constant_expression_p can unset
+ CONSTRUCTOR_NO_CLEARING.  */
+  if (!non_constant_p
+  && TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
+{
+  if (!allow_non_constant)
+   error ("%qE is not a constant expression because it refers to "
+  "an incompletely initialized variable", t);
+  TREE_CONSTANT (r) = false;
+  non_constant_p = true;
+}
+
   if (non_constant_p)
 /* If we saw something bad, go back to our argument.  The wrapping below is
only for the cases of TREE_CONSTANT argument or overflow.  */
@@ -9331,13 +9332,17 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
 
   if (non_constant_p && !allow_non_constant)
 return error_mark_node;
-  else if (constexpr_dtor)
-return r;
   else if (non_constant_p && TREE_CONSTANT (r))
 r = mark_non_constant (r);
   else if (non_constant_p)
 return t;
 
+  if (constexpr_dtor)
+{
+  DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
+  return r;
+}
+
   /* Check we are not trying to return the wrong type.  */
   if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
 {


[gcc r16-50] [PATCH 43/61] Disable ssa-dom-cse-2.c for MIPS lp64

2025-04-21 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:139e1949a6edf4b066d15e73c0e8c3eae1e7495d

commit r16-50-g139e1949a6edf4b066d15e73c0e8c3eae1e7495d
Author: Matthew Fortune 
Date:   Mon Apr 21 09:46:44 2025 -0600

[PATCH 43/61] Disable ssa-dom-cse-2.c for MIPS lp64

The optimisation to reduce the result to constant 28 still happens
but only much later in combine.

gcc/testsuite/
* gcc.dg/tree-ssa/ssa-dom-cse-2.c: Do not check output for
MIPS lp64 abi.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
index a879d3059714..6fa52f6fb9b4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
@@ -27,4 +27,4 @@ foo ()
but the loop reads only one element at a time, and DOM cannot resolve these.
The same happens on powerpc depending on the SIMD support available.  */
 
-/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* 
hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* 
sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } 
} } } } */
+/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* 
hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { mips*-*-* 
powerpc*-*-* sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! 
arm_neon } } } } } } } */


[gcc r16-52] [PATCH 08/61] Testsuite: Accept jrc for clear cache intrinsic

2025-04-21 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:7c48d3e49b5417bd26beea7eb832fa9ca5caf38e

commit r16-52-g7c48d3e49b5417bd26beea7eb832fa9ca5caf38e
Author: Matthew Fortune 
Date:   Mon Apr 21 09:53:49 2025 -0600

[PATCH 08/61] Testsuite: Accept jrc for clear cache intrinsic

Accept jrc for clear cache intrinsic.

gcc/testsuite
* gcc.target/mips/clear-cache-1.c: Also allow jrc.

Diff:
---
 gcc/testsuite/gcc.target/mips/clear-cache-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/mips/clear-cache-1.c 
b/gcc/testsuite/gcc.target/mips/clear-cache-1.c
index f1554f593dcd..cd11c665b939 100644
--- a/gcc/testsuite/gcc.target/mips/clear-cache-1.c
+++ b/gcc/testsuite/gcc.target/mips/clear-cache-1.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-msynci isa_rev>=2" } */
 /* { dg-final { scan-assembler "\tsynci\t" } } */
-/* { dg-final { scan-assembler "\tjr.hb\t" } } */
+/* { dg-final { scan-assembler "\tjrc?.hb\t" } } */
 /* { dg-final { scan-assembler-not "_flush_cache|mips_sync_icache|_cacheflush" 
} } */
 
 NOMIPS16 void f()


[gcc r16-53] [PATCH 21/61] Testsuite: Modify the gcc.dg/memcpy-4.c test

2025-04-21 Thread Jeff Law via Gcc-cvs
https://gcc.gnu.org/g:2d07e3687998f31dfc7a18cbf14f17096c599549

commit r16-53-g2d07e3687998f31dfc7a18cbf14f17096c599549
Author: Andrew Bennett 
Date:   Mon Apr 21 09:56:47 2025 -0600

[PATCH 21/61] Testsuite: Modify the gcc.dg/memcpy-4.c test

From: Andrew Bennett 

Firstly, remove the MIPS specific bit of the test.
Secondly, create a MIPS specific version in the gcc.target/mips.
This will only execute for a MIPS ISA less than R6.

Cherry-picked c8b051cdbb1d5b166293513b0360d3d67cf31eb9
from https://github.com/MIPS/gcc

gcc/testsuite
* gcc.dg/memcpy-4.c: Remove mips specific code.
* gcc.target/mips/memcpy-2.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/memcpy-4.c  |  7 +--
 gcc/testsuite/gcc.target/mips/memcpy-2.c | 12 
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/memcpy-4.c b/gcc/testsuite/gcc.dg/memcpy-4.c
index 4c726f0ad74d..b17b369c5c63 100644
--- a/gcc/testsuite/gcc.dg/memcpy-4.c
+++ b/gcc/testsuite/gcc.dg/memcpy-4.c
@@ -1,13 +1,8 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-rtl-expand" } */
+/* { dg-options "-O2" } */
 
-#ifdef __mips
-__attribute__((nomips16))
-#endif
 void
 f1 (char *p)
 {
   __builtin_memcpy (p, "12345", 5);
 }
-
-/* { dg-final { scan-rtl-dump "mem/u.*mem/u" "expand" { target mips*-*-* } } } 
*/
diff --git a/gcc/testsuite/gcc.target/mips/memcpy-2.c 
b/gcc/testsuite/gcc.target/mips/memcpy-2.c
new file mode 100644
index ..df0cd18c2b2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/memcpy-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "isa_rev<=5 -fdump-rtl-expand" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-Os" } { "" } } */
+
+__attribute__((nomips16))
+void
+f1 (char *p)
+{
+  __builtin_memcpy (p, "12345", 5);
+}
+
+/* { dg-final { scan-rtl-dump "mem/u.*mem/u" "expand" } } */


[gcc r16-47] libgcobol: Check for struct tm tm_zone

2025-04-21 Thread Rainer Orth via Gcc-cvs
https://gcc.gnu.org/g:a619a128c992b2121a862b8470960ae751d25db6

commit r16-47-ga619a128c992b2121a862b8470960ae751d25db6
Author: Rainer Orth 
Date:   Mon Apr 21 15:59:14 2025 +0200

libgcobol: Check for struct tm tm_zone

intrinsic.cc doesn't compile on Solaris:

/vol/gcc/src/hg/master/cobol/libgcobol/intrinsic.cc: In function ‘void
__gg__formatted_current_date(cblc_field_t*, cblc_field_t*, std::size_t,
std::size_t)’:
/vol/gcc/src/hg/master/cobol/libgcobol/intrinsic.cc:1480:6: error: ‘struct
std::tm’ has no member named ‘tm_zone’; did you mean ‘tm_mon’?
 1480 |   tm.tm_zone = "GMT";
  |  ^~~
  |  tm_mon

struct tm.tm_zone is new in POSIX.1-2024, thus cannot be assumed to be
present universally.

This patch checks for its presence and guards the use accordingly.

Bootstrapped without regressions on amd64-pc-solaris2.11,
sparcv9-sun-solaris2.11, and x86_64-pc-solaris2.11.

2025-04-08  Rainer Orth  

libgcobol:
* configure.ac: Check for struct tm.tm_zone.
* configure, config.h.in: Regenerate.
* intrinsic.cc (__gg__formatted_current_date): Guard tm.tm_zone
use with HAVE_STRUCT_TM_TM_ZONE.

Diff:
---
 libgcobol/config.h.in  |  3 ++
 libgcobol/configure| 74 --
 libgcobol/configure.ac |  3 ++
 libgcobol/intrinsic.cc |  2 ++
 4 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in
index 6a5327996167..fdf5e3e7dc1c 100644
--- a/libgcobol/config.h.in
+++ b/libgcobol/config.h.in
@@ -72,6 +72,9 @@
 /* Define to 1 if you have the `strtof128' function. */
 #undef HAVE_STRTOF128
 
+/* Define to 1 if `tm_zone' is a member of `struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
 /* Define to 1 if you have the  header file. */
 #undef HAVE_SYS_STAT_H
 
diff --git a/libgcobol/configure b/libgcobol/configure
index e83119d48f62..6821591852af 100755
--- a/libgcobol/configure
+++ b/libgcobol/configure
@@ -2449,6 +2449,63 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_cxx_check_func
+
+# ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES
+# --
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_cxx_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+  { $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_member
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -11693,7 +11750,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11696 "configure"
+#line 11753 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11799,7 +11856,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11802 "configure"
+#line 11859 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17434,6 +17491,19 @@ $as_echo "#define USE_IEC_60559 1" >>confdefs.h
 
 
 
+# struct tm tm_zone is a POSIX.1-2024 addition.
+ac_fn_cxx_check_member "$LINENO" "struct tm" "tm_zone" 
"ac_cv_member_struct_tm_tm_zone" "#include 
+"
+if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TM_TM_ZONE 1
+_ACEOF
+
+
+fi
+
+
 if test "${multilib}" = "yes"; then
   multilib_arg="--enable-multilib"
 else
diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac
index a1e95139299e..4bb690559ad9 100644
--- a/libgcobol/configure.ac
+++ b/libgcobol/configure.ac
@@ -231,6 +231,9 @@ elif test "${ENABLE_LIBQUADMATH_SUPPORT}" = "default" ; then
 fi
 LIBGCOBOL_CHECK_FLOAT128
 
+# struct tm tm_zone is a POSIX.1

[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression transfer_simplify_11

2025-04-21 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d31f0a7e37df6d3ee164c86b0dcb27e70d66425a

commit d31f0a7e37df6d3ee164c86b0dcb27e70d66425a
Author: Mikael Morin 
Date:   Sun Apr 20 22:31:01 2025 +0200

Correction régression transfer_simplify_11

Diff:
---
 gcc/fortran/trans-array.cc | 26 --
 gcc/tree-ssa-loop-niter.cc |  3 ++-
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2fe00be9251f..652649953a24 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3516,8 +3516,8 @@ build_ptr_array_ref (tree data, tree offset)
 
 
 tree
-build_array_ref_dim (gfc_ss *ss, tree index, tree spacing,
-tree offset = NULL_TREE, bool tmp_array = false)
+build_array_ref_dim (gfc_ss *ss, tree index, tree lbound, tree spacing,
+bool tmp_array = false)
 {
   gfc_array_info *info = &ss->info->data.array;
 
@@ -3529,8 +3529,8 @@ build_array_ref_dim (gfc_ss *ss, tree index, tree spacing,
 || ss_type == GFC_SS_INTRINSIC
 || tmp_array
 || non_negative_strides_array_p (info->descriptor);
-  return gfc_build_array_ref (base, index, non_negative_stride, NULL_TREE,
- spacing, offset);
+  return gfc_build_array_ref (base, index, non_negative_stride, lbound,
+ spacing);
 }
 
 
@@ -3551,8 +3551,8 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref 
* ar, bool tmp_array =
   tree index = conv_array_index (se, ss, ss->dim[n], n, ar);
 
   gfc_array_info *info = &ss->info->data.array;
-  se->expr = build_array_ref_dim (ss, index, info->spacing[ss->dim[n]],
- info->offset, tmp_array);
+  se->expr = build_array_ref_dim (ss, index, info->lbound[ss->dim[n]],
+ info->spacing[ss->dim[n]], tmp_array);
 }
 
 
@@ -3761,7 +3761,7 @@ add_array_offset (stmtblock_t *pblock, gfc_loopinfo 
*loop, gfc_ss *ss,
 
   gfc_add_block_to_block (pblock, &se.pre);
 
-  tree tmp = build_array_ref_dim (ss, index, info->spacing[array_dim]);
+  tree tmp = build_array_ref_dim (ss, index, info->lbound[array_dim], 
info->spacing[array_dim]);
   tmp = gfc_build_addr_expr (NULL_TREE, tmp);
   tmp = fold_convert_loc (input_location, type, tmp);
   info->data = gfc_evaluate_now (tmp, pblock);
@@ -4155,7 +4155,7 @@ evaluate_bound (stmtblock_t *block, tree *bounds, 
gfc_expr ** values,
 
 
 static void
-conv_array_spacing (stmtblock_t * block, gfc_ss * ss, int dim)
+conv_array_lbound_spacing (stmtblock_t * block, gfc_ss * ss, int dim)
 {
   gfc_array_info *info;
 
@@ -4193,6 +4193,12 @@ conv_array_spacing (stmtblock_t * block, gfc_ss * ss, 
int dim)
 info->spacing[dim] = gfc_evaluate_now (value, block);
   else
 info->spacing[dim] = value;
+
+  value = gfc_conv_array_lbound (desc, dim);
+  if (save_value)
+info->lbound[dim] = gfc_evaluate_now (value, block);
+  else
+info->lbound[dim] = value;
 }
 
 
@@ -4505,13 +4511,13 @@ done:
  for (n = 0; n < ss->dimen; n++)
{
  gfc_conv_section_startstride (&outer_loop->pre, ss, ss->dim[n]);
- conv_array_spacing (&outer_loop->pre, ss, ss->dim[n]);
+ conv_array_lbound_spacing (&outer_loop->pre, ss, ss->dim[n]);
}
  if (loop->parent == nullptr)
for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
  if (info->subscript[n]
  && info->subscript[n]->info->type == GFC_SS_SCALAR)
-   conv_array_spacing (&outer_loop->pre, ss, n);
+   conv_array_lbound_spacing (&outer_loop->pre, ss, n);
  break;
 
case GFC_SS_INTRINSIC:
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 9ce881344142..0fa9388594bc 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -3926,7 +3926,8 @@ do_warn_aggressive_loop_optimizations (class loop *loop,
 known constant bound.  */
   || wi::cmpu (i_bound, wi::to_widest (loop->nb_iterations)) >= 0
   /* And undefined behavior happens unconditionally.  */
-  || !dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (stmt)))
+  || !dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (stmt))
+  || loop->latch == gimple_bb (stmt))
 return;
 
   edge e = single_exit (loop);


[gcc r16-54] Fix cost of vectorized double->float conversion

2025-04-21 Thread Jan Hubicka via Gcc-cvs
https://gcc.gnu.org/g:0907a810f586b07636cc5b83dba6025eb5240655

commit r16-54-g0907a810f586b07636cc5b83dba6025eb5240655
Author: Jan Hubicka 
Date:   Mon Apr 21 20:16:50 2025 +0200

Fix cost of vectorized double->float conversion

In previous patch I miscomputed costs of cvtpd2pf instruction
which mistakely gets accounted as 2 (VEC_PACK_TRUNC_EXPR).
Vectorizer can produce both, but when producing VEC_PACK_TRUNC_EXPR
it use promote_demote patch.  This patch thus simplifies
handling of NOP_EXPR since in that case we should always be producing
only one instruction.

PR target/119879
* config/i386/i386.cc (fp_conversion_stmt_cost): Inline to ...
(ix86_vector_costs::add_stmt_cost): ... here; fix handling of 
NOP_EXPR.

Diff:
---
 gcc/config/i386/i386.cc | 51 +
 1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 28603c2943ee..d15f91ddd2cb 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -25257,32 +25257,6 @@ ix86_vectorize_create_costs (vec_info *vinfo, bool 
costing_for_scalar)
   return new ix86_vector_costs (vinfo, costing_for_scalar);
 }
 
-/* Return cost of statement doing FP conversion.  */
-
-static unsigned
-fp_conversion_stmt_cost (machine_mode mode, gimple *stmt, bool scalar_p)
-{
-  int outer_size
-= tree_to_uhwi
-   (TYPE_SIZE
-   (TREE_TYPE (gimple_assign_lhs (stmt;
-  int inner_size
-= tree_to_uhwi
-   (TYPE_SIZE
-   (TREE_TYPE (gimple_assign_rhs1 (stmt;
-  int stmt_cost = vec_fp_conversion_cost
-   (ix86_tune_cost, GET_MODE_BITSIZE (mode));
-  /* VEC_PACK_TRUNC_EXPR: If inner size is greater than outer size we will end
- up doing two conversions and packing them.  */
-  if (!scalar_p && inner_size > outer_size)
-{
-  int n = inner_size / outer_size;
-  stmt_cost = stmt_cost * n
- + (n - 1) * ix86_vec_cost (mode, ix86_cost->sse_op);
-}
-  return stmt_cost;
-}
-
 unsigned
 ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
  stmt_vec_info stmt_info, slp_tree node,
@@ -25394,8 +25368,8 @@ ix86_vector_costs::add_stmt_cost (int count, 
vect_cost_for_stmt kind,
 TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt
stmt_cost = 0;
  else if (fp)
-   stmt_cost = fp_conversion_stmt_cost (mode, stmt_info->stmt,
-scalar_p);
+   stmt_cost = vec_fp_conversion_cost
+ (ix86_tune_cost, GET_MODE_BITSIZE (mode));
  break;
 
case BIT_IOR_EXPR:
@@ -25439,7 +25413,26 @@ ix86_vector_costs::add_stmt_cost (int count, 
vect_cost_for_stmt kind,
 
   if (kind == vec_promote_demote
   && fp && FLOAT_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt
-stmt_cost = fp_conversion_stmt_cost (mode, stmt_info->stmt, scalar_p);
+{
+  int outer_size
+   = tree_to_uhwi
+   (TYPE_SIZE
+   (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt;
+  int inner_size
+   = tree_to_uhwi
+   (TYPE_SIZE
+   (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt;
+  int stmt_cost = vec_fp_conversion_cost
+   (ix86_tune_cost, GET_MODE_BITSIZE (mode));
+  /* VEC_PACK_TRUNC_EXPR: If inner size is greater than outer size we will 
end
+up doing two conversions and packing them.  */
+  if (inner_size > outer_size)
+   {
+ int n = inner_size / outer_size;
+ stmt_cost = stmt_cost * n
+ + (n - 1) * ix86_vec_cost (mode, ix86_cost->sse_op);
+   }
+}
 
   /* If we do elementwise loads into a vector then we are bound by
  latency and execution resources for the many scalar loads


[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régressions transfer_simplify_*

2025-04-21 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a7cdd9b8bc3e05431b7d7cbec12fc23344c28054

commit a7cdd9b8bc3e05431b7d7cbec12fc23344c28054
Author: Mikael Morin 
Date:   Mon Apr 21 17:27:45 2025 +0200

Correction régressions transfer_simplify_*

Diff:
---
 gcc/tree-ssa-loop-niter.cc |  7 ---
 gcc/tree.cc| 12 +++-
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 0fa9388594bc..9d352da8b2a0 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -3926,8 +3926,8 @@ do_warn_aggressive_loop_optimizations (class loop *loop,
 known constant bound.  */
   || wi::cmpu (i_bound, wi::to_widest (loop->nb_iterations)) >= 0
   /* And undefined behavior happens unconditionally.  */
-  || !dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (stmt))
-  || loop->latch == gimple_bb (stmt))
+  || !(dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (stmt))
+  || loop->latch == gimple_bb (stmt)))
 return;
 
   edge e = single_exit (loop);
@@ -4004,7 +4004,8 @@ record_estimate (class loop *loop, tree bound, const 
widest_int &i_bound,
 
   /* If statement is executed on every path to the loop latch, we can directly
  infer the upper bound on the # of iterations of the loop.  */
-  if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (at_stmt)))
+  if (!(dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (at_stmt)))
+   || loop->latch == gimple_bb (at_stmt))
 upper = false;
 
   /* Update the number of iteration estimates according to the bound.
diff --git a/gcc/tree.cc b/gcc/tree.cc
index eccfcc89da40..86e6515f9cee 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -13058,7 +13058,17 @@ array_ref_up_bound (tree exp)
   /* If there is a domain type and it has an upper bound, use it, substituting
  for a PLACEHOLDER_EXPR as needed.  */
   if (domain_type && TYPE_MAX_VALUE (domain_type))
-return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
+{
+  tree val = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), 
exp);
+  if (TREE_OPERAND (exp, 2))
+return fold_build2_loc (EXPR_LOCATION (exp), PLUS_EXPR,
+   TREE_TYPE (val), val,
+   fold_convert_loc (EXPR_LOCATION (exp),
+ TREE_TYPE (val),
+ TREE_OPERAND (exp, 2)));
+  else
+   return val;
+}
 
   /* Otherwise fail.  */
   return NULL_TREE;