Re: [PATCH] COBOL v3: 3/14 80K bld: config and build machinery

2025-03-17 Thread Andreas Schwab
On Mär 13 2025, James K. Lowden wrote:

> On Tue, 11 Mar 2025 11:18:22 +0100
> Andreas Schwab  wrote:
>
>> libgcobol/configure.tgt says it's supported on powerpc64le.
>
> Our intention, tell me if you disagree, is that cobol is enabled if
>
> 1.  --enable-languages=all, and
> 2.  the host and target are "known good", x86_64 or aarch64

But powerpc64le is known good as well.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


[PATCH v2] libstdc++: Add P1206R7 from_range members to ordered sets [PR111055]

2025-03-17 Thread Tomasz Kamiński
This is another piece of P1206R7, adding new members to std::set
and std::multiset.

PR libstdc++/111055

libstdc++-v3/ChangeLog:

* include/bits/stl_multiset.h: (inser_range)
(multiset(from_range_t, _Rg&&, const _Compare&, const _Alloc&))
(multiset(from_range_t, _Rg&&, const _Alloc&)): Define.
* include/bits/stl_set.h: (set(from_range_t, _Rg&&, const _Alloc&))
(set(from_range_t, _Rg&&, const _Compare&, const _Alloc&), 
insert_range):
Define.
* testsuite/23_containers/multiset/cons/from_range.cc: New test.
* testsuite/23_containers/multiset/modifiers/insert/insert_range.cc: 
New test.
* testsuite/23_containers/set/cons/from_range.cc: New test.
* testsuite/23_containers/set/modifiers/insert/insert_range.cc: New 
test.
---
 Added missing includes, replaced spaces with tabs.
 Tested on x86_64-linux without PCH. OK for trunk?

 libstdc++-v3/include/bits/stl_multiset.h  |  52 
 libstdc++-v3/include/bits/stl_set.h   |  55 
 .../23_containers/multiset/cons/from_range.cc | 118 ++
 .../multiset/modifiers/insert/insert_range.cc |  76 +++
 .../23_containers/set/cons/from_range.cc  | 117 +
 .../set/modifiers/insert/insert_range.cc  |  79 
 6 files changed, 497 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/23_containers/multiset/cons/from_range.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/insert_range.cc
 create mode 100644 libstdc++-v3/testsuite/23_containers/set/cons/from_range.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/set/modifiers/insert/insert_range.cc

diff --git a/libstdc++-v3/include/bits/stl_multiset.h 
b/libstdc++-v3/include/bits/stl_multiset.h
index 57caf6e8cc4..1d40ae01de3 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -60,6 +60,9 @@
 #if __cplusplus >= 201103L
 #include 
 #endif
+#if __glibcxx_ranges_to_container // C++ >= 23
+# include  // ranges::begin, ranges::distance etc.
+#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -271,6 +274,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
: _M_t(_Key_alloc_type(__a))
{ _M_t._M_insert_range_equal(__first, __last); }
 
+#if __glibcxx_ranges_to_container // C++ >= 23
+  /**
+   * @brief Builds a %set from a range.
+   * @since C++23
+   */
+  template<__detail::__container_compatible_range<_Key> _Rg>
+   multiset(from_range_t, _Rg&& __rg,
+const _Compare& __comp,
+const _Alloc& __a = _Alloc())
+   : _M_t(__comp, _Key_alloc_type(__a))
+   { insert_range(std::forward<_Rg>(__rg)); }
+
+  /// Allocator-extended range constructor.
+  template<__detail::__container_compatible_range<_Key> _Rg>
+   multiset(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
+   : _M_t(_Key_alloc_type(__a))
+   { insert_range(std::forward<_Rg>(__rg)); }
+#endif
+
   /**
*  The dtor only erases the elements, and note that if the elements
*  themselves are pointers, the pointed-to memory is not touched in any
@@ -566,6 +588,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   { this->insert(__l.begin(), __l.end()); }
 #endif
 
+#if __glibcxx_ranges_to_container // C++ >= 23
+  /**
+   *  @brief Inserts a range of elements.
+   *  @since C++23
+   *  @param  __rg An input range of elements that can be converted to
+   *   the list's value type.
+   */
+  template<__detail::__container_compatible_range<_Key> _Rg>
+   void
+   insert_range(_Rg&& __rg)
+   {
+ auto __first = ranges::begin(__rg);
+ const auto __last = ranges::end(__rg);
+ for (; __first != __last; ++__first)
+   _M_t._M_emplace_equal(*__first);
+   }
+#endif
+
+
 #ifdef __glibcxx_node_extract // >= C++17
   /// Extract a node.
   node_type
@@ -955,6 +996,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 multiset(initializer_list<_Key>, _Allocator)
 -> multiset<_Key, less<_Key>, _Allocator>;
 
+#if __glibcxx_ranges_to_container // C++ >= 23
+  template>,
+  __allocator_like _Alloc = std::allocator>>
+multiset(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
+  -> multiset, _Compare, _Alloc>;
+
+  template
+multiset(from_range_t, _Rg&&, _Alloc)
+  -> multiset, 
less>, _Alloc>;
+#endif
 #endif // deduction guides
 
   /**
diff --git a/libstdc++-v3/include/bits/stl_set.h 
b/libstdc++-v3/include/bits/stl_set.h
index f32323db368..2f9b2bbfb5f 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -60,6 +60,9 @@
 #if __cplusplus >= 201103L
 #include 
 #endif
+#if __glibcxx_ranges_to_container // C++ >= 23
+# include  // ranges::begin, ranges::distance etc.
+#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -275,6 +278,25 @@ _GLIBCXX_BEGI

Re: [PATCH] aarch64: remove SVE2 requirement from SME and diagnose it as unsupported

2025-03-17 Thread Andre Vieira (lists)

Thanks for the suggestions.

On 14/03/2025 21:43, Andrew Carlotti wrote:

On Thu, Mar 13, 2025 at 05:10:07PM +, Andre Vieira (lists) wrote:

Apologies for the delay, had been waiting on some other relevant patches to
go in to make sure we didn't break any valid existing behaviours. It should
all be working properly now. I think I've also addressed all your comments.
Most notable change is that it now uses the 'sorry' mechanism.

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


aarch64: remove SVE2 requirement from SME and diagnose it as unsupported


I find this line hard to understand, but I struggled to find a better wording
when you posted the first version.  I think something better would be:

  aarch64: Remove +sme -> +sve2 feature flag dependency

I prefer your subject line..



  We don't yet support SME without SVE2, so bail out with a 'sorry' if we
  encounter this configuration.

But using a slightly different text underneath.


...


diff --git a/gcc/config/aarch64/aarch64-option-extensions.def 
b/gcc/config/aarch64/aarch64-option-extensions.def
index 
aa8d315c240fbd25b49008b131cc09f04001eb80..8603836de01588b8db417289f842f911567288ea
 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -207,7 +207,7 @@ AARCH64_FMV_FEATURE("sve2-sm4", SVE_SM4, (SVE2_SM4))
  
  AARCH64_OPT_EXTENSION("sve2p1", SVE2p1, (SVE2), (), (), "sve2p1")
  
-AARCH64_OPT_FMV_EXTENSION("sme", SME, (BF16, SVE2), (), (), "sme")

+AARCH64_OPT_FMV_EXTENSION("sme", SME, (BF16, FCMA, F16FML), (), (), "sme")


Have you deliberately changed other dependenciesi?  As well as removing SVE and
SVE2 from +sme, this would also remove FP16 and add F16FML (which does
nothing by itself if FP16 isn't also enabled).


Didn't realize the dependency wasn't implied, even though +fp16fml 
implies +fp16, somewhat confusing... but I'm sure there's a good reason 
for it. I'll add F16 to the requires list thanks for spotting that.


  
  AARCH64_OPT_EXTENSION("memtag", MEMTAG, (), (), (), "")
  
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc

index 
36b65df50c57267d9c18e430665c411f1bf3cc24..c9f37bd70cbccef70f383f873c97b2be58c938dc
 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18886,6 +18886,9 @@ aarch64_override_options_internal (struct gcc_options 
*opts)
  SET_OPTION_IF_UNSET (opts, &global_options_set, param_fully_pipelined_fma,
 1);
  
+  if (TARGET_SME && !TARGET_SVE2)

+sorry ("no support for %qs without %qs", "sme", "sve2");
+
aarch64_override_options_after_change_1 (opts);
  }
  
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi

index 
4fbb4cda101ebd14891a3ad80aa5b1bc069b45c6..3754e468a05b3ae554b71adb4cf60068d5249507
 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -22068,7 +22068,8 @@ Enable the Pointer Authentication Extension.
  @item cssc
  Enable the Common Short Sequence Compression instructions.
  @item sme
-Enable the Scalable Matrix Extension.
+Enable the Scalable Matrix Extension.  This can only be used with the sve2
+extension.


How about "This is only supported when SVE2 is also enabled"?  I think that
would make it clearer that it's a lack of (gcc) support, not a fundamental
requirement.


Sure.



[PATCH v3] reassoc: Optimize CMP/XOR expressions [PR116860]

2025-03-17 Thread Konstantinos Eleftheriou
Testcases for match.pd patterns
`((a ^ b) & c) cmp d | a != b -> (0 cmp d | a != b)` and
`(a ^ b) cmp c | a != b -> (0 cmp c | a != b)` were failing on some targets,
like PowerPC.

This patch adds an implemenetation for the optimization in reassoc. Doing so,
we can now handle cases where the related conditions appear in an AND
expression too. Also, we can optimize cases where we have intermediate
expressions between the related ones in the AND/OR expression on some targets.
This is not handled on targets like PowerPC, where each condition of the
AND/OR expression is placed into a different basic block.

Bootstrapped/regtested on x86 and AArch64.

PR tree-optimization/116860

gcc/ChangeLog:

* tree-ssa-reassoc.cc (solve_expr): New function.
(find_terminal_nodes): New function.
(get_terminal_nodes): New function.
(optimize_cmp_xor_exprs): New function.
(optimize_range_tests): Call optimize_cmp_xor_exprs.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/fold-xor-and-or.c:
Remove logical-op-non-short-circuit=1.
* gcc.dg/tree-ssa/fold-xor-or.c: Likewise.
* gcc.dg/tree-ssa/fold-xor-and-or-2.c: New test.
* gcc.dg/tree-ssa/fold-xor-and.c: New test.
---
 .../gcc.dg/tree-ssa/fold-xor-and-or-2.c   |  59 +++
 .../gcc.dg/tree-ssa/fold-xor-and-or.c |   2 +-
 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and.c  |  55 +++
 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c   |   2 +-
 gcc/tree-ssa-reassoc.cc   | 354 ++
 5 files changed, 470 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c
new file mode 100644
index 000..eea44d616b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c
@@ -0,0 +1,59 @@
+/* This test is not working across all targets (e.g. it fails on PowerPC, 
+   because each condition of the AND/OR expression is placed into
+   a different basic block). Therefore, it is gated for x86-64 and AArch64,
+   where we know that it has to pass.  */
+/* { dg-do compile { target { aarch64-*-* x86_64-*-* } } } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+typedef unsigned long int uint64_t;
+
+int cmp1_or_inter(int d1, int d2, int d3) {
+  if (((d1 ^ d2) & 0xabcd) == 0 || d3 != 10 || d1 != d2)
+return 0;
+  return 1;
+}
+
+int cmp2_or_inter(int d1, int d2, int d3, int d4) {
+  if (((d1 ^ d2) & 0xabcd) == 0 || d3 != 10 || d1 != d2 || d4 == 11)
+return 0;
+  return 1;
+}
+
+int cmp1_and_inter(int d1, int d2, int d3) {
+  if (!(((d1 ^ d2) & 0xabcd) == 0) && d3 == 10 && d1 == d2)
+return 0;
+  return 1;
+}
+
+int cmp2_and_inter(int d1, int d2, int d3, int d4) {
+  if (!(((d1 ^ d2) & 0xabcd) == 0) && d3 == 10 && d1 == d2 && d4 != 11)
+return 0;
+  return 1;
+}
+
+int cmp1_or_inter_64(uint64_t d1, uint64_t d2, uint64_t d3) {
+  if (((d1 ^ d2) & 0xabcd) == 0 || d3 != 10 || d1 != d2)
+return 0;
+  return 1;
+}
+
+int cmp2_or_inter_64(uint64_t d1, uint64_t d2, uint64_t d3, uint64_t d4) {
+  if (((d1 ^ d2) & 0xabcd) == 0 || d3 != 10 || d1 != d2 || d4 == 11)
+return 0;
+  return 1;
+}
+
+int cmp1_and_inter_64(uint64_t d1, uint64_t d2, uint64_t d3) {
+  if (!(((d1 ^ d2) & 0xabcd) == 0) && d3 == 10 && d1 == d2)
+return 0;
+  return 1;
+}
+
+int cmp2_and_inter_64(uint64_t d1, uint64_t d2, uint64_t d3, uint64_t d4) {
+  if (!(((d1 ^ d2) & 0xabcd) == 0) && d3 == 10 && d1 == d2 && d4 != 11)
+return 0;
+  return 1;
+}
+
+/* The if should be removed, so the condition should not exist */
+/* { dg-final { scan-tree-dump-not "d1_\[0-9\]+.D. \\^ d2_\[0-9\]+.D." 
"optimized" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c 
b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
index 99e83d8e5aa..e5dc98e7541 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-optimized --param 
logical-op-non-short-circuit=1" } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
 
 typedef unsigned long int uint64_t;
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and.c 
b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and.c
new file mode 100644
index 000..558ba888553
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+typedef unsigned long int uint64_t;
+
+int cmp1(int d1, int d2) {
+  if (!((d1 ^ d2) == 0xabcd) && d1 == d2)
+return 0;
+  return 1;
+}
+
+int cmp2(int d1, int d2) {
+  if (d1 == d2 && !((d1 ^ d2) == 0xabcd))
+return 0;
+  return 1;
+}
+
+int cmp3(int d1, int d2) {
+  if (!(((d1 ^ d2) & 0xabcd) == 0) && d1 == d2)
+return 0;
+  re

[PATCH v2 04/18] Add microMIPS R6 support

2025-03-17 Thread Aleksandar Rakic
From: Andrew Bennett 

gcc/
* config/mips/constraints.md: Update ZC/ZD constraints for
microMIPS R6 9-bit offsets.
* config/mips/m6200.md: Add the m6200 architecture and
scheduler.
* config/mips/mips-cpus.def: Add the m6201 cpu.
* config/mips/mips-dsp.md: Add the dspr3 compact branch support.
* config/mips/mips-tables.opt: Add the m6201 architecture.
* config/mips/mips.cc:
(mips_rtx_cost_data): Add M6200 costs.
(mips_output_move): Add the DSP accumulator register for mtlo
and mflo if ISA doesn't support neither MULT nor MULTU.
(mips_set_fast_mult_zero_zero_p): Account for HI/LO part of DSP
accumulator registers.
(mips_avoid_hazard): Don't think short micromips instructions
are barriers. Some micromips insns have length of 2, but
unfortuantely 2/4 returns 0, so the routine incorrectly thinks
that the instruction is a barrier and does not reset the
fs_delay state. Use TARGET_FORBIDDEN_SLOTS to enable forbidden
slot filling.
(mips_option_override): Replace TARGET_MICROMIPS with
is_micromips. Prevent -mdsp and -mdspr2 with
-mmicromips -mips32r6. Add DSPr3 support.
(mips_conditional_register_usage): Check whether the hilo
calculcation is still ok for micromips instructions (account for
DSP accumulator registers).
* config/mips/mips.h:
(TARGET_MICROMIPS_R6): Define.
(TARGET_CPU_CPP_BUILTINS): Define __mips_dspr3 and
__mips_dsp_rev=3 if DSPr3 is used.
(MIPS_ISA_LEVEL_SPEC): Infer -mips32r6 from an march=m6201
argument.
(MIPS_ARCH_FLOAT_SPEC): Infer -msoft-float from an march=m6201
argument.
(MIPS_ISA_NAN2008_SPEC): Ensure micromips is always considered
NAN2008 for hard-float.
(MIPS_ASE_DSP_SPEC): Infer -mno-forbidden-slots for micromips r6
if -mforbidden-slots is not set.
(ISA_HAS_DELAY_SLOTS): Set to false for micromips r6 onwards.
(ISA_HAS_LWXS): LWXS removed for microMIPS R6.
(ASM_SPEC): Add placeholders that include the -mdspr3,
-mno-dspr3, and -mforbidden-slots options.
(CRT_CALL_STATIC_FUNCTION): Remove nop from the delay slot after
the branch.
* config/mips/mips.md (processor): Add m6200.
(m6200.md): Include.
(mulsidi3_32bit): Account for the micromips r6 DSP mult
instruction.
(mfhi_, mthi_):
Account for the DSP accumulator register.
(clear_cache): Fix micromips r6 issue with clear_hazard insn.
(clear_hazard_): Fix indentation.
(clear_hazard_ur6_, clear_hazard_r6_): New insn
patterns.
(*branch_fp_, *branch_fp_inverted_): Add umipsr6
compact branch support.
* config/mips/mips.opt (mdspr3): Add DSPr3 support.
(mforbidden-slots): Add undocumented command line option to
enable forbidden slot filling.
* config/mips/ml-img-elf: Add microMIPSr6 hard/soft float
support.
* config/mips/ml-img-linux: Likewise.
* config/mips/t-mips-multi: Add microMIPS R6 multilib configs.
* doc/invoke.texi (march): Add the m6201 processor.
* doc/md.texi (ZC): Update the constraint for microMIPS R6 9-bit
offsets.
* testsuite/gcc.target/mips/mips.exp: Remove -mno-dsp for r6.

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

Signed-off-by: Andrew Bennett 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/constraints.md |  33 ++--
 gcc/config/mips/m6200.md   | 229 +
 gcc/config/mips/mips-cpus.def  |   3 +
 gcc/config/mips/mips-dsp.md|  17 +-
 gcc/config/mips/mips-tables.opt|  49 +++---
 gcc/config/mips/mips.cc|  54 --
 gcc/config/mips/mips.h |  40 +++--
 gcc/config/mips/mips.md|  88 --
 gcc/config/mips/mips.opt   |   7 +
 gcc/config/mips/ml-img-elf |   4 +
 gcc/config/mips/ml-img-linux   |   4 +
 gcc/config/mips/t-mips-multi   |  43 +
 gcc/doc/invoke.texi|   2 +-
 gcc/doc/md.texi|  11 +-
 gcc/testsuite/gcc.target/mips/mips.exp |   1 -
 15 files changed, 498 insertions(+), 87 deletions(-)
 create mode 100644 gcc/config/mips/m6200.md

diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index a96028dd746..3b8fe9c3b70 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -368,25 +368,30 @@
(match_test "mips_const_vector_same_bytes_p (op, mode)")))
 
 (define_memory_constraint "ZC"
-  "A memory operand whose address is formed by a base register and offset
-   that is suitable for use in instructions with the same addressing mode
-   as @code{ll} and @code{sc}."
+  "When c

[PATCH v2 16/18] Inefficient 64-bit signed modulo by powers of two

2025-03-17 Thread Aleksandar Rakic
From: Mihailo Stojanovic 

This adds the custom MIPS-specific modulo by power of two expander,
which uses a modified algorithm, tailored to MIPS instruction set.

gcc/

* config/mips/mips-protos.h (mips_expand_mod_pow2): New prototype.
* config/mips/mips.cc (mips_rtx_costs): Don't force power of two
constants into registers during modulo operations. Modify the cost
modulo by power of two.
(mips_expand_mod_pow2): New expander for modulo by power of two of
64-bit values on 32-bit targets.
* config/mips/mips.md (define_expand "mod3"): Separate
define_expand for "mod3" from the define_insn and call the
new expander for 64-bit values on 32-bit targets.
(define_insn "*mod3"): Add * to the pattern name to avoid
clash with the define_expand pattern.

gcc/testsuite/

* gcc.target/mips/mod-pow2.c: New test.

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

Signed-off-by: Mihailo Stojanovic 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips-protos.h|   2 +
 gcc/config/mips/mips.cc  | 143 +-
 gcc/config/mips/mips.md  |  31 +++-
 gcc/testsuite/gcc.target/mips/mod-pow2.c | 176 +++
 4 files changed, 349 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/mod-pow2.c

diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 1ec6f386f5f..efe6aed5afe 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -399,4 +399,6 @@ extern void mips_bit_clear_info (enum machine_mode, 
unsigned HOST_WIDE_INT,
 
 extern const char *mips_output_compare (const char *fpcmp, const char *fcond,
const char *fmt, const char *fpcc_mode, bool swap);
+extern bool mips_expand_mod_pow2 (rtx, rtx, rtx);
+
 #endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index b1e687a0f31..247b3ebaea8 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -5141,6 +5141,19 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
  return true;
}
 
+  /* Don't force the constant into register during modulo by power of two.
+This is needed so that the MIPS-specific modulo pattern will be
+selected during the expand phase.  */
+  if (!TARGET_64BIT
+ && !TARGET_MIPS16
+ && outer_code == MOD
+ && mode == DImode
+ && (exact_log2 (INTVAL (x)) > 0))
+   {
+ *total = 0;
+ return true;
+   }
+
   if (TARGET_MIPS16)
{
  cost = mips16_constant_cost (outer_code, INTVAL (x));
@@ -5464,8 +5477,20 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
}
   /* Fall through.  */
 
-case SQRT:
 case MOD:
+  /* Modulo by power of two produces (at most) nine instructions.  */
+  if (CONST_INT_P (XEXP (x, 1))
+ && exact_log2 (INTVAL (XEXP (x, 1))) > 0
+ && !TARGET_64BIT
+ && !TARGET_MIPS16
+ && mode == DImode)
+   {
+ *total = COSTS_N_INSNS (9);
+ return true;
+   }
+  /* Fall through.  */
+
+case SQRT:
   if (float_mode_p)
{
  *total = mips_fp_div_cost (mode);
@@ -25033,6 +25058,122 @@ mips_noce_conversion_profitable_p (rtx_insn *seq, 
struct noce_if_info *if_info)
   return speed && cost <= if_info->max_seq_cost;
 }
 
+/* Expand modulo by power of two of DImode values on 32-bit targets.  */
+
+bool
+mips_expand_mod_pow2 (rtx target, rtx op1, rtx op2)
+{
+  HOST_WIDE_INT val, reg_width;
+  rtx out_low, out_high;
+  rtx in_low, in_high;
+  rtx at, temp;
+  rtx comp, cond_operands[4];
+
+  gcc_assert (GET_CODE (op2) == CONST_INT);
+
+  val = INTVAL (op2);
+
+  int logd = exact_log2 (val);
+
+  if (logd <= 0)
+return false;
+
+  /* Extract lower and upper words of DImode source and destination.  */
+  out_low = mips_subword (target, 0);
+  out_high = mips_subword (target, 1);
+
+  in_low = mips_subword (op1, 0);
+  in_high = mips_subword (op1, 1);
+
+  at = gen_reg_rtx (SImode);
+  temp = gen_reg_rtx (SImode);
+
+  reg_width = GET_MODE_BITSIZE (SImode);
+
+  /* Divisor equals 2.  */
+  if (logd == 1)
+{
+  mips_emit_binary (AND, at, in_low, const1_rtx);
+  mips_emit_binary (ASHIFT, temp, in_low,
+   gen_int_mode (reg_width - 1, SImode));
+  mips_emit_binary (AND, temp, in_high, temp);
+  mips_emit_binary (ASHIFTRT, out_high, temp,
+   gen_int_mode (reg_width - 1, SImode));
+  mips_emit_binary (IOR, out_low, out_high, at);
+
+  return true;
+}
+  /* Divisor fits into 32 bits.  */
+  else if (logd <= reg_width)
+{
+  mips_emit_binary (ASHIFTRT, at, in_high,
+   gen_int_mode (reg_width - 1, SImode));
+
+  if (logd == reg_width)
+   mips_emit_move (out_low, in_low);
+  else if (ISA

[PATCH v2 0/1] Improve inlining

2025-03-17 Thread Aleksandar Rakic
This patch series improves the inlining in GCC.

This patch is cherry-picked from the mips_rel/9_3_0/master branch
from the MIPS' repository:
https://github.com/MIPS/gcc .
Further details on the individual changes are included in the
respective patch.


[PATCH v2 10/10] nanoMIPS: unnecessary AND following an EXT

2025-03-17 Thread Aleksandar Rakic
From: "dragan.mladjenovic" 

The fwprop1 introduces a new use of Y by replacing the
(subreg:QI (reg:SI X)) with (reg:QI Y) preventing the optimization of
zero_extend later during the combine. This patch prevents this
replacement in two new cases.

 A: (set (subreg:SI (reg:QI Y))
 (zero_extract:SI Z (const_int 8) (const_int ?)))
 B: (set (reg:SI X) (zero_extend:SI (reg:QI Y)))
 C: (... (subreg:QI (reg:SI X)) ...)
 D: (... (reg:SI X) ...)

 A: (set (reg:SI Y)
 (zero_extract:SI Z (const_int 8) (const_int ?)))
 B: (set (reg:SI X) (zero_extend:SI (reg:QI Y)))
 C: (... (subreg:QI (reg:SI X)) ...)
 D: (... (reg:SI X) ...)

gcc/

* fwprop.cc (free_load_extend): Renamed to ...
  (free_extend): Handle zero/sign_extract sources.
  (forward_propagate_subreg): Use free_extend.

gcc/testsuite/

* gcc.target/mips/union-zext.c: New.

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

Signed-off-by: Dragan Mladjenovic 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/fwprop.cc  | 38 ++
 gcc/testsuite/gcc.target/mips/union-zext.c | 29 +
 2 files changed, 60 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/union-zext.c

diff --git a/gcc/fwprop.cc b/gcc/fwprop.cc
index 8cba6b7ce9f..717415a4fb6 100644
--- a/gcc/fwprop.cc
+++ b/gcc/fwprop.cc
@@ -614,15 +614,14 @@ try_fwprop_subst (use_info *use, set_info *def,
 
 /* For the given single_set INSN, containing SRC known to be a
ZERO_EXTEND or SIGN_EXTEND of a register, return true if INSN
-   is redundant due to the register being set by a LOAD_EXTEND_OP
-   load from memory.  */
+   is redundant due to the register being set by ZERO_EXTRACT or
+   SIGN_EXTRACT of appropriate size or by LOAD_EXTEND_OP load
+   from memory.  */
 
 static bool
-free_load_extend (rtx src, insn_info *insn)
+free_extend (rtx src, insn_info *insn)
 {
   rtx reg = XEXP (src, 0);
-  if (load_extend_op (GET_MODE (reg)) != GET_CODE (src))
-return false;
 
   def_info *def = nullptr;
   for (use_info *use : insn->uses ())
@@ -644,10 +643,35 @@ free_load_extend (rtx src, insn_info *insn)
 {
   rtx patt = PATTERN (def_rtl);
 
-  if (GET_CODE (patt) == SET
+  if (GET_CODE (patt) != SET)
+  return false;
+
+#ifdef LOAD_EXTEND_OP
+  if (LOAD_EXTEND_OP (GET_MODE (reg)) == GET_CODE (src)
  && GET_CODE (SET_SRC (patt)) == MEM
  && rtx_equal_p (SET_DEST (patt), reg))
return true;
+#endif
+
+  int extract_code = GET_CODE (src) == ZERO_EXTEND
+? ZERO_EXTRACT : SIGN_EXTRACT;
+
+  if (GET_CODE (SET_SRC (patt)) == extract_code
+&& GET_MODE (SET_SRC (patt)) == GET_MODE (src)
+ && INTVAL (XEXP (SET_SRC (patt), 1))
+<= GET_MODE_BITSIZE (GET_MODE (reg)).to_constant ())
+  {
+if (GET_CODE (SET_DEST (patt)) == SUBREG
+  && GET_MODE (SET_DEST (patt)) == GET_MODE (src)
+  && rtx_equal_p (XEXP (SET_DEST (patt), 0), reg))
+  return true;
+
+if (REG_P (SET_DEST (patt))
+  && GET_MODE (SET_DEST (patt)) == GET_MODE (src)
+  && REGNO (SET_DEST (patt)) == REGNO (reg))
+  return true;
+  }
+
 }
   return false;
 }
@@ -709,7 +733,7 @@ forward_propagate_subreg (use_info *use, set_info *def,
  && REG_P (XEXP (src, 0))
  && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
  && GET_MODE (XEXP (src, 0)) == use_mode
- && !free_load_extend (src, def->insn ())
+ && !free_extend (src, def->insn ())
  && (targetm.mode_rep_extended (int_use_mode, src_mode)
  != (int) GET_CODE (src)))
return try_fwprop_subst (use, def, loc, use_reg, XEXP (src, 0));
diff --git a/gcc/testsuite/gcc.target/mips/union-zext.c 
b/gcc/testsuite/gcc.target/mips/union-zext.c
new file mode 100644
index 000..7192ce4fa18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/union-zext.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "(HAS_INS) -mgp32" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-not "\tandi\t"} } */
+
+typedef struct bits
+{
+  unsigned B0:8, B1:8, B2:8, B3:8;
+} bits_t;
+
+typedef union
+{
+  unsigned v;
+  bits_t b;
+} bitfields_t;
+
+void *
+string_copy (void *__restrict__ dst, const void *__restrict__ _a)
+{
+  unsigned x = *(unsigned *) _a;
+  bitfields_t bx;
+  bx.v = x;
+
+  unsigned char v2 = (unsigned char) bx.b.B2;
+  ((unsigned char *) (dst))[2] = (v2);
+  if (v2 == 0)
+return 0;
+  return dst;
+}
-- 
2.34.1


[PATCH v2 4/4] Add uclibc support

2025-03-17 Thread Aleksandar Rakic
From: Jean Lee 

libsanitizer/
* asan/asan_descriptions.cpp (GetStackTraceFromId): Disable
stack unwind for uclibc on mips target.
* asan/asan_linux.cpp: Fix "ASan runtime does not come first in
initial library list; you should either link runtime to your
application or manually preload it with LD_PRELOAD."
* interception/interception_linux.cpp: Uclibc doesn't support
dlvsym.
* interception/interception_linux.h: Likewise.
* sanitizer_common/sanitizer_common.cpp: Resolve libsanitizer
build issues for uclibc.
* sanitizer_common/sanitizer_linux.cpp: Likewise.
(GetPageSize): Fix page size for uclibc on mips target.
* sanitizer_common/sanitizer_platform.h: Include features.h for
uclibc.
(SANITIZER_UCLIBC): Define macro.
* sanitizer_platform_interceptors.h: Disable
SANITIZER_INTERCEPT_GLOB, SANITIZER_INTERCEPT_GLOB64, and
SANITIZER_INTERCEPT_GETIFADDRS.
* sanitizer_platform_limits_posix.cpp: Resolve libsanitizer
build issues for uclibc.
* sanitizer_platform_limits_posix.h: Likewise.
* sanitizer_unwind_linux_libcdep.cpp
(BufferedStackTrace::UnwindSlow): Disable stack unwind for
uclibc on mips target.

Cherry-picked 94e7806991cf3af0dbaf6147d0010480a7760cc8,
52849bd97f29b6ad17d493ad383d8833473ee6a7,
0dcb2d0c3cc4d7118bd211a24e01d9a991dd72d2,
127b4d28d9bfba10e7006decdcd0f24665e5d5af,
5cd320103ba1248c6925b9843f1139e60d283bed and
af4425414cef0155d6f00ad118417f4908eae756
from https://github.com/MIPS/gcc

Signed-off-by: Jean Lee 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 libsanitizer/asan/asan_descriptions.cpp   |  5 ++
 libsanitizer/asan/asan_linux.cpp  |  2 +-
 .../interception/interception_linux.cpp   |  6 ++-
 .../interception/interception_linux.h |  6 ++-
 .../sanitizer_common/sanitizer_common.cpp | 10 +++-
 .../sanitizer_common/sanitizer_linux.cpp  |  6 ++-
 .../sanitizer_common/sanitizer_platform.h |  9 
 .../sanitizer_platform_interceptors.h | 14 --
 .../sanitizer_platform_limits_posix.cpp   | 46 +++
 .../sanitizer_platform_limits_posix.h |  9 +++-
 .../sanitizer_unwind_linux_libcdep.cpp|  2 +
 11 files changed, 93 insertions(+), 22 deletions(-)

diff --git a/libsanitizer/asan/asan_descriptions.cpp 
b/libsanitizer/asan/asan_descriptions.cpp
index caec79313e2..0b8180bbf0f 100644
--- a/libsanitizer/asan/asan_descriptions.cpp
+++ b/libsanitizer/asan/asan_descriptions.cpp
@@ -175,10 +175,15 @@ bool GetHeapAddressInformation(uptr addr, uptr 
access_size,
 }
 
 static StackTrace GetStackTraceFromId(u32 id) {
+#if !(defined(__mips__) && SANITIZER_UCLIBC)
   CHECK(id);
   StackTrace res = StackDepotGet(id);
   CHECK(res.trace);
   return res;
+#else
+  StackTrace res;
+  return res;
+#endif
 }
 
 bool DescribeAddressIfHeap(uptr addr, uptr access_size) {
diff --git a/libsanitizer/asan/asan_linux.cpp b/libsanitizer/asan/asan_linux.cpp
index 4cabca388ca..abcfb2467c9 100644
--- a/libsanitizer/asan/asan_linux.cpp
+++ b/libsanitizer/asan/asan_linux.cpp
@@ -107,7 +107,7 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
   ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
 }
 
-#  if SANITIZER_ANDROID
+#  if SANITIZER_ANDROID || SANITIZER_UCLIBC
 // FIXME: should we do anything for Android?
 void AsanCheckDynamicRTPrereqs() {}
 void AsanCheckIncompatibleRT() {}
diff --git a/libsanitizer/interception/interception_linux.cpp 
b/libsanitizer/interception/interception_linux.cpp
index ef8136eb4fc..ed8bd3a80b9 100644
--- a/libsanitizer/interception/interception_linux.cpp
+++ b/libsanitizer/interception/interception_linux.cpp
@@ -64,7 +64,8 @@ bool InterceptFunction(const char *name, uptr *ptr_to_real, 
uptr func,
 }
 
 // dlvsym is a GNU extension supported by some other platforms.
-#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if (SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD) && \
+!SANITIZER_UCLIBC
 static void *GetFuncAddr(const char *name, const char *ver) {
   return dlvsym(RTLD_NEXT, name, ver);
 }
@@ -75,7 +76,8 @@ bool InterceptFunction(const char *name, const char *ver, 
uptr *ptr_to_real,
   *ptr_to_real = (uptr)addr;
   return addr && (func == trampoline);
 }
-#  endif  // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
+#  endif  // (SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD) &&
+ // !SANITIZER_UCLIBC
 
 }  // namespace __interception
 
diff --git a/libsanitizer/interception/interception_linux.h 
b/libsanitizer/interception/interception_linux.h
index 2e01ff44578..897ec677350 100644
--- a/libsanitizer/interception/interception_linux.h
+++ b/libsanitizer/interception/interception_linux.h
@@ -38,7 +38,8 @@ bool InterceptFunction(const char *name, const char *ver, 
uptr *ptr_to_real,
   (::__interception::uptr) &TRAMPOLINE(func))
 

[PATCH v3 1/2] Aarch64: Add FMA and FMAF intrinsic and corresponding tests

2025-03-17 Thread Ayan Shafqat
This patch introduces inline definitions for the __fma and __fmaf
functions in arm_acle.h for Aarch64 targets. These definitions rely on
__builtin_fma and __builtin_fmaf to ensure proper inlining and to meet
the ACLE requirements [1].

The patch has been tested locally using a crosstool-NG sysroot for
Aarch64, confirming that the generated code uses the expected fused
multiply-accumulate instructions (fmadd).

[1] 
https://arm-software.github.io/acle/main/acle.html#fused-multiply-accumulate-fma

gcc/ChangeLog:

* config/aarch64/arm_acle.h (__fma, __fmaf): New functions.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/acle/acle_fma.c: New test.
---
 gcc/config/aarch64/arm_acle.h | 14 ++
 .../gcc.target/aarch64/acle/acle_fma.c| 19 +++
 2 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/acle_fma.c

diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 7976c117daf..d9e2401ea9f 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -129,6 +129,20 @@ __jcvt (double __a)
 
 #pragma GCC pop_options
 
+__extension__ extern __inline double
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__fma (double __x, double __y, double __z)
+{
+  return __builtin_fma (__x, __y, __z);
+}
+
+__extension__ extern __inline float
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__fmaf (float __x, float __y, float __z)
+{
+  return __builtin_fmaf (__x, __y, __z);
+}
+
 #pragma GCC push_options
 #pragma GCC target ("+nothing+frintts")
 __extension__ extern __inline float
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/acle_fma.c 
b/gcc/testsuite/gcc.target/aarch64/acle/acle_fma.c
new file mode 100644
index 000..d7986caba31
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/acle_fma.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include "arm_acle.h"
+
+double
+test_acle_fma (double x, double y, double z)
+{
+  return __fma (x, y, z);
+}
+
+float
+test_acle_fmaf (float x, float y, float z)
+{
+  return __fmaf (x, y, z);
+}
+
+/* { dg-final { scan-assembler-times "fmadd\td\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fmadd\ts\[0-9\]" 1 } } */
-- 
2.43.0



[PATCH v2 05/10] P5600: Option -msched-weight added

2025-03-17 Thread Aleksandar Rakic
From: Jaydeep Patil 

Fix negative offset memory addressing. Unconditionally set
DONT_BREAK_DEPENDENCIES in scheduling flags. The code to break
dependencies does not appear to provide a win under any circumstance and
is often harmful. Disable it completely pending further investigation.

gcc/
* config/mips/mips.cc (level, consumer_luid): New static global
variables.
(LEVEL, CONSUMER_LUID): New macros.
(find_reg_born): New static function.
(get_weight): Likewise.
(mips_weight_init_global): Likewise.
(mips_sched_init_global): Likewise.
(mips_weight_evaluation): Likewise.
(mips_evaluation_hook): Likewise.
(mips_set_sched_flags): Likewise. Fix negative offset memory
addressing. Unconditionally set DONT_BREAK_DEPENDENCIES in
scheduling flags. The code to break dependencies does not appear
to provide a win under any circumstance and is often harmful.
Disable it completely pending further investigation.
(mips_weight_finish_global): New static function.
(mips_sched_finish_global): Likewise.
(mips_sched_weight): Likewise.
(mips_sched_reorder_1): Call mips_sched_weight.
(TARGET_SCHED_INIT_GLOBAL, TARGET_SCHED_FINISH_GLOBAL,
TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK,
TARGET_SCHED_SET_SCHED_FLAGS): New macros.
* config/mips/mips.opt (-msched-weight): New option.

Cherry-picked 0cf2542b41d8102800af180f0b6da1fe55a9d76b,
and f732af3ad1a393d2f2e708f0d7c469a093049d01
from https://github.com/MIPS/gcc

Signed-off-by: Matthew Fortune 
Signed-off-by: Prachi Godbole 
Signed-off-by: Jaydeep Patil 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.cc  | 239 +++
 gcc/config/mips/mips.opt |   3 +
 2 files changed, 242 insertions(+)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 59781ac7077..894baa2b7a1 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -74,6 +74,17 @@ along with GCC; see the file COPYING3.  If not see
 /* This file should be included last.  */
 #include "target-def.h"
 
+/* Definitions used in ready queue reordering for first scheduling pass.  */
+
+static int *level = NULL;
+static int *consumer_luid = NULL;
+
+#define LEVEL(INSN)\
+  level[INSN_UID ((INSN))]
+
+#define CONSUMER_LUID(INSN)\
+  consumer_luid[INSN_UID ((INSN))]
+
 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
 #define UNSPEC_ADDRESS_P(X)\
   (GET_CODE (X) == UNSPEC  \
@@ -15540,6 +15551,217 @@ mips_74k_agen_reorder (rtx_insn **ready, int nready)
   break;
 }
 }
+
+/* These functions are called when -msched-weight is set.  */
+
+/* Find register born in given X if any.  */
+
+static int
+find_reg_born (rtx x)
+{
+  if (GET_CODE (x) == CLOBBER)
+return 1;
+
+  if (GET_CODE (x) == SET)
+{
+  if (REG_P (SET_DEST (x)) && reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
+   return 0;
+  return 1;
+}
+  return 0;
+}
+
+/* Calculate register weight for given INSN.  */
+
+static int
+get_weight (rtx insn)
+{
+  int weight = 0;
+  rtx x;
+
+  /* Increment weight for each register born here.  */
+  x = PATTERN (insn);
+  weight = find_reg_born (x);
+
+  if (GET_CODE (x) == PARALLEL)
+{
+  int i;
+  for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+   {
+ x = XVECEXP (PATTERN (insn), 0, i);
+ weight += find_reg_born (x);
+   }
+}
+
+  /* Decrement weight for each register that dies here.  */
+  for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
+{
+  if (REG_NOTE_KIND (x) == REG_DEAD || REG_NOTE_KIND (x) == REG_UNUSED)
+   {
+ rtx note = XEXP (x, 0);
+ if (REG_P (note))
+   weight--;
+   }
+}
+  return weight;
+}
+
+/* TARGET_SCHED_WEIGHT helper function.
+   Allocate and initialize global data.  */
+
+static void
+mips_weight_init_global (int old_max_uid)
+{
+  level = (int *) xcalloc (old_max_uid, sizeof (int));
+  consumer_luid = (int *) xcalloc (old_max_uid, sizeof (int));
+}
+
+/* Implement TARGET_SCHED_INIT_GLOBAL.  */
+
+static void
+mips_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
+   int verbose ATTRIBUTE_UNUSED,
+   int old_max_uid)
+{
+  if (!reload_completed && TARGET_SCHED_WEIGHT)
+mips_weight_init_global (old_max_uid);
+}
+
+/* TARGET_SCHED_WEIGHT helper function.  Called for each basic block
+   with dependency chain information in HEAD and TAIL.
+   Calculates LEVEL for each INSN from its forward dependencies
+   and finds out UID of first consumer instruction (CONSUMER_LUID) of INSN.  */
+
+static void
+mips_weight_evaluation (rtx_insn *head, rtx_insn *tail)
+{
+  sd_iterator_def sd_it;
+  dep_t dep;
+  rtx_insn *prev_head, *insn;
+  rtx x;
+  prev_head = PREV_INSN (head);
+
+  for (insn = tail; insn != 

[PATCH v2 08/18] Add -mfunc-opt-list=

2025-03-17 Thread Aleksandar Rakic
From: Simon Dardis 

New option for MIPS -mfunc-opt-list=FILE. This option takes a file which
has one function per line followed by a whitespace (space/tab) followed
by one or more attributes. Supported attributes are O2, Os,
code-read=pcrel, always_inline, noinline, mips16, nomips16, epi,
longcall.

Attributes are applied to functions that the compiler sees, so functions
listed that the compiler doesn't see are ignored.

Now understands the majority of function attributes. These are:
O1, O2, O3, Os, mips16, nomips16, always_inline, noinline, unused, used,
far, near, hot, cold, code_readable, alias, aligned, alloc_size,
alloc_align, assume_aligned, artifical, constructor, const, deprecated,
destructor, error, flatten, gnu_inline, interrupt,
keep_interrupts_masked, long_call, leaf, noclone, noreturn, malloc,
nonnull, nothrow, optimize, returns_nonnull, returns_twice, section,
pure, use_debug_exception_return, use_shadow_register_set, visibility,
warning, warn_unused_result, weak, weakref.

Syntax of attributes that take arguments is like: alias ("O2")
or nonnull (1,2)

Attach unknown attributes anyway.

gcc/
* config/mips/mips.cc (mips_func_opt_list_arg_t,
mips_fol_collides): New enum.
(attr_desc): New struct.
(mips_func_opt_list_strings): New static global variable.
(mips_func_opt_list_arg): New struct.
(mips_func_opt_unknown_list): Likewise.
(mips_func_opt_list): Likewise.
(mips_fn_opt_list): New static global variable.
(mips_func_opt_list_find): New static function.
(mips_fol_attr_conflicts): Likewise.
(MATCH_WHITESPACE, MATCH_EMPTYSTRING): New macros.
(mips_func_opt_list_parse_arg_1, mips_func_opt_list_parse_arg,
mips_func_opt_list_read_line, mips_func_opt_list_read,
mips_insert_fol_args, mips_insert_fol_attributes):
New static functions.
(mips_insert_attributes): Insert the attributes into a function.
(mips_option_override): Read func_opt_list file.
* config/mips/mips.opt (mfunc-opt-list): New option.
* doc/invoke.texi (mfunc-opt-list): Document new option.

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

Signed-off-by: Simon Dardis 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.cc  | 609 +++
 gcc/config/mips/mips.opt |   4 +
 gcc/doc/invoke.texi  |  33 +++
 3 files changed, 646 insertions(+)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 596227ded74..6452991c2e1 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -697,6 +697,524 @@ mips_find_list (const char *var, struct mips_sdata_entry 
*list)
   return false;
 }
 
+/* Argument type descriptor.  */
+
+enum mips_func_opt_list_arg_t
+{
+  FOL_ARG_NONE,
+  FOL_ARG_STRING,
+  FOL_ARG_SINGLE_NUM,
+  FOL_ARG_OPTIONAL_NUM_LIST,
+  FOL_ARG_NUM_ONE_OR_TWO,
+  FOL_ARG_OPTIONAL_STRING,
+  FOL_ARG_OPTIONAL_NUM,
+  FOL_ARG_UNKNOWN
+};
+
+/* Collisons for FUNC_OPT_LIST.  Rather that just relying on the middle to
+   complain, check at parse time so we can produce accurate diagnositics.  */
+
+enum mips_fol_collides
+{
+  FOLC_O1,
+  FOLC_O2,
+  FOLC_O3,
+  FOLC_OS,
+  FOLC_MIPS16,
+  FOLC_NOMIPS16,
+  FOLC_ALWAYS_INLINE,
+  FOLC_NOINLINE,
+  FOLC_UNUSED,
+  FOLC_USED,
+  FOLC_FAR,
+  FOLC_NEAR,
+  FOLC_HOT,
+  FOLC_COLD,
+  FOLC_END
+};
+
+/* Part of FUNC_OPT_LIST.  Use a tuple to record the name to be matched against
+   which GCC uses internally, an optional second string if the name is required
+   to be an argument of a different attribute and a bitmask describing which
+   other entries collide with this entry.  */
+
+struct attr_desc
+{
+  const char * optstring;
+  const char * maintype;
+  enum mips_func_opt_list_arg_t arg_type;
+  int collisions;
+};
+
+/* This table encodes the strings to match against for parsing func-opt-list,
+   an optional string which the first is argument of, e.g. optimize ("O2")
+   and the colliding attributes.  */
+
+static const struct attr_desc mips_func_opt_list_strings[] = {
+  {"O1",   "optimize", FOL_ARG_NONE,
+   1 << FOLC_O2 | 1 << FOLC_O3 | 1 << FOLC_OS },
+  {"O2",   "optimize", FOL_ARG_NONE,
+   1 << FOLC_O1 | 1 << FOLC_O3 | 1 << FOLC_OS },
+  {"O3",   "optimize", FOL_ARG_NONE,
+   1 << FOLC_O1 | 1 << FOLC_O2 | 1 << FOLC_OS },
+  {"Os",   "optimize", FOL_ARG_NONE,
+   1 << FOLC_O1 | 1 << FOLC_O2 | 1 << FOLC_O3 },
+  {"mips16",0,  FOL_ARG_NONE, 1 << FOLC_NOMIPS16 },
+  {"nomips16",  0,  FOL_ARG_NONE, 1 << FOLC_MIPS16 },
+  {"always_inline", 0,  FOL_ARG_NONE, 1 << FOLC_NOINLINE },
+  {"noinline",  0,  FOL_ARG_NONE, 1 << FOLC_ALWAYS_INLINE },
+  {"unused",0,  FOL_ARG_NONE, 1 << FOLC_USED },
+  {"used",  0,  FOL_ARG_NONE, 1 << FOLC_UNUSED },
+  {"far",   0,  FOL_ARG_NO

[PATCH v2 15/18] Inefficient scattered double precision load in MSA

2025-03-17 Thread Aleksandar Rakic
From: Mihailo Stojanovic 

gcc/
* config/mips/mips.cc (mips_legitimate_combined_insn):
New function.

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

Signed-off-by: Mihailo Stojanovic 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.cc | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 1385607eafc..b1e687a0f31 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -24906,6 +24906,22 @@ mips_c_mode_for_floating_type (enum tree_index ti)
   return default_mode_for_floating_type (ti);
 }
 
+/* Implemet TARGET_LEGITIMATE_COMBINED_INSN hook.  */
+
+static bool
+mips_legitimate_combined_insn (rtx_insn *insn)
+{
+  rtx p = PATTERN (insn);
+  if (GET_CODE (p) == SET
+  && GET_CODE (XEXP (p, 1)) == VEC_DUPLICATE
+  && GET_CODE (XEXP (XEXP (p, 1), 0)) == REG
+  && (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (XEXP (p, 1), 0)))
+ > UNITS_PER_WORD))
+return false;
+
+  return true;
+}
+
 void
 mips_bit_clear_info (enum machine_mode mode, unsigned HOST_WIDE_INT m,
  int *start_pos, int *size)
@@ -25284,6 +25300,9 @@ mips_noce_conversion_profitable_p (rtx_insn *seq, 
struct noce_if_info *if_info)
 #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
 #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS 
mips_ira_change_pseudo_allocno_class
 
+#undef TARGET_LEGITIMATE_COMBINED_INSN
+#define TARGET_LEGITIMATE_COMBINED_INSN mips_legitimate_combined_insn
+
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
 
-- 
2.34.1


[PATCH v2 02/12] Fix unsafe comparison against stack_pointer_rtx

2025-03-17 Thread Aleksandar Rakic
From: Andrew Bennett 

GCC can modify a rtx which was created using stack_pointer_rtx.
This means that just doing a straight address comparision of a rtx
against stack_pointer_rtx to see whether it is the stack pointer
register will not be correct in all cases.

gcc/
* config/mips/mips.cc: Rewrite comparisons of a rtx against
stack_pointer_rtx to check that firstly the rtx is a register
and its register number is STACK_POINTER_REGNUM.
* config/mips/mips.md: Likewise.

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

Signed-off-by: Andrew Bennett 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.cc | 16 +---
 gcc/config/mips/mips.md |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 392755316eb..ae0477b2dce 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -2779,7 +2779,7 @@ mips_stack_address_p (rtx x, machine_mode mode)
 
   return (mips_classify_address (&addr, x, mode, false)
  && addr.type == ADDRESS_REG
- && addr.reg == stack_pointer_rtx);
+ && REGNO (addr.reg) == STACK_POINTER_REGNUM);
 }
 
 /* Return true if ADDR matches the pattern for the LWXS load scaled indexed
@@ -2845,7 +2845,8 @@ mips16_unextended_reference_p (machine_mode mode, rtx 
base,
   if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0
   && REGNO (base) != GLOBAL_POINTER_REGNUM)
 {
-  if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx)
+  if (GET_MODE_SIZE (mode) == 4 && GET_CODE (base) == REG
+ && REGNO (base) == STACK_POINTER_REGNUM)
return offset < 256U * GET_MODE_SIZE (mode);
   return offset < 32U * GET_MODE_SIZE (mode);
 }
@@ -9849,7 +9850,7 @@ mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
   if (offset == 0)
 offset = INTVAL (offset2);
 
-  if (reg == stack_pointer_rtx
+  if ((GET_CODE (reg) == REG && REGNO (reg) == STACK_POINTER_REGNUM)
   || reg == frame_pointer_rtx
   || reg == hard_frame_pointer_rtx)
 {
@@ -10592,7 +10593,7 @@ mips16e_collect_argument_save_p (rtx dest, rtx src, rtx 
*reg_values,
   required_offset = cfun->machine->frame.total_size + argno * UNITS_PER_WORD;
   if (base == hard_frame_pointer_rtx)
 required_offset -= cfun->machine->frame.hard_frame_pointer_offset;
-  else if (base != stack_pointer_rtx)
+  else if (!(GET_CODE (base) == REG && REGNO (base) == STACK_POINTER_REGNUM))
 return false;
   if (offset != required_offset)
 return false;
@@ -10803,7 +10804,7 @@ mips16e_save_restore_pattern_p (rtx pattern, 
HOST_WIDE_INT adjust,
   /* Check that the address is the sum of the stack pointer and a
 possibly-zero constant offset.  */
   mips_split_plus (XEXP (mem, 0), &base, &offset);
-  if (base != stack_pointer_rtx)
+  if (!(GET_CODE (base) == REG && REGNO (base) == STACK_POINTER_REGNUM))
return false;
 
   /* Check that SET's other operand is a register.  */
@@ -12959,7 +12960,8 @@ mips_restore_reg (rtx reg, rtx mem)
 static void
 mips_deallocate_stack (rtx base, rtx offset, HOST_WIDE_INT new_frame_size)
 {
-  if (base == stack_pointer_rtx && offset == const0_rtx)
+  if (GET_CODE (base) == REG && REGNO (base) == STACK_POINTER_REGNUM
+  && offset == const0_rtx)
 return;
 
   mips_frame_barrier ();
@@ -18169,7 +18171,7 @@ r10k_simplify_address (rtx x, rtx_insn *insn)
{
  /* Replace the incoming value of $sp with
 virtual_incoming_args_rtx.  */
- if (x == stack_pointer_rtx
+ if (GET_CODE (x) == REG && REGNO (x) == STACK_POINTER_REGNUM
  && DF_REF_BB (def) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
newx = virtual_incoming_args_rtx;
}
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index f147667d63a..4b486a7ad29 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -7714,7 +7714,7 @@
[(set (match_operand:SI 1 "register_operand")
 (plus:SI (match_dup 1)
  (match_operand:SI 2 "const_int_operand")))])]
-  "operands[1] == stack_pointer_rtx
+  "GET_CODE (operands[1]) == REG && REGNO (operands[1]) == STACK_POINTER_REGNUM
&& mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)"
   { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); }
   [(set_attr "type" "arith")
-- 
2.34.1


[PATCH v2 0/1] Improve the contrib directory

2025-03-17 Thread Aleksandar Rakic
This patch series improves the script in the contrib directory of
the GCC source tree.

This patch is cherry-picked from the mips_rel/9_3_0/master branch
from the MIPS' repository:
https://github.com/MIPS/gcc .
Further details on the individual changes are included in the
respective patch.


Re: [PATCH] c++: poor diag w/ non-constexpr dtor called from constexpr ctor

2025-03-17 Thread Jason Merrill

On 3/14/25 1:34 PM, Patrick Palka wrote:

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for stage 1?


OK.


-- >8 --

When diagnosing a non-constexpr constructor call during constexpr
evaluation, explain_invalid_constexpr_fn was passing the genericized
body to require_potential_constant_expression rather than the saved
non-genericized one.

This meant for the below testcase (reduced from PR libstdc++/119282)
in which B::B() is deemed non-constexpr due to the local variable having
a non-constexpr destructor we would then issue the cryptic diagnostic:

constexpr-nonlit19.C:17:16: error: non-constant condition for static assertion
17 | static_assert(f());
   |   ~^~
constexpr-nonlit19.C:17:16:   in ‘constexpr’ expansion of ‘f()’
constexpr-nonlit19.C:13:5: error: ‘constexpr B::B()’ called in a constant 
expression
13 |   B b;
   | ^
constexpr-nonlit19.C:6:13: note: ‘constexpr B::B()’ is not usable as a 
‘constexpr’ function because:
 6 |   constexpr B() {
   | ^
constexpr-nonlit19.C:8:5: error: ‘goto’ is not a constant expression
 8 | for (int i = 0; i < 10; i++) { }
   | ^~~

This patch makes us pass the non-genericized body to
require_potential_constant_expression, and so we now emit:

...
constexpr-nonlit19.C:6:13: note: ‘constexpr B::B()’ is not usable as a 
‘constexpr’ function because:
 6 |   constexpr B() {
   | ^
constexpr-nonlit19.C:9:3: error: call to non-‘constexpr’ function ‘A::~A()’
 9 |   }
   |   ^
constexpr-nonlit19.C:3:12: note: ‘A::~A()’ declared here
 3 | struct A { ~A() { } };
   |^

gcc/cp/ChangeLog:

* constexpr.cc (explain_invalid_constexpr_fn): In the
DECL_CONSTRUCTOR_P branch pass the non-gimplified body to
require_potential_constant_expression.

gcc/testsuite/ChangeLog:

* g++.dg/cpp23/constexpr-nonlit19.C: New test.
---
  gcc/cp/constexpr.cc | 13 +
  gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C | 17 +
  2 files changed, 22 insertions(+), 8 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 4820bcc84aa..5b2ae2cbe0a 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1097,17 +1097,14 @@ explain_invalid_constexpr_fn (tree fun)
body = fd->body;
  else
body = DECL_SAVED_TREE (fun);
- body = massage_constexpr_body (fun, body);
- require_potential_rvalue_constant_expression (body);
+ tree massaged = massage_constexpr_body (fun, body);
+ require_potential_rvalue_constant_expression (massaged);
  if (DECL_CONSTRUCTOR_P (fun))
{
- cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
+ cx_check_missing_mem_inits (DECL_CONTEXT (fun), massaged, true);
  if (cxx_dialect > cxx11)
-   {
- /* Also check the body, not just the ctor-initializer.  */
- body = DECL_SAVED_TREE (fun);
- require_potential_rvalue_constant_expression (body);
-   }
+   /* Also check the body, not just the ctor-initializer.  */
+   require_potential_rvalue_constant_expression (body);
}
}
  }
diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C 
b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C
new file mode 100644
index 000..1b73e2d8209
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++23 } }
+
+struct A { ~A() { } };
+
+struct B {
+  constexpr B() {
+A a;
+for (int i = 0; i < 10; i++) { }
+  } // { dg-error "call to non-'constexpr' function 'A::~A..'" }
+};
+
+constexpr bool f() {
+  B b; // { dg-error "B::B..' called in a constant expression" }
+  return true;
+}
+
+static_assert(f()); // { dg-error "non-constant" }




[PATCH v2] ISC-V: Support for zilsd and zclsd extensions.

2025-03-17 Thread Dongyan Chen
This patch support zilsd and zclsd[1] extensions.
To enable GCC to recognize and process zilsd and zclsd extension correctly at 
compile time.

[1] https://github.com/riscv/riscv-zilsd

Changes for v2:
- Remove the addition of zilsd extension in 
gcc/common/config/riscv/riscv-ext-bitmask.def
- Fix a bug with zilsd and zclsd extension dependency in 
gcc/common/config/riscv/riscv-common.cc

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc 
(riscv_subset_list::check_conflict_ext): New extension.
* config/riscv/riscv.opt: Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/arch-45.c: New test.
* gcc.target/riscv/arch-46.c: New test.
* gcc.target/riscv/arch-47.c: New test.

---
 gcc/common/config/riscv/riscv-common.cc  | 16 
 gcc/config/riscv/riscv.opt   |  4 
 gcc/testsuite/gcc.target/riscv/arch-45.c |  5 +
 gcc/testsuite/gcc.target/riscv/arch-46.c |  6 ++
 gcc/testsuite/gcc.target/riscv/arch-47.c |  6 ++
 5 files changed, 37 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-45.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-46.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-47.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index b34409adf39c..0e244d3cefc8 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -115,6 +115,9 @@ static const riscv_implied_info_t riscv_implied_info[] =
   {"zicfiss", "zimop"},
   {"zicfilp", "zicsr"},

+  {"zclsd", "zilsd"},
+  {"zclsd", "zca"},
+
   {"zk", "zkn"},
   {"zk", "zkr"},
   {"zk", "zkt"},
@@ -338,6 +341,9 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zicntr", ISA_SPEC_CLASS_NONE, 2, 0},
   {"zihpm",  ISA_SPEC_CLASS_NONE, 2, 0},

+  {"zilsd",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zclsd",  ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"zk",ISA_SPEC_CLASS_NONE, 1, 0},
   {"zkn",   ISA_SPEC_CLASS_NONE, 1, 0},
   {"zks",   ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1308,6 +1314,14 @@ riscv_subset_list::check_conflict_ext ()
   if (lookup ("zcf") && m_xlen == 64)
 error_at (m_loc, "%<-march=%s%>: zcf extension supports in rv32 only",
  m_arch);
+  
+  if (lookup ("zilsd") && m_xlen == 64)
+error_at (m_loc, "%<-march=%s%>: zilsd extension supports in rv32 only",
+ m_arch);
+
+  if (lookup ("zclsd") && m_xlen == 64)
+error_at (m_loc, "%<-march=%s%>: zclsd extension supports in rv32 only",
+ m_arch);

   if (lookup ("zfinx") && lookup ("f"))
 error_at (m_loc,
@@ -1648,6 +1662,7 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   RISCV_EXT_FLAG_ENTRY ("ziccif",  x_riscv_zi_subext, MASK_ZICCIF),
   RISCV_EXT_FLAG_ENTRY ("zicclsm", x_riscv_zi_subext, MASK_ZICCLSM),
   RISCV_EXT_FLAG_ENTRY ("ziccrse", x_riscv_zi_subext, MASK_ZICCRSE),
+  RISCV_EXT_FLAG_ENTRY ("zilsd",   x_riscv_zi_subext, MASK_ZILSD),

   RISCV_EXT_FLAG_ENTRY ("zicboz", x_riscv_zicmo_subext, MASK_ZICBOZ),
   RISCV_EXT_FLAG_ENTRY ("zicbom", x_riscv_zicmo_subext, MASK_ZICBOM),
@@ -1731,6 +1746,7 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   RISCV_EXT_FLAG_ENTRY ("zcd",  x_riscv_zc_subext, MASK_ZCD),
   RISCV_EXT_FLAG_ENTRY ("zcmp", x_riscv_zc_subext, MASK_ZCMP),
   RISCV_EXT_FLAG_ENTRY ("zcmt", x_riscv_zc_subext, MASK_ZCMT),
+  RISCV_EXT_FLAG_ENTRY ("zclsd", x_riscv_zc_subext, MASK_ZCLSD),

   RISCV_EXT_FLAG_ENTRY ("svinval", x_riscv_sv_subext, MASK_SVINVAL),
   RISCV_EXT_FLAG_ENTRY ("svnapot", x_riscv_sv_subext, MASK_SVNAPOT),
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 7515c8ea13dd..51bbe225ea06 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -257,6 +257,8 @@ Mask(ZICFISS) Var(riscv_zi_subext)

 Mask(ZICFILP) Var(riscv_zi_subext)

+Mask(ZILSD)   Var(riscv_zi_subext)
+
 TargetVariable
 int riscv_za_subext

@@ -461,6 +463,8 @@ Mask(ZCMP) Var(riscv_zc_subext)

 Mask(ZCMT) Var(riscv_zc_subext)

+Mask(ZCLSD) Var(riscv_zc_subext)
+
 Mask(XCVBI) Var(riscv_xcv_subext)

 TargetVariable
diff --git a/gcc/testsuite/gcc.target/riscv/arch-45.c 
b/gcc/testsuite/gcc.target/riscv/arch-45.c
new file mode 100644
index ..452c04e42f6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-45.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zilsd_zclsd -mabi=ilp32d" } */
+int foo()
+{
+}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-46.c 
b/gcc/testsuite/gcc.target/riscv/arch-46.c
new file mode 100644
index ..52b698d83b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-46.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zilsd -mabi=ilp32d" } */
+int foo()
+{
+}
+/* { missing " for " dg-error 6 ".'error: '-march=rv64gc_zilsd': zilsd 
extension supports in rv32 only " } */
diff --git a/gcc/testsuite/gcc.target/riscv/arch-47.c 
b/gcc/testsuite/gcc.

[COMMITTED 031/145] gccrs: Change return type of lookup trait defid functions.

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

Wrap the return type with an optional.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc (HIRCompileBase::resolve_method_address):
Update code around lookup return type.
* typecheck/rust-tyty-bounds.cc 
(TypeCheckBase::get_predicate_from_bound):
Likewise.
* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output):
Likewise.
* util/rust-hir-map.cc (Mappings::insert_defid_mapping): Likewise.
(Mappings::lookup_trait_item_defid): Update return type with an
optional.
(Mappings::get_lang_item): Likewise.
* util/rust-hir-map.h: Update the functions prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-base.cc  |  2 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc |  7 +--
 gcc/rust/typecheck/rust-tyty.cc|  4 ++--
 gcc/rust/util/rust-hir-map.cc  | 10 +-
 gcc/rust/util/rust-hir-map.h   |  6 +++---
 5 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index c7031edd30b..add173c50a9 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -887,7 +887,7 @@ HIRCompileBase::resolve_method_address (TyTy::FnType 
*fntype,
 
   // it might be resolved to a trait item
   HIR::TraitItem *trait_item
-= ctx->get_mappings ().lookup_trait_item_defid (id);
+= ctx->get_mappings ().lookup_trait_item_defid (id).value ();
   HIR::Trait *trait = ctx->get_mappings ().lookup_trait_item_mapping (
 trait_item->get_mappings ().get_hirid ());
 
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index a18a0e40ddf..43404385cdd 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -245,8 +245,11 @@ TypeCheckBase::get_predicate_from_bound (HIR::TypePath 
&type_path,
rust_assert (fn.has_return_type ());
TypeCheckType::Resolve (fn.get_return_type ().get ());
 
-   HIR::TraitItem *trait_item = mappings.lookup_trait_item_lang_item (
- LangItem::Kind::FN_ONCE_OUTPUT, final_seg->get_locus ());
+   HIR::TraitItem *trait_item
+ = mappings
+ .lookup_trait_item_lang_item (LangItem::Kind::FN_ONCE_OUTPUT,
+   final_seg->get_locus ())
+ .value ();
 
std::vector bindings;
location_t output_locus = fn.get_return_type ()->get_locus ();
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 2e9a551e4c7..565f2bc58aa 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2238,8 +2238,8 @@ ClosureType::setup_fn_once_output () const
   rust_assert (!trait_ref->is_error ());
 
   // resolve to trait item
-  HIR::TraitItem *trait_item = mappings.lookup_trait_item_defid 
(trait_item_id);
-  rust_assert (trait_item != nullptr);
+  HIR::TraitItem *trait_item
+= mappings.lookup_trait_item_defid (trait_item_id).value ();
   rust_assert (trait_item->get_item_kind ()
   == HIR::TraitItem::TraitItemKind::TYPE);
   std::string item_identifier = trait_item->trait_identifier ();
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index dcedea97e09..41e4b048eb5 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -314,7 +314,7 @@ Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
 
   rust_assert (!lookup_defid (id));
   rust_assert (!lookup_local_defid (crate_num, local_def_id));
-  rust_assert (lookup_trait_item_defid (id) == nullptr);
+  rust_assert (!lookup_trait_item_defid (id));
 
   defIdMappings[id] = item;
   insert_local_defid_mapping (crate_num, local_def_id, item);
@@ -338,17 +338,17 @@ Mappings::insert_defid_mapping (DefId id, HIR::TraitItem 
*item)
 
   rust_assert (!lookup_defid (id));
   rust_assert (!lookup_local_defid (crate_num, local_def_id));
-  rust_assert (lookup_trait_item_defid (id) == nullptr);
+  rust_assert (!lookup_trait_item_defid (id));
 
   defIdTraitItemMappings[id] = item;
 }
 
-HIR::TraitItem *
+tl::optional
 Mappings::lookup_trait_item_defid (DefId id)
 {
   auto it = defIdTraitItemMappings.find (id);
   if (it == defIdTraitItemMappings.end ())
-return nullptr;
+return tl::nullopt;
 
   return it->second;
 }
@@ -1264,7 +1264,7 @@ Mappings::get_lang_item (LangItem::Kind item_type, 
location_t locus)
   return item;
 }
 
-HIR::TraitItem *
+tl::optional
 Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t locus)
 {
   DefId trait_item_id = get_lang_item (item, locus);
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index b4c39a94e82..ff0da5556a7 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -108,7 +108,7 @@ public:
   void insert_defid_mapping (DefId id, HIR::Item *item);
   tl::optional lookup_defid

[COMMITTED 010/145] gccrs: borrowck: Use std::ignore

2025-03-17 Thread arthur . cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::visit): Use std::ignore.
---
 .../errors/borrowck/rust-bir-builder-expr-stmt.cc  | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 29ae4dc1b37..acfcdd88425 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -237,7 +237,7 @@ ExprStmtBuilder::visit (HIR::ArrayIndexExpr &expr)
   auto lhs = visit_expr (*expr.get_array_expr ());
   auto rhs = visit_expr (*expr.get_index_expr ());
   // The index is not tracked in BIR.
-  (void) rhs;
+  std::ignore = rhs;
   return_place (
 ctx.place_db.lookup_or_add_path (Place::INDEX, lookup_type (expr), lhs));
 }
@@ -454,7 +454,7 @@ ExprStmtBuilder::visit (HIR::LoopExpr &expr)
 {
   auto loop = setup_loop (expr);
 
-  (void) visit_expr (*expr.get_loop_block ());
+  std::ignore = visit_expr (*expr.get_loop_block ());
   if (!ctx.get_current_bb ().is_terminated ())
 push_goto (loop.continue_bb);
 
@@ -471,7 +471,7 @@ ExprStmtBuilder::visit (HIR::WhileLoopExpr &expr)
   push_switch (cond_val, {body_bb, loop.break_bb});
 
   ctx.current_bb = body_bb;
-  (void) visit_expr (*expr.get_loop_block ());
+  std::ignore = visit_expr (*expr.get_loop_block ());
   push_goto (loop.continue_bb);
 
   ctx.current_bb = loop.break_bb;
@@ -497,7 +497,7 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
 
   ctx.current_bb = new_bb ();
   BasicBlockId then_start_block = ctx.current_bb;
-  (void) visit_expr (*expr.get_if_block ());
+  std::ignore = visit_expr (*expr.get_if_block ());
   if (!ctx.get_current_bb ().is_terminated ())
 push_goto (INVALID_BB); // Resolved later.
   BasicBlockId then_end_block = ctx.current_bb;
@@ -525,14 +525,14 @@ ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 
   ctx.current_bb = new_bb ();
   BasicBlockId then_start_bb = ctx.current_bb;
-  (void) visit_expr (*expr.get_if_block (), result);
+  std::ignore = visit_expr (*expr.get_if_block (), result);
   if (!ctx.get_current_bb ().is_terminated ())
 push_goto (INVALID_BB); // Resolved later.
   BasicBlockId then_end_bb = ctx.current_bb;
 
   ctx.current_bb = new_bb ();
   BasicBlockId else_start_bb = ctx.current_bb;
-  (void) visit_expr (*expr.get_else_block (), result);
+  std::ignore = visit_expr (*expr.get_else_block (), result);
   if (!ctx.get_current_bb ().is_terminated ())
 push_goto (INVALID_BB); // Resolved later.
   BasicBlockId else_end_bb = ctx.current_bb;
@@ -658,7 +658,7 @@ ExprStmtBuilder::visit (HIR::LetStmt &stmt)
push_user_type_ascription (var, lookup_type (*stmt.get_type ()));
 
   if (stmt.has_init_expr ())
-   (void) visit_expr (*stmt.get_init_expr (), var);
+   std::ignore = visit_expr (*stmt.get_init_expr (), var);
 }
   else
 {
-- 
2.45.2



[COMMITTED 032/145] gccrs: Change lookup_hir_extern_item return type

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

Wrap the return type with an optional and make the return type a pair
with the parent hid.

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile):
Adapt code around new return type.
* checks/errors/rust-const-checker.cc 
(ConstChecker::check_function_call):
Likewise.
* checks/errors/rust-unsafe-checker.cc 
(UnsafeChecker::check_use_of_static):
Likewise.
(UnsafeChecker::check_function_call): Likewise.
* typecheck/rust-type-util.cc (query_type): Likewise.
* util/rust-hir-map.cc (Mappings::insert_hir_extern_item): Likewise.
(Mappings::lookup_hir_extern_item): Change return type.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-resolve-path.cc |  8 +++-
 gcc/rust/checks/errors/rust-const-checker.cc  |  9 -
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 18 ++
 gcc/rust/typecheck/rust-type-util.cc  | 11 ---
 gcc/rust/util/rust-hir-map.cc | 12 +---
 gcc/rust/util/rust-hir-map.h  |  5 -
 6 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index bf294e4c879..c27074f89a4 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -201,10 +201,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
   const Analysis::NodeMapping &mappings,
   location_t expr_locus, bool is_qualified_path)
 {
-  HirId parent_block;
-  HIR::ExternalItem *resolved_extern_item
-= ctx->get_mappings ().lookup_hir_extern_item (ref, &parent_block);
-  bool is_hir_extern_item = resolved_extern_item != nullptr;
   bool is_fn = lookup->get_kind () == TyTy::TypeKind::FNDEF;
   if (auto resolved_item = ctx->get_mappings ().lookup_hir_item (ref))
 {
@@ -215,8 +211,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
return CompileItem::compile (*resolved_item, ctx, lookup, true,
 expr_locus);
 }
-  else if (is_hir_extern_item)
+  else if (auto hir_extern_item
+  = ctx->get_mappings ().lookup_hir_extern_item (ref))
 {
+  HIR::ExternalItem *resolved_extern_item = hir_extern_item->first;
   if (!lookup->has_substitutions_defined ())
return CompileExternItem::compile (resolved_extern_item, ctx, nullptr,
   true, expr_locus);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 1bb2c37d7eb..8c12012b33f 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -315,11 +315,9 @@ ConstChecker::check_function_call (HirId fn_id, location_t 
locus)
   // There are const extern functions (intrinsics)
   // TODO: Should we check the ABI is only "rust intrinsics"? Is that handled
   // elsewhere?
-  HirId parent_block;
-  auto maybe_extern_item
-= mappings.lookup_hir_extern_item (fn_id, &parent_block);
+  auto maybe_extern_item = mappings.lookup_hir_extern_item (fn_id);
   if (maybe_extern_item
-  && maybe_extern_item->get_extern_kind ()
+  && maybe_extern_item->first->get_extern_kind ()
   != ExternalItem::ExternKind::Function)
 return;
 
@@ -334,7 +332,8 @@ ConstChecker::check_function_call (HirId fn_id, location_t 
locus)
   if (maybe_extern_item)
 {
   {
-   auto fn = static_cast (maybe_extern_item);
+   auto fn
+ = static_cast (maybe_extern_item->first);
if (!is_const_extern_fn (*fn))
  is_error = true;
   }
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index fc83283a795..19a0489297f 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -70,15 +70,12 @@ UnsafeChecker::check_use_of_static (HirId node_id, 
location_t locus)
   if (unsafe_context.is_in_context ())
 return;
 
-  HirId extern_block;
-  auto maybe_extern_static
-= mappings.lookup_hir_extern_item (node_id, &extern_block);
-
   if (auto maybe_static_mut = mappings.lookup_hir_item (node_id))
 check_static_mut (*maybe_static_mut, locus);
 
-  if (maybe_extern_static)
-check_extern_static (static_cast (maybe_extern_static),
+  if (auto maybe_extern_static = mappings.lookup_hir_extern_item (node_id))
+check_extern_static (static_cast (
+  maybe_extern_static->first),
 locus);
 }
 
@@ -166,18 +163,15 @@ UnsafeChecker::check_function_call (HirId node_id, 
location_t locus)
   if (unsafe_context.is_in_context ())
 return;
 
-  HirId parent_exter

[COMMITTED 038/145] gccrs: Change lookup_hir_generic_param return type

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

Wrap the function's return type with an optional.

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::insert_hir_generic_param): Change
call site to accomodate the new return type.
(Mappings::lookup_hir_generic_param): Wrap the function's return type
with an optional.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/util/rust-hir-map.cc | 6 +++---
 gcc/rust/util/rust-hir-map.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index c96743a54f8..c3929d8f3ce 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -571,19 +571,19 @@ void
 Mappings::insert_hir_generic_param (HIR::GenericParam *param)
 {
   auto id = param->get_mappings ().get_hirid ();
-  rust_assert (lookup_hir_generic_param (id) == nullptr);
+  rust_assert (!lookup_hir_generic_param (id));
 
   hirGenericParamMappings[id] = param;
   insert_node_to_hir (param->get_mappings ().get_nodeid (), id);
   insert_location (id, param->get_locus ());
 }
 
-HIR::GenericParam *
+tl::optional
 Mappings::lookup_hir_generic_param (HirId id)
 {
   auto it = hirGenericParamMappings.find (id);
   if (it == hirGenericParamMappings.end ())
-return nullptr;
+return tl::nullopt;
 
   return it->second;
 }
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index c7d0838d400..d04232f3d5d 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -152,7 +152,7 @@ public:
   tl::optional lookup_hir_path_expr_seg (HirId id);
 
   void insert_hir_generic_param (HIR::GenericParam *expr);
-  HIR::GenericParam *lookup_hir_generic_param (HirId id);
+  tl::optional lookup_hir_generic_param (HirId id);
 
   void insert_hir_type (HIR::Type *type);
   HIR::Type *lookup_hir_type (HirId id);
-- 
2.45.2



[COMMITTED 042/145] gccrs: Change lookup_hir_self_param return type

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

Wrap the function's return type within an optional in order to
differentiate null pointers from missing value.

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::insert_hir_self_param): Adapt call
site to new return type.
(Mappings::lookup_hir_self_param): Change the function's return type.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/util/rust-hir-map.cc | 6 +++---
 gcc/rust/util/rust-hir-map.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index e2c3b98eff5..f124be8b998 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -652,18 +652,18 @@ void
 Mappings::insert_hir_self_param (HIR::SelfParam *param)
 {
   auto id = param->get_mappings ().get_hirid ();
-  rust_assert (lookup_hir_self_param (id) == nullptr);
+  rust_assert (!lookup_hir_self_param (id));
 
   hirSelfParamMappings[id] = param;
   insert_node_to_hir (param->get_mappings ().get_nodeid (), id);
 }
 
-HIR::SelfParam *
+tl::optional
 Mappings::lookup_hir_self_param (HirId id)
 {
   auto it = hirSelfParamMappings.find (id);
   if (it == hirSelfParamMappings.end ())
-return nullptr;
+return tl::nullopt;
 
   return it->second;
 }
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 6f97dcb6bc6..720dd976af4 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -164,7 +164,7 @@ public:
   tl::optional lookup_hir_param (HirId id);
 
   void insert_hir_self_param (HIR::SelfParam *type);
-  HIR::SelfParam *lookup_hir_self_param (HirId id);
+  tl::optional lookup_hir_self_param (HirId id);
 
   void insert_hir_struct_field (HIR::StructExprField *type);
   HIR::StructExprField *lookup_hir_struct_field (HirId id);
-- 
2.45.2



[COMMITTED 016/145] gccrs: Improve matching on non-enum ADTs

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

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc
(check_match_scrutinee): Add assertion.
* backend/rust-compile-pattern.cc
(CompilePatternCheckExpr::visit):
Handle HIR::PathInExpression matching a non-enum.

gcc/testsuite/ChangeLog:

* rust/compile/match-struct-path.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/backend/rust-compile-expr.cc   |  2 ++
 gcc/rust/backend/rust-compile-pattern.cc| 11 ---
 gcc/testsuite/rust/compile/match-struct-path.rs |  7 +++
 3 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/match-struct-path.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index ac85628d03c..52318a973aa 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -956,6 +956,8 @@ check_match_scrutinee (HIR::MatchExpr &expr, Context *ctx)
   TyTy::ADTType *adt = static_cast (scrutinee_expr_tyty);
   if (adt->is_enum ())
rust_assert (adt->number_of_variants () > 0);
+  else
+   rust_assert (adt->number_of_variants () == 1);
 }
   else if (scrutinee_kind == TyTy::TypeKind::FLOAT)
 {
diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 86063202bf8..ffa1fa7f5dc 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -35,11 +35,16 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression 
&pattern)
  &lookup);
   rust_assert (ok);
 
-  // this must be an enum
-  // TODO: might not be
+  // must be an ADT (?)
   rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT);
   TyTy::ADTType *adt = static_cast (lookup);
-  rust_assert (adt->is_enum ());
+
+  // if this isn't an enum, always succeed
+  if (!adt->is_enum ())
+{
+  check_expr = boolean_true_node;
+  return;
+}
 
   // lookup the variant
   HirId variant_id;
diff --git a/gcc/testsuite/rust/compile/match-struct-path.rs 
b/gcc/testsuite/rust/compile/match-struct-path.rs
new file mode 100644
index 000..acadcdb87ad
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-struct-path.rs
@@ -0,0 +1,7 @@
+pub struct S;
+
+pub fn foo(v: S) {
+match v {
+S => ()
+}
+}
-- 
2.45.2



[COMMITTED 034/145] gccrs: Change return type to optional in get_lang_item

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

Wrap the function's return type with an optional.

gcc/rust/ChangeLog:

* typecheck/rust-autoderef.cc: Adapt calling code to new return type.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise.
(TypeCheckExpr::resolve_operator_overload): Likewise.
* typecheck/rust-tyty-bounds.cc 
(TypeBoundsProbe::assemble_builtin_candidate):
Likewise.
* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): Likewise.
* util/rust-hir-map.cc (Mappings::get_lang_item): Change return type.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/typecheck/rust-autoderef.cc  |  5 +--
 .../typecheck/rust-hir-type-check-expr.cc | 42 +++
 gcc/rust/typecheck/rust-tyty-bounds.cc|  6 +--
 gcc/rust/typecheck/rust-tyty.cc   | 12 ++
 gcc/rust/util/rust-hir-map.cc | 10 ++---
 gcc/rust/util/rust-hir-map.h  |  7 ++--
 6 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/gcc/rust/typecheck/rust-autoderef.cc 
b/gcc/rust/typecheck/rust-autoderef.cc
index 233d5d459d1..7e80b8efddf 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -129,12 +129,11 @@ resolve_operator_overload_fn (
 
   // look up lang item for arithmetic type
   std::string associated_item_name = LangItem::ToString (lang_item_type);
-  DefId respective_lang_item_id = UNKNOWN_DEFID;
-  bool lang_item_defined
-= mappings.lookup_lang_item (lang_item_type, &respective_lang_item_id);
+  auto lang_item_defined = mappings.lookup_lang_item (lang_item_type);
 
   if (!lang_item_defined)
 return false;
+  DefId &respective_lang_item_id = lang_item_defined.value ();
 
   // we might be in a static or const context and unknown is fine
   TypeCheckContextItem current_context = TypeCheckContextItem::get_error ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 95e421d8720..7cbcdedbe4d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -628,10 +628,7 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
 {
   auto lang_item_type = LangItem::Kind::RANGE;
 
-  DefId respective_lang_item_id = UNKNOWN_DEFID;
-  bool lang_item_defined
-= mappings.lookup_lang_item (lang_item_type, &respective_lang_item_id);
-
+  auto lang_item_defined = mappings.lookup_lang_item (lang_item_type);
   // we need to have it maybe
   if (!lang_item_defined)
 {
@@ -640,6 +637,7 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
  LangItem::ToString (lang_item_type).c_str ());
   return;
 }
+  DefId respective_lang_item_id = lang_item_defined.value ();
 
   // look it up and it _must_ be a struct definition
   HIR::Item *item = mappings.lookup_defid (respective_lang_item_id).value ();
@@ -682,10 +680,7 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
 {
   auto lang_item_type = LangItem::Kind::RANGE_FROM;
 
-  DefId respective_lang_item_id = UNKNOWN_DEFID;
-  bool lang_item_defined
-= mappings.lookup_lang_item (lang_item_type, &respective_lang_item_id);
-
+  auto lang_item_defined = mappings.lookup_lang_item (lang_item_type);
   // we need to have it maybe
   if (!lang_item_defined)
 {
@@ -694,6 +689,7 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
  LangItem::ToString (lang_item_type).c_str ());
   return;
 }
+  DefId &respective_lang_item_id = lang_item_defined.value ();
 
   // look it up and it _must_ be a struct definition
   HIR::Item *item = mappings.lookup_defid (respective_lang_item_id).value ();
@@ -729,10 +725,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
 {
   auto lang_item_type = LangItem::Kind::RANGE_TO;
 
-  DefId respective_lang_item_id = UNKNOWN_DEFID;
-  bool lang_item_defined
-= mappings.lookup_lang_item (lang_item_type, &respective_lang_item_id);
-
+  auto lang_item_defined = mappings.lookup_lang_item (lang_item_type);
   // we need to have it maybe
   if (!lang_item_defined)
 {
@@ -742,6 +735,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
   return;
 }
 
+  DefId &respective_lang_item_id = lang_item_defined.value ();
   // look it up and it _must_ be a struct definition
   HIR::Item *item = mappings.lookup_defid (respective_lang_item_id).value ();
 
@@ -775,10 +769,7 @@ TypeCheckExpr::visit (HIR::RangeFullExpr &expr)
 {
   auto lang_item_type = LangItem::Kind::RANGE_FULL;
 
-  DefId respective_lang_item_id = UNKNOWN_DEFID;
-  bool lang_item_defined
-= mappings.lookup_lang_item (lang_item_type, &respective_lang_item_id);
-
+  auto lang_item_defined = mappings.lookup_lang_item (lang_item_type);
   // we need to have it maybe
   if (!lang_item_defined)
 {
@@ -787,6 +778,7 @@ TypeCheckExpr::visit (HIR::RangeFullExpr &expr)

[COMMITTED 043/145] gccrs: Change lookup_hir_struct_field return type

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

Wrap the function's return type within an optional to differentiate
between a null pointer and a missing value.

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::insert_hir_struct_field): Change
call site to accomodate new return type.
(Mappings::lookup_hir_struct_field): Change the function's return
type.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/util/rust-hir-map.cc | 6 +++---
 gcc/rust/util/rust-hir-map.h  | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index f124be8b998..d1f55a372ac 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -672,18 +672,18 @@ void
 Mappings::insert_hir_struct_field (HIR::StructExprField *field)
 {
   auto id = field->get_mappings ().get_hirid ();
-  rust_assert (lookup_hir_struct_field (id) == nullptr);
+  rust_assert (!lookup_hir_struct_field (id));
 
   hirStructFieldMappings[id] = field;
   insert_node_to_hir (field->get_mappings ().get_nodeid (), id);
 }
 
-HIR::StructExprField *
+tl::optional
 Mappings::lookup_hir_struct_field (HirId id)
 {
   auto it = hirStructFieldMappings.find (id);
   if (it == hirStructFieldMappings.end ())
-return nullptr;
+return tl::nullopt;
 
   return it->second;
 }
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 720dd976af4..740a8e6d499 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -167,7 +167,7 @@ public:
   tl::optional lookup_hir_self_param (HirId id);
 
   void insert_hir_struct_field (HIR::StructExprField *type);
-  HIR::StructExprField *lookup_hir_struct_field (HirId id);
+  tl::optional lookup_hir_struct_field (HirId id);
 
   void insert_hir_pattern (HIR::Pattern *pattern);
   HIR::Pattern *lookup_hir_pattern (HirId id);
-- 
2.45.2



[COMMITTED 040/145] gccrs: Change lookup_hir_smt's return type with optional

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

Wrap the function's return type within an optional in order to
differentiate missing values from null pointers.

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::insert_hir_stmt): Change call site
to accomodate new return type.
(Mappings::lookup_hir_stmt): Change the function's return type.
(Mappings::resolve_nodeid_to_stmt): Adapt call site to new return type.
* util/rust-hir-map.h: Update the function's prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/util/rust-hir-map.cc | 8 
 gcc/rust/util/rust-hir-map.h  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index ae11e67a57b..025b3121b27 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -612,18 +612,18 @@ void
 Mappings::insert_hir_stmt (HIR::Stmt *stmt)
 {
   auto id = stmt->get_mappings ().get_hirid ();
-  rust_assert (lookup_hir_stmt (id) == nullptr);
+  rust_assert (!lookup_hir_stmt (id));
 
   hirStmtMappings[id] = stmt;
   insert_node_to_hir (stmt->get_mappings ().get_nodeid (), id);
 }
 
-HIR::Stmt *
+tl::optional
 Mappings::lookup_hir_stmt (HirId id)
 {
   auto it = hirStmtMappings.find (id);
   if (it == hirStmtMappings.end ())
-return nullptr;
+return tl::nullopt;
 
   return it->second;
 }
@@ -796,7 +796,7 @@ Mappings::resolve_nodeid_to_stmt (NodeId id)
 return tl::nullopt;
 
   HirId resolved = it->second;
-  return {lookup_hir_stmt (resolved)};
+  return lookup_hir_stmt (resolved);
 }
 
 void
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index e4f47852ed9..f6db83d6e11 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -158,7 +158,7 @@ public:
   tl::optional lookup_hir_type (HirId id);
 
   void insert_hir_stmt (HIR::Stmt *stmt);
-  HIR::Stmt *lookup_hir_stmt (HirId id);
+  tl::optional lookup_hir_stmt (HirId id);
 
   void insert_hir_param (HIR::FunctionParam *type);
   HIR::FunctionParam *lookup_hir_param (HirId id);
-- 
2.45.2



[COMMITTED 109/145] gccrs: Fix visitor-related warnings

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit):
Fix visitor-related warnings
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* expand/rust-derive.h: Likewise.
* expand/rust-macro-builtins-asm.cc (parse_reg_operand): Likewise.
* hir/rust-hir-dump.cc (Dump::visit): Likewise.
* hir/rust-hir-dump.h: Likewise.
* hir/tree/rust-hir-visitor.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
---
 gcc/rust/ast/rust-ast-collector.cc|  5 +
 gcc/rust/ast/rust-ast-collector.h |  2 +-
 gcc/rust/ast/rust-ast-visitor.cc  |  6 ++
 gcc/rust/ast/rust-ast-visitor.h   |  5 +++--
 .../errors/borrowck/rust-bir-builder-struct.h |  1 +
 .../errors/borrowck/rust-function-collector.h |  1 +
 gcc/rust/checks/errors/rust-const-checker.cc  |  4 
 gcc/rust/checks/errors/rust-const-checker.h   |  2 ++
 gcc/rust/expand/rust-derive.h |  1 +
 gcc/rust/expand/rust-macro-builtins-asm.cc| 19 +--
 gcc/rust/hir/rust-hir-dump.cc |  5 +
 gcc/rust/hir/rust-hir-dump.h  |  1 +
 gcc/rust/hir/tree/rust-hir-visitor.h  |  3 ++-
 gcc/rust/resolve/rust-ast-resolve-base.cc |  4 
 gcc/rust/resolve/rust-ast-resolve-base.h  |  1 +
 15 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index bc8bc9caabe..f1d5c8c6c32 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -18,6 +18,7 @@
 #include "rust-ast-collector.h"
 #include "rust-ast.h"
 #include "rust-diagnostics.h"
+#include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
 #include "rust-token.h"
@@ -1511,6 +1512,10 @@ TokenCollector::visit (AsyncBlockExpr &expr)
   visit (expr.get_block_expr ());
 }
 
+void
+TokenCollector::visit (InlineAsm &expr)
+{}
+
 // rust-item.h
 
 void
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index 7b418bb6d31..b2dc41b4318 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -303,7 +303,7 @@ public:
   void visit (MatchExpr &expr);
   void visit (AwaitExpr &expr);
   void visit (AsyncBlockExpr &expr);
-
+  void visit (InlineAsm &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 2c1674e21ea..c4abf2ea870 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -662,6 +662,12 @@ DefaultASTVisitor::visit (AST::AsyncBlockExpr &expr)
   visit (expr.get_block_expr ());
 }
 
+void
+DefaultASTVisitor::visit (AST::InlineAsm &expr)
+{
+  rust_unreachable ();
+}
+
 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 d91ef3da93e..2f56d89c582 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -23,7 +23,6 @@
 // full include not required - only forward decls
 #include "rust-ast-full-decls.h"
 #include "rust-ast.h"
-#include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-system.h"
 
@@ -129,7 +128,7 @@ public:
   virtual void visit (MatchExpr &expr) = 0;
   virtual void visit (AwaitExpr &expr) = 0;
   virtual void visit (AsyncBlockExpr &expr) = 0;
-  virtual void visit (InlineAsm &expr) { rust_unreachable (); }
+  virtual void visit (InlineAsm &expr) = 0;
 
   // rust-item.h
   virtual void visit (TypeParam ¶m) = 0;
@@ -313,6 +312,8 @@ protected:
   virtual void visit (AST::MatchExpr &expr) override;
   virtual void visit (AST::AwaitExpr &expr) override;
   virtual void visit (AST::AsyncBlockExpr &expr) override;
+  virtual void visit (InlineAsm &expr) override;
+
   virtual void visit (AST::TypeParam ¶m) override;
   virtual void visit (AST::LifetimeWhereClauseItem &item) override;
   virtual void visit (AST::TypeBoundWhereClauseItem &item) override;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index 17331ddc826..53346bfe737 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -154,6 +154,7 @@ protected:
   void visit (HIR::MatchExpr &expr) override { rust_unreachable (); }
   void visit (HIR::Awa

New template for 'gcc' made available

2025-03-17 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.  (If you have
any questions, send them to .)

A new POT file for textual domain 'gcc' has been made available
to the language teams for translation.  It is archived as:

https://translationproject.org/POT-files/gcc-15.1-b20250316.pot

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

Below is the URL which has been provided to the translators of your
package.  Please inform the translation coordinator, at the address
at the bottom, if this information is not current:

https://gcc.gnu.org/pub/gcc/snapshots/15-20250316/gcc-15-20250316.tar.xz

Translated PO files will later be automatically e-mailed to you.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




[RISC-V] Fix unreported code quality regression with single bit manipulations

2025-03-17 Thread Jeff Law
I was reviewing some code recently and spotted an oddity.  In a few 
places we were emitting andi dst,src,-1 and in others [x]ori dst,src,0. 
Those are obviously nops and we should get rid of them.


Most of these are coming from a split part of a couple 
define_insn_and_split patterns added back in late 2022, so this is an 
unreported 13, 14 & 15 code quality regression (verified on godbolt, 
https://godbolt.org/z/EPszox5Kd).  Essentially the split part is 
matching over-aggressively and splitting what should be a trivial 
bitmanip insn such as bset, bclr or binv into a nop logical with a bit 
twiddle.


Since the split portions trigger post-reload nothing comes along to 
remove the nop logical operations.


The fix is trivial.  Just refine the condition.  I considered refining 
the operand predicates too.  Both are valid approaches.  I noticed the 
formatting was goofy, so fixed that while I was in there.


I'm aware of one other similar case, but I haven't concluded if it's a 
regression or not.


Tested in my tester.  Waiting for pre-commit CI to do its thing.


Jeff

gcc/
* config/riscv/bitmanip.md (*i_extrabit): Reject cases
where we only need to twiddle one bit.  Fix formatting.
*(andie_xtrabit): Likewise.

gcc/testsuite/

* gcc.target/riscv/redundant-andi.c: New test.
* gcc.target/riscv/redundant-ori.c: Likewise

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 684e5d2ae8b..b29c127bcb8 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1017,17 +1017,17 @@ (define_insn_and_split "*i_extrabit"
   [(set (match_operand:X 0 "register_operand" "=r")
(any_or:X (match_operand:X 1 "register_operand" "r")
  (match_operand:X 2 "uimm_extra_bit_or_twobits" "i")))]
-  "TARGET_ZBS"
+  "TARGET_ZBS && !single_bit_mask_operand (operands[2], VOIDmode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (:X (match_dup 1) (match_dup 3)))
(set (match_dup 0) (:X (match_dup 0) (match_dup 4)))]
 {
-   unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
-   unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
+  unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
 
-   operands[3] = GEN_INT (bits &~ topbit);
-   operands[4] = GEN_INT (topbit);
+  operands[3] = GEN_INT (bits &~ topbit);
+  operands[4] = GEN_INT (topbit);
 }
 [(set_attr "type" "bitmanip")])
 
@@ -1036,17 +1036,17 @@ (define_insn_and_split "*andi_extrabit"
   [(set (match_operand:X 0 "register_operand" "=r")
(and:X (match_operand:X 1 "register_operand" "r")
   (match_operand:X 2 "not_uimm_extra_bit_or_nottwobits" "i")))]
-  "TARGET_ZBS"
+  "TARGET_ZBS && !not_single_bit_mask_operand (operands[2], VOIDmode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
 {
-   unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
-   unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
+  unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
 
-   operands[3] = GEN_INT (bits | topbit);
-   operands[4] = GEN_INT (~topbit);
+  operands[3] = GEN_INT (bits | topbit);
+  operands[4] = GEN_INT (~topbit);
 }
 [(set_attr "type" "bitmanip")])
 
diff --git a/gcc/testsuite/gcc.target/riscv/redundant-andi.c 
b/gcc/testsuite/gcc.target/riscv/redundant-andi.c
new file mode 100644
index 000..8945faf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/redundant-andi.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+
+typedef struct sv SV;
+
+typedef struct magic MAGIC;
+typedef short I16;
+typedef unsigned short U16;
+typedef int I32;
+typedef unsigned int U32;
+struct sv
+{
+  U32 sv_refcnt;
+  U32 sv_flags;
+};
+struct magic
+{
+  U16 mg_private;
+};
+extern SV **PL_psig_ptr;
+int
+Perl_magic_setsig (SV *sv, MAGIC *mg, const char *s)
+{
+  I32 i;
+  i = (I16) mg->mg_private;
+  if (sv)
+{
+  PL_psig_ptr[i] = (++((sv)->sv_refcnt), ((SV *) ((void *) (sv;
+  ((sv)->sv_flags &= ~0x0008);
+}
+  else
+{
+  PL_psig_ptr[i] = ((void *) 0);
+}
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "andi\t" } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/redundant-ori.c 
b/gcc/testsuite/gcc.target/riscv/redundant-ori.c
new file mode 100644
index 000..e863343b561
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/redundant-ori.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+
+struct sv XS_constant__make_const_svz_2_0;
+struct sv {
+  int sv_flags;
+} XS_constant__make_const() {
+  struct sv *sv 

[COMMITTED 139/145] gccrs: Update pattern with \r* for dg-output tests

2025-03-17 Thread arthur . cohen
From: badumbatish 

First scan with "rg -v '\\r' gcc/testsuite/rust | rg 'dg-output'"

gcc/testsuite/ChangeLog:

* rust/execute/torture/issue-2187.rs:
Update pattern with \r* for dg-output tests
* rust/execute/xfail/macro1.rs: Likewise
---
 gcc/testsuite/rust/execute/torture/issue-2187.rs | 3 +--
 gcc/testsuite/rust/execute/xfail/macro1.rs   | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/rust/execute/torture/issue-2187.rs 
b/gcc/testsuite/rust/execute/torture/issue-2187.rs
index b5312575041..08246deba7f 100644
--- a/gcc/testsuite/rust/execute/torture/issue-2187.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-2187.rs
@@ -1,4 +1,4 @@
-/* { dg-output "L1\n\L2\nL3\nL4" } */
+/* { dg-output "L1\r*\n\L2\r*\nL3\r*\nL4" } */
 extern "C" {
 fn printf(s: *const i8, ...);
 }
@@ -20,4 +20,3 @@ L4\0";
 
 0
 }
-
diff --git a/gcc/testsuite/rust/execute/xfail/macro1.rs 
b/gcc/testsuite/rust/execute/xfail/macro1.rs
index eab5a0285cf..ab71941a231 100644
--- a/gcc/testsuite/rust/execute/xfail/macro1.rs
+++ b/gcc/testsuite/rust/execute/xfail/macro1.rs
@@ -1,4 +1,4 @@
-// { dg-output "macro\nmacro\nmacro\nmacro\n" }
+// { dg-output "macro\r*\nmacro\r*\nmacro\r*\nmacro\r*\n" }
 extern "C" {
 fn printf(s: *const i8, ...);
 }
-- 
2.45.2



[COMMITTED] doc: Regenerate common.opt.urls

2025-03-17 Thread Michal Jires
Regenerated common.opt.urls, which I missed until autobuilder noticed.

Committed as obvious.

gcc/ChangeLog:

* common.opt.urls: Regenerate.
---
 gcc/common.opt.urls | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index 79c322bed2b..ac602631179 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -935,6 +935,12 @@ UrlSuffix(gcc/Optimize-Options.html#index-flto)
 flto=
 UrlSuffix(gcc/Optimize-Options.html#index-flto)
 
+flto-incremental=
+UrlSuffix(gcc/Optimize-Options.html#index-flto-incremental)
+
+flto-incremental-cache-size=
+UrlSuffix(gcc/Optimize-Options.html#index-flto-incremental-cache-size)
+
 flto-partition=
 UrlSuffix(gcc/Optimize-Options.html#index-flto-partition)
 
-- 
2.48.1



[committed] testsuite: Add -gno-strict-dwarf option to dwarf2 inline[26].c tests

2025-03-17 Thread John David Anglin
Tested on hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu.  Committed
to trunk.

Dave
---

testsuite: Add -gno-strict-dwarf option to dwarf2 inline[26].c tests

Some targets default to strict dwarf.

2025-03-17  John David Anglin  

gcc/testsuite/ChangeLog:

PR testsuite/119220
* gcc.dg/debug/dwarf2/inline2.c: Add -gno-strict-dwarf option.
* gcc.dg/debug/dwarf2/inline6.c: Likewise.

diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c 
b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
index 6893ddfa2eb..f5d7e4efd16 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
@@ -16,7 +16,7 @@
 
 /* Explicitly use dwarf-2 because dwarf-5 might use DW_FORM_implicit_const
which is hard to scan for. */
-/* { dg-options "-O -g3 -gdwarf-2 -dA -fgnu89-inline" } */
+/* { dg-options "-O -g3 -gdwarf-2 -gno-strict-dwarf -dA -fgnu89-inline" } */
 /* { dg-do compile } */
 
 /* There are 6 inlined subroutines:
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c 
b/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c
index d7c86f89895..f271ebbcc80 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c
@@ -16,7 +16,7 @@
 
 /* Explicitly use dwarf-5 which uses DW_FORM_implicit_const.  */
 /* { dg-do compile } */
-/* { dg-options "-O -g3 -gdwarf-5 -dA -fgnu89-inline -gno-as-loc-support" } */
+/* { dg-options "-O -g3 -gdwarf-5 -gno-strict-dwarf -dA -fgnu89-inline 
-gno-as-loc-support" } */
 
 /* There are 6 inlined subroutines:
- One for each subroutine inlined into main, that's 3.


signature.asc
Description: PGP signature


[COMMITTED 134/145] rust: fix HIR dump for MatchExpr

2025-03-17 Thread arthur . cohen
From: Marc Poulhiès 

The visitor was still using the as_string() method.

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::do_matcharm): New.
(Dump::do_matchcase): New.
(Dump::visit(MatchExpr)): Adjust, don't use as_string.
* hir/rust-hir-dump.h (Dump::do_matcharm, Dump::do_matchcase): New.

Signed-off-by: Marc Poulhiès 
---
 gcc/rust/hir/rust-hir-dump.cc | 43 +--
 gcc/rust/hir/rust-hir-dump.h  |  2 ++
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index f0fd9141f5e..4ae9cba858d 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -352,6 +352,31 @@ Dump::do_expr (Expr &e)
   do_outer_attrs (oa);
 }
 
+void
+Dump::do_matcharm (MatchArm &e)
+{
+  begin ("MatchArm");
+  // FIXME Can't remember how to handle that. Let's see later.
+  // do_outer_attrs(e);
+  visit_collection ("match_arm_patterns", e.get_patterns ());
+  visit_field ("guard_expr", e.get_guard_expr ());
+  end ("MatchArm");
+}
+
+void
+Dump::do_matchcase (HIR::MatchCase &e)
+{
+  begin ("MatchCase");
+
+  begin_field ("arm");
+  do_matcharm (e.get_arm ());
+  end_field ("arm");
+
+  visit_field ("expr", e.get_expr ());
+
+  end ("MatchCase");
+}
+
 void
 Dump::do_pathexpr (PathExpr &e)
 {
@@ -1437,16 +1462,20 @@ Dump::visit (MatchExpr &e)
   begin ("MatchExpr");
   do_inner_attrs (e);
   do_expr (e);
+
   visit_field ("branch_value", e.get_scrutinee_expr ());
 
-  std::string str;
-  if (e.get_match_cases ().empty ())
-str = "none";
+  if (!e.has_match_arms ())
+{
+  put_field ("match_arms", "empty");
+}
   else
-for (const auto &arm : e.get_match_cases ())
-  str += "\n " + arm.as_string ();
-  put_field ("match_arms", str);
-
+{
+  begin_field ("match_arms");
+  for (auto &arm : e.get_match_cases ())
+   do_matchcase (arm);
+  end_field ("match_arms");
+}
   end ("MatchExpr");
 }
 
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index bb5c3606b51..b3a2020742f 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -100,6 +100,8 @@ private:
   void do_structfield (StructField &);
   void do_maybenamedparam (MaybeNamedParam &);
   void do_struct (Struct &);
+  void do_matcharm (MatchArm &);
+  void do_matchcase (MatchCase &);
 
   void visit (AST::Attribute &attribute);
   virtual void visit (Lifetime &) override;
-- 
2.45.2



New template for 'cpplib' made available

2025-03-17 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.  (If you have
any questions, send them to .)

A new POT file for textual domain 'cpplib' has been made available
to the language teams for translation.  It is archived as:

https://translationproject.org/POT-files/cpplib-15.1-b20250316.pot

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

Below is the URL which has been provided to the translators of your
package.  Please inform the translation coordinator, at the address
at the bottom, if this information is not current:

https://gcc.gnu.org/pub/gcc/snapshots/15-20250316/gcc-15-20250316.tar.xz

Translated PO files will later be automatically e-mailed to you.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




New Romanian PO file for 'cpplib' (version 15.1-b20250316)

2025-03-17 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'cpplib' has been submitted
by the Romanian team of translators.  The file is available at:

https://translationproject.org/latest/cpplib/ro.po

(This file, 'cpplib-15.1-b20250316.ro.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

https://translationproject.org/latest/cpplib/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

https://translationproject.org/domain/cpplib.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




[COMMITTED 143/145] gccrs: Fix ffi and enum conventions

2025-03-17 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* ast/rust-fmt.h (enum ParseMode):
Drop typedef in Cpp

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs:
Remove repr(C)
* libformat_parser/src/bin.rs: Use ffi
* libformat_parser/src/lib.rs: pub ffi, create ParseMode and match
rustc's parse mode
---
 gcc/rust/ast/rust-fmt.h   |  6 +--
 .../generic_format_parser/src/lib.rs  |  1 -
 libgrust/libformat_parser/src/bin.rs  |  2 +-
 libgrust/libformat_parser/src/lib.rs  | 43 ++-
 4 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 1db391bafe7..a54faec6381 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -258,11 +258,11 @@ struct FormatArgsHandle
   RustString rust_string;
 };
 
-typedef enum
+enum ParseMode
 {
-  Format,
+  Format = 0,
   InlineAsm,
-} ParseMode;
+};
 
 extern "C" {
 
diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index ad4d3d9a546..25f6b0ead17 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -78,7 +78,6 @@ enum InputStringKind {
 }
 
 /// The type of format string that we are parsing.
-#[repr(C)]
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum ParseMode {
 /// A normal format string as per `format_args!`.
diff --git a/libgrust/libformat_parser/src/bin.rs 
b/libgrust/libformat_parser/src/bin.rs
index a7947afb11c..a48d0066bf2 100644
--- a/libgrust/libformat_parser/src/bin.rs
+++ b/libgrust/libformat_parser/src/bin.rs
@@ -6,6 +6,6 @@ fn main() {
 None,
 None,
 false,
-generic_format_parser::ParseMode::Format
+libformat_parser::ffi::ParseMode::Format,
 ));
 }
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index 42ad62892bd..d920cfaa63d 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -24,7 +24,7 @@ where
 // FIXME: Make an ffi module in a separate file
 // FIXME: Remember to leak the boxed type somehow
 // FIXME: How to encode the Option type? As a pointer? Option -> Option<&T> 
-> *const T could work maybe?
-mod ffi {
+pub mod ffi {
 use super::IntoFFI;
 
 // FIXME: We need to ensure we deal with memory properly - whether it's 
owned by the C++ side or the Rust side
@@ -79,14 +79,14 @@ mod ffi {
 
 // TODO: Not needed for now?
 // /// The type of format string that we are parsing.
-// #[derive(Copy, Clone, Debug, Eq, PartialEq)]
-// #[repr(C)]
-// pub enum ParseMode {
-// /// A normal format string as per `format_args!`.
-// Format,
-// /// An inline assembly template string for `asm!`.
-// InlineAsm,
-// }
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[repr(C)]
+pub enum ParseMode {
+/// A normal format string as per `format_args!`.
+Format = 0,
+/// An inline assembly template string for `asm!`.
+InlineAsm,
+}
 
 /// A piece is a portion of the format string which represents the next 
part
 /// to emit. These are emitted as a stream by the `Parser` class.
@@ -327,17 +327,20 @@ mod ffi {
 
 // FIXME: Rename?
 pub mod rust {
-use generic_format_parser::{ParseMode, Parser, Piece};
-
+use crate::ffi::ParseMode;
+use generic_format_parser::{Parser, Piece};
 pub fn collect_pieces(
 input: &str,
 style: Option,
 snippet: Option,
 append_newline: bool,
-parse_mode: ParseMode
+parse_mode: ParseMode,
 ) -> Vec> {
-let parser = Parser::new(input, style, snippet, append_newline, 
parse_mode);
-
+let converted_parse_mode = match parse_mode {
+ParseMode::Format => generic_format_parser::ParseMode::Format,
+ParseMode::InlineAsm => 
generic_format_parser::ParseMode::InlineAsm,
+};
+let parser = Parser::new(input, style, snippet, append_newline, 
converted_parse_mode);
 parser.into_iter().collect()
 }
 }
@@ -361,12 +364,11 @@ pub struct RustString {
 #[repr(C)]
 pub struct FormatArgsHandle(PieceSlice, RustString);
 
-
 #[no_mangle]
 pub extern "C" fn collect_pieces(
 input: *const libc::c_char,
 append_newline: bool,
-parse_mode : generic_format_parser::ParseMode 
+parse_mode: crate::ffi::ParseMode,
 ) -> FormatArgsHandle {
 // FIXME: Add comment
 let str = unsafe { CStr::from_ptr(input) };
@@ -379,10 +381,11 @@ pub extern "C" fn collect_pieces(
 let s = unsafe { std::mem::transmute::<&'_ str, &'static str>(s) };
 
 // FIXME: No unwrap
-let pieces: Vec> = rust::collect_pieces(s, None, None, 
append_newline, parse_mode)
-.into_iter()
-.map(Into::into)
-.collect();
+  

[COMMITTED 126/145] gccrs: Added tl::expected to parse_operand

2025-03-17 Thread arthur . cohen
From: jjasmine 

Added tl::expected to parse_operand by implementing the validation
inside the parse_reg_operand function.

gcc/rust/ChangeLog:

* ast/rust-expr.h:
Added tl::expected to parse_operand
* expand/rust-macro-builtins-asm.cc (parse_reg): Likewise.
(parse_reg_operand): Likewise.
(parse_reg_operand_const): Likewise.
(parse_reg_operand_inout): Likewise.
(parse_asm_arg): Likewise.
* expand/rust-macro-builtins-asm.h: Likewise.

Signed-off-by: badumbatish 
---
 gcc/rust/ast/rust-expr.h   | 12 
 gcc/rust/expand/rust-macro-builtins-asm.cc | 72 +++---
 gcc/rust/expand/rust-macro-builtins-asm.h  | 14 ++---
 3 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index ba413da95df..9787e9ae123 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -5072,9 +5072,21 @@ private:
   std::vector outer_attrs;
 
 public:
+  // 
https://github.com/rust-lang/rust/blob/55cac26a9ef17da1c9c77c0816e88e178b7cc5dd/compiler/rustc_builtin_macros/src/asm.rs#L56C1-L64C7
+  //   let mut args = AsmArgs {
+  // templates: vec![first_template],
+  // operands: vec![],
+  // named_args: Default::default(),
+  // reg_args: Default::default(),
+  // clobber_abis: Vec::new(),
+  // options: ast::InlineAsmOptions::empty(),
+  // options_spans: vec![],
+  // };
   std::vector template_;
   std::vector template_strs;
   std::vector operands;
+  std::map named_args;
+  std::set reg_args;
   std::vector clobber_abi;
   std::set options;
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 7e484713ef7..05d8f866c61 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -143,7 +143,6 @@ parse_reg (InlineAsmContext &inline_asm_ctx)
   // after successful left parenthesis parsing, we should return ast of
   // InlineAsmRegOrRegClass of reg or reg class
   auto token = parser.peek_current_token ();
-  auto tok_id = token->get_id ();
   AST::InlineAsmRegOrRegClass reg_class;
   if (parser.skip_token (IDENTIFIER))
 {
@@ -151,7 +150,7 @@ parse_reg (InlineAsmContext &inline_asm_ctx)
   reg_class.type = RegType::RegClass;
   reg_class.reg_class.Symbol = token->as_string ();
 }
-  else if (tok_id == STRING_LITERAL)
+  else if (parser.skip_token (STRING_LITERAL))
 {
   // TODO: there is STRING_LITERAL, and BYTE_STRING_LITERAL, should we 
check
   // for both?
@@ -200,19 +199,30 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   AST::InlineAsmOperand reg_operand;
   auto token = parser.peek_current_token ();
   auto iden_token = parser.peek_current_token ();
+
+  tl::optional name = tl::nullopt;
   if (check_identifier (parser, ""))
 {
   auto equal_token = parser.peek_current_token ();
-  if (!parser.skip_token (EQUAL))
+
+  if (parser.skip_token (EQUAL))
{
- // TODO: Please handle this.
- rust_unreachable ();
+ name = token->as_string ();
+   }
+  else
+   {
+ rust_error_at (token->get_locus (),
+"expected operand, clobber_abi, options, or "
+"additional template string");
+ return tl::unexpected (COMMITTED);
}
 }
 
   tl::expected parsing_operand
 = tl::expected (inline_asm_ctx);
 
+  int slot = inline_asm_ctx.inline_asm.operands.size ();
+
   // Here is all parse_reg_operand functions we're using in a for loop
   auto parse_funcs = {parse_reg_operand_in,   parse_reg_operand_out,
  parse_reg_operand_lateout,   parse_reg_operand_inout,
@@ -226,10 +236,55 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
 {
   parsing_operand.emplace (inline_asm_ctx);
   parsing_operand.map (parse_func);
-  if (parsing_operand || parsing_operand.error () == COMMITTED)
+
+  // Per rust's asm.rs's structure
+  // After we've parse successfully, we break out and do a local validation
+  // of named, positional & explicit register operands
+
+  if (parsing_operand.has_value ())
+   break;
+  if (parsing_operand.error () == COMMITTED)
return parsing_operand;
 }
 
+  auto &inline_asm = inline_asm_ctx.inline_asm;
+
+  token = inline_asm_ctx.parser.peek_current_token ();
+  rust_debug_loc (token->get_locus (), "Here\n");
+  if (inline_asm_ctx.is_explicit)
+{
+  if (name != tl::nullopt)
+   {
+ rust_error_at (token->get_locus (),
+"explicit register arguments cannot have names");
+ return tl::unexpected (COMMITTED);
+   }
+  inline_asm.reg_args.insert (slot);
+}
+  else if (name != tl::nullopt)
+{
+  if (inline_asm.named_args.find (name.value ())
+ != inline_asm.named_args.end ())
+   {
+ rust_error_at (token->get_locus (), 

[COMMITTED 128/145] gccrs: Add WARN_UNUSED_RESULT parse error

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.h (enum InlineAsmParseError):
Add WARN_UNUSED_RESULT parse error
(enum WARN_UNUSED_RESULT): Likewise.

Signed-off-by: badumbatish 
---
 gcc/rust/expand/rust-macro-builtins-asm.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 32a8d0ba030..d3ca9340156 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -5,9 +5,10 @@
 #include "expected.h"
 #include "rust-macro-invoc-lexer.h"
 #include "rust/ast/rust-expr.h"
+#include "system.h"
 namespace Rust {
 
-enum InlineAsmParseError
+enum WARN_UNUSED_RESULT InlineAsmParseError
 {
   // Enum for InlineAsmParseError
 
-- 
2.45.2



Re: rs6000: Add -msplit-patch-nops (PR112980)

2025-03-17 Thread Michael Matz
Hey,

On Thu, 20 Feb 2025, Richard Biener wrote:

> > > +@opindex msplit-patch-nops
> > > +@item -msplit-patch-nops
> > > +When adding NOPs for a patchable area via the
> > > +@option{-fpatchable-function-entry} option emit the "before" NOPs in 
> > > front
> > > +of the global entry point and the "after" NOPs after the local entry 
> > > point.
> >
> > Please use TeX quotes ``before'' and ``after''.
> 
> The patch is OK for trunk with this change suggested by Andreas.  
> Please give powerpc target maintainers a week to object or perform an 
> review on their behalf.

Now in as 96698551.


Ciao,
Michael.


[PATCH v2 00/10] Improvements for the targets other than mips64r6

2025-03-17 Thread Aleksandar Rakic
From: Aleksandar Rakic 

Andrew Bennett (2):
  Only split shifts if using -mno-debugd
  Testsuite: Modify the gcc.dg/memcpy-4.c test

Jaydeep Patil (1):
  P5600: Option -msched-weight added

Matthew Fortune (3):
  Testsuite: Fix insn-*.c tests from trunk
  Testsuite: Adjust tests to cope with -mips16
  Testsuite: Skip tests making calls to variables

Robert Suchanek (1):
  Remove redundant moves

dragan.mladjenovic (1):
  nanoMIPS: unnecessary AND following an EXT

mfortune (2):
  Add -mgrow-frame-downwards
  Add offset shrinking pass (-mshrink-offsets)

 gcc/config/mips/mips.cc   | 618 ++
 gcc/config/mips/mips.h|  10 +-
 gcc/config/mips/mips.md   |  25 +
 gcc/config/mips/mips.opt  |  13 +-
 gcc/doc/invoke.texi   |  11 +
 gcc/fwprop.cc |  38 +-
 .../gcc.c-torture/compile/20020129-1.c|   5 +
 .../gcc.c-torture/compile/pr37433-1.c |   5 +
 gcc/testsuite/gcc.c-torture/compile/pr37433.c |   5 +
 gcc/testsuite/gcc.dg/memcpy-4.c   |   7 +-
 .../gcc.target/mips/call-clobbered-2.c|   3 +-
 .../gcc.target/mips/call-clobbered-3.c|   2 +-
 .../gcc.target/mips/call-clobbered-5.c|   2 +-
 gcc/testsuite/gcc.target/mips/ds-schedule-2.c |   4 +-
 gcc/testsuite/gcc.target/mips/insn-casesi.c   |   6 +-
 .../gcc.target/mips/insn-tablejump.c  |   6 +-
 .../gcc.target/mips/interrupt_handler-bug-1.c |   2 +-
 gcc/testsuite/gcc.target/mips/memcpy-2.c  |  12 +
 gcc/testsuite/gcc.target/mips/movdf-1.c   |   2 +-
 gcc/testsuite/gcc.target/mips/movdf-2.c   |   2 +-
 gcc/testsuite/gcc.target/mips/movdf-3.c   |   2 +-
 gcc/testsuite/gcc.target/mips/msa-builtins.c  | 334 +-
 gcc/testsuite/gcc.target/mips/msa.c   |  12 +-
 gcc/testsuite/gcc.target/mips/union-zext.c|  29 +
 gcc/testsuite/lib/target-supports.exp |  10 +
 25 files changed, 961 insertions(+), 204 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/memcpy-2.c
 create mode 100644 gcc/testsuite/gcc.target/mips/union-zext.c

-- 
2.34.1


[PATCH v2 09/10] Remove redundant moves

2025-03-17 Thread Aleksandar Rakic
From: Robert Suchanek 

These reloads happen because of different modes making elimination
non-trivial.

gcc/
* config/mips/mips.md: Add peepholes to remove silly moves.

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

Signed-off-by: Robert Suchanek 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.md | 24 
 1 file changed, 24 insertions(+)

diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 9813745dd95..5c2bfa4fa62 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5137,6 +5137,18 @@
   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
(set_attr "mode" "HI")])
 
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand")
+   (match_operand:HI 1 "register_operand"))
+   (set (match_operand:SI 2 "register_operand")
+   (match_operand:SI 3 "register_operand"))]
+  "TARGET_MIPS16
+   && REGNO (operands[1]) == REGNO (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])
+   && peep2_reg_dead_p (2, operands[3])"
+  [(const_int 0)]
+  "")
+
 ;; On the mips16, we can split lh $r,N($r) into an add and a load,
 ;; when the original load is a 4 byte instruction but the add and the
 ;; load are 2 2 byte instructions.
@@ -5213,6 +5225,18 @@
   [(set_attr "move_type" "move,move,move,const,constN,load,store,mflo")
(set_attr "mode" "QI")])
 
+(define_peephole2
+  [(set (match_operand:QI 0 "register_operand")
+   (match_operand:QI 1 "register_operand"))
+   (set (match_operand:SI 2 "register_operand")
+   (match_operand:SI 3 "register_operand"))]
+  "TARGET_MIPS16
+   && REGNO (operands[1]) == REGNO (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])
+   && peep2_reg_dead_p (2, operands[3])"
+  [(const_int 0)]
+  "")
+
 ;; On the mips16, we can split lb $r,N($r) into an add and a load,
 ;; when the original load is a 4 byte instruction but the add and the
 ;; load are 2 2 byte instructions.
-- 
2.34.1


[PATCH v2 09/12] Add -mmxu and -mno-mxu driver pass through

2025-03-17 Thread Aleksandar Rakic
From: Matthew Fortune 

gcc/
* config/mips/mips.h (ASM_SPEC): Add placeholders for -mmxu and
-mno-mxu.

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

Signed-off-by: Matthew Fortune 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index fb696ed9957..39584f43394 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1465,6 +1465,7 @@ struct mips_cpu_info {
 %{mloongson-ext2} %{mno-loongson-ext2} \
 %{msmartmips} %{mno-smartmips} \
 %{mmt} %{mno-mt} \
+%{mmxu} %{mno-mxu} \
 %{mfix-r5900} %{mno-fix-r5900} \
 %{mfix-rm7000} %{mno-fix-rm7000} \
 %{mfix-vr4120} %{mfix-vr4130} \
-- 
2.34.1


[PATCH v2 10/18] Add -march=interaptiv-mr2 with MIPS16E2

2025-03-17 Thread Aleksandar Rakic
From: Robert Suchanek 

- Bugfix [MIPS16E2]: split of moves of negative constants should exclude
zero const.

- Add support for every style of ZEB/ZEH support that has been tried:

An earlier attempt to improve generation of ZEB/ZEH led to a chaotic
effect of sometimes generating the instructions and sometimes retaining
the ANDI 0x. Also occasional generation of LHU/LBU appeared where
the original value was not already in memory.

Performance results are showing wild and unexpected variation which
appears to correlate with the way in which ZEH/ZEB handling is or is
not implemented. Support all forms tried so far with a hidden option
defaulting to the preferred method.

- Check to see if it is safe to use the SAVE/RESTORE instruction in a
function.

- Add interaptiv-mr2 architecture with COPYW/UCOPYW.

- Add -muse-copyw-ucopyw option (hidden from help).

- Disable tests at -O0 due to introducing a frame:

SAVE/RESTORE end up introducing a frame owing to saving more data
than strictly necessary.

gcc/
* config/mips/24k.md: Include the interaptiv_mr2 cpu.
* config/mips/mips-cpus.def: Add the interAptiv-mr2 CPU. Set
the PTF_AVOID_BRANCHLIKELY_ALWAYS flag.
* config/mips/mips-protos.h (mips_expand_block_move): Add the
alignment parameter.
(mips16_expand_copy): New prototype.
* config/mips/mips-tables.opt: Add the interaptiv-mr2
architecture.
* config/mips/mips.cc (MIPS_MAX_FIRST_STACK_STEP): Check the
TARGET_USE_SAVE_RESTORE flag.
(mips_rtx_cost_data): Add the INTERAPTIV_MR2 costs.
(mips_build_lower): Use PLUS for the mips16e2 target if the bit
15 isn't set.
(mips_small_data_pattern_1): Change return value type to bool.
(mips16_constant_cost): Add a case for IOR. Restrict to an
unsigned 16-bit number and the mips16e2 target.
(mips_constant_pool_symbol_in_sdata): New function.
(mips_output_move): Use the move instruction if the symbol is a
symbolic constant that addresses this function's rtl constants
pool and that can be used as the address in a MEM and whose
value will be calculated by adding a 16-bit offset from $gp.
(mips_use_by_pieces_infrastructure_p): Use COPYW for at least 2
words.
(mips_block_move_straight): Add the unused alignment parameter.
(mips_block_move_loop): Add the alignment parameter and use it.
(mips16_expand_copy): New function.
(mips_expand_block_move): Add the alignment parameter and use
it. Return false for the mips16 target if the (u)copy
instruction is not available. Use mips16_expand_copy otherwise.
(mips_compute_frame_info): Check if it is safe to use the
SAVE/RESTORE instruction in a function.
(mips_expand_prologue, mips_expand_epilogue): Check the
safe_to_use_save_restore flag.
(mips_option_override): Set default for TARGET_USE_COPYW_UCOPYW
and TARGET_USE_SAVE_RESTORE. Prevent using -muse-save-restore
and -muse-copyw_ucopyw with non-interaptiv-mr2 target.
* config/mips/mips.h (GENERATE_MIPS16E_SAVE_RESTORE): Update to
reference TARGET_USE_SAVE_RESTORE.
(TARGET_INTERAPTIV_MR2): New macro.
(MIPS_CPP_SET_PROCESSOR): Rename '-' to '_' in "interaptiv-mr2".
(MIPS_ISA_LEVEL_SPEC): Infer a -mips32r3 argument from an
-march=interaptiv-mr2 argument.
(MIPS_ASE_DSP_SPEC): Infer an -mdsp argument from an
-march=interaptiv* argument if -mno-dsp is not set. Infer an
-mmips16e2 argument from an -march=interaptiv-mr2 argument if
-mno-mips16e2 is not set.
(ISA_HAS_COPY): New macro.
(ASM_SPEC): Add a placeholder for the -mmips16-copy option.
(MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER): The (U)COPYW instruction
copies up to 4 words of data.
(MOVE_RATIO): Account for the (U)COPYW instructions.
(struct machine_function): New safe_to_use_save_restore flag.
* config/mips/mips.md (processor): Add the interaptiv_mr2 cpu.
(extvmisalign, extzvmisalign, insvmisalign):
Account for lwl/lwr/swl/swr instructions on the mips16e2 target.
(*movdi_32bit_mips16): Change the constraint "K" to "i" in order
to match the general integer constant instead of the unsigned
16-bit number on mips16 target.
(mips16_copy): New expand.
(mips16_copy_ofs): New insn.
(split): Split of moves of negative constants should exclude
zero const on mips16e2.
(cpymemsi): Check the ISA_HAS_COPY flag. Use the alignment.
(*mips16e_save_restore): Set an attribute "can_delay" to "no".
* config/mips/mips.opt (-muse-save-restore, -muse-copyw-ucopyw):
New hidden options.
* config/mips/predicates.md (small_data_pattern): Remove the
unspec and unspec_volatile codes.
* doc/invoke.texi (march): Add the interaptiv-mr2 p

[PATCH v2 02/10] Only split shifts if using -mno-debugd

2025-03-17 Thread Aleksandar Rakic
From: Andrew Bennett 

gcc/
* config/mips/mips.md (3): Check
TARGET_DEBUG_D_MODE before split.
* config/mips/mips.opt: Enable -mdebugd by default.

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

Signed-off-by: Andrew Bennett 
Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 gcc/config/mips/mips.md  | 1 +
 gcc/config/mips/mips.opt | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index f147667d63a..9813745dd95 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5833,6 +5833,7 @@
  be careful not to allocate a new register if we've reached the
  reload pass.  */
   if (TARGET_MIPS16
+  && !TARGET_DEBUG_D_MODE
   && optimize
   && CONST_INT_P (operands[2])
   && INTVAL (operands[2]) > 8
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index ec6ecd58f7b..faa8b529809 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -127,7 +127,7 @@ mdebug
 Target Var(TARGET_DEBUG_MODE) Undocumented
 
 mdebugd
-Target Var(TARGET_DEBUG_D_MODE) Undocumented
+Target Var(TARGET_DEBUG_D_MODE) Undocumented Init(1)
 
 meb
 Target RejectNegative Mask(BIG_ENDIAN)
-- 
2.34.1


[COMMITTED 001/145] gccrs: contrib: Add libgrust to update-copyright.py script

2025-03-17 Thread arthur . cohen
From: Sahil Yeole 

contrib/ChangeLog:
* update-copyright.py: Add libgrust folder.

Signed-off-by: Sahil Yeole 
---
 contrib/update-copyright.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/contrib/update-copyright.py b/contrib/update-copyright.py
index 0e45609d5eb..838c44f33eb 100755
--- a/contrib/update-copyright.py
+++ b/contrib/update-copyright.py
@@ -792,6 +792,7 @@ class GCCCmdLine (CmdLine):
 self.add_dir ('libgfortran')
 # libgo is imported from upstream.
 self.add_dir ('libgomp')
+self.add_dir ('libgrust')
 self.add_dir ('libiberty')
 self.add_dir ('libitm')
 self.add_dir ('libobjc')
@@ -819,6 +820,7 @@ class GCCCmdLine (CmdLine):
 'libgcc',
 'libgfortran',
 'libgomp',
+'libgrust',
 'libiberty',
 'libitm',
 'libobjc',
-- 
2.45.2



[COMMITTED 002/145] gccrs: git: Ignore libgrust build folders

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

ChangeLog:

* .gitignore: Add libgrust target folders to the ignore list.
---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitignore b/.gitignore
index f044fe16b5f..7150fc3b29c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,3 +71,6 @@ stamp-*
 /gmp*
 /isl*
 /gettext*
+
+# ADDITIONS from GCCRS front-end
+libgrust/*/target/
-- 
2.45.2



[COMMITTED 005/145] gccrs: borrowck: Polonius dump

2025-03-17 Thread arthur . cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* checks/errors/borrowck/polonius/rust-polonius.h (struct FullPoint):
Polonius facts dump.
(struct Facts): Polonius facts dump.
* checks/errors/borrowck/rust-bir-dump.cc (Dump::go):
Polonius facts dump.
(Dump::visit): Polonius facts dump.
(Dump::visit_place): Polonius facts dump.
(Dump::visit_move_place): Polonius facts dump.
(Dump::visit_scope): Polonius facts dump.
* checks/errors/borrowck/rust-borrow-checker.cc (BorrowChecker::go): 
Polonius facts dump.

Signed-off-by: Jakub Dupak 
---
 .../errors/borrowck/polonius/rust-polonius.h  |  2 +-
 .../checks/errors/borrowck/rust-bir-dump.cc   | 25 +--
 .../errors/borrowck/rust-borrow-checker.cc| 69 ++-
 3 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h 
b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
index fa73528ea85..b93906cdfc1 100644
--- a/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
+++ b/gcc/rust/checks/errors/borrowck/polonius/rust-polonius.h
@@ -148,7 +148,7 @@ struct Facts
   void dump_var_used_at (std::ostream &os) const
   {
 for (auto &e : var_used_at)
-  os << e.first - 1 << " " << FullPoint (e.second) << "\n";
+  os << e.first << " " << FullPoint (e.second) << "\n";
   }
 
   void dump_var_defined_at (std::ostream &os) const
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 45a071da565..a35f47b86d6 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -115,7 +115,7 @@ Dump::go (bool enable_simplify_cfg)
   if (enable_simplify_cfg)
 simplify_cfg (func, bb_fold_map);
 
-  renumber_places (func, place_map);
+  // renumber_places (func, place_map);
 
   stream << "fn " << name << "(";
   print_comma_separated (stream, func.arguments, [this] (PlaceId place_id) {
@@ -214,6 +214,8 @@ Dump::visit (const Statement &stmt)
   visit_place (stmt.get_place ());
   stream << ")";
   break;
+default:
+  rust_internal_error_at (UNKNOWN_LOCATION, "Unknown statement kind.");
 }
   statement_place = INVALID_PLACE;
 }
@@ -251,7 +253,8 @@ Dump::visit_place (PlaceId place_id)
   stream << "const " << get_tyty_name (place.tyty);
   break;
 case Place::INVALID:
-  stream << "_INVALID";
+  if (place_id == INVALID_PLACE)
+   stream << "_INVALID";
 }
 }
 
@@ -259,7 +262,7 @@ void
 Dump::visit_move_place (PlaceId place_id)
 {
   const Place &place = func.place_db[place_id];
-  if (!place.is_constant ())
+  if (place.should_be_moved ())
 stream << "move ";
   visit_place (place_id);
 }
@@ -267,7 +270,11 @@ Dump::visit_move_place (PlaceId place_id)
 void
 Dump::visit (const BorrowExpr &expr)
 {
-  stream << "&";
+  stream << "&"
+<< "'?" << expr.get_origin () << " ";
+  if (func.place_db.get_loans ()[expr.get_loan ()].mutability
+  == Mutability::Mut)
+stream << "mut ";
   visit_place (expr.get_place ());
 }
 
@@ -360,7 +367,15 @@ Dump::visit_scope (ScopeId id, size_t depth)
   indent (depth + 1) << "let _";
   stream << place_map[local] << ": "
 << get_tyty_name (func.place_db[local].tyty);
-  stream << ";\n";
+  stream << ";\t";
+
+  stream << "[";
+  print_comma_separated (stream,
+func.place_db[local].regions.get_regions (),
+[this] (FreeRegion region_id) {
+  stream << "'?" << region_id;
+});
+  stream << "]\n";
 }
   for (auto &child : scope.children)
 visit_scope (child, (id >= 1) ? depth + 1 : depth);
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
index 8380f2c5cfa..e41cea33b3b 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
@@ -18,9 +18,10 @@
 
 #include "rust-borrow-checker.h"
 #include "rust-function-collector.h"
+#include "rust-bir-fact-collector.h"
 #include "rust-bir-builder.h"
 #include "rust-bir-dump.h"
-#include "rust-bir-fact-collector.h"
+#include "polonius/rust-polonius.h"
 
 namespace Rust {
 namespace HIR {
@@ -36,7 +37,7 @@ mkdir_wrapped (const std::string &dirname)
 #elif __APPLE__
   ret = mkdir (dirname.c_str (), 0775);
 #endif
-  (void) ret;
+  rust_assert (ret == 0 || errno == EEXIST);
 }
 
 void
@@ -68,6 +69,8 @@ BorrowChecker::go (HIR::Crate &crate)
= mappings->get_crate_name (crate.get_mappings ().get_crate_num (),
crate_name);
   rust_assert (ok);
+
+  mkdir_wrapped ("nll_facts_gccrs");
 }
 
   FunctionCollector collector;
@@ -75,6 +78,9 @@ BorrowChecker::go (HIR::Crate &crate)
 
   for (auto func : collector.get_functions

[COMMITTED 007/145] gccrs: borrowck: Link Polonius and run it

2025-03-17 Thread arthur . cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* Make-lang.in: Link Polonius.
* checks/errors/borrowck/rust-borrow-checker.cc: Run Polonius.

Signed-off-by: Jakub Dupak 
---
 gcc/rust/Make-lang.in  | 9 ++---
 gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc | 2 ++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 795e899f51c..4f164c9753a 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -225,12 +225,15 @@ rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
 LIBFORMAT_PARSER = ../libgrust/libformat_parser/debug/liblibformat_parser.a
+LIBFFI_POLONIUS = rust/libffi_polonius.a
 
 # The compiler itself is called crab1
-crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) 
$(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) $(rust.prev)
+crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS) 
$(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) $(LIBFFI_POLONIUS) $(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(CRAB1_LIBS) 
$(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) \
+ $(LIBS) $(CRAB1_LIBS) $(LIBPROC_MACRO_INTERNAL) 
$(LIBFORMAT_PARSER) $(LIBFFI_POLONIUS) \
+ $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
 
 # Build hooks.
@@ -493,4 +496,4 @@ rust/libffi_polonius.a: \
rust/checks/errors/borrowck/ffi-polonius/Cargo.toml \
$(wildcard $(srcdir)/rust/checks/errors/borrowck/ffi-polonius/src/*)
cargo build --manifest-path 
$(srcdir)/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml --release 
--target-dir rust/ffi-polonius
-   cp rust/ffi-polonius/release/libffi_polonius.a rust/libffi_polonius.a
\ No newline at end of file
+   cp rust/ffi-polonius/release/libffi_polonius.a rust/libffi_polonius.a
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
index e41cea33b3b..12334b11dd7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
@@ -154,6 +154,8 @@ BorrowChecker::go (HIR::Crate &crate)
  dump_facts_to_file ("placeholder",
  &Polonius::Facts::dump_placeholder);
}
+
+  Polonius::polonius_run (facts.freeze (), rust_be_debug_p ());
 }
 
   for (auto closure ATTRIBUTE_UNUSED : collector.get_closures ())
-- 
2.45.2



[COMMITTED 009/145] gccrs: borrowck: Testsuite

2025-03-17 Thread arthur . cohen
From: Jakub Dupak 

gcc/testsuite/ChangeLog:

* rust/borrowck/borrowck.exp: New test.
* rust/borrowck/position_dependant_outlives.rs: New test.
* rust/borrowck/reference.rs: New test.
* rust/borrowck/return_ref_to_local.rs: New test.
* rust/borrowck/subset.rs: New test.
* rust/borrowck/test_move.rs: New test.
* rust/borrowck/test_move_behind_reference.rs: New test.
* rust/borrowck/test_move_conditional.rs: New test.
* rust/borrowck/tmp.rs: New test.
* rust/borrowck/use_while_mut.rs: New test.
* rust/borrowck/use_while_mut_fr.rs: New test.
* rust/borrowck/well_formed_function_inputs.rs: New test.
---
 gcc/testsuite/rust/borrowck/borrowck.exp  | 35 +++
 .../borrowck/position_dependant_outlives.rs   | 11 +++
 gcc/testsuite/rust/borrowck/reference.rs  | 99 +++
 .../rust/borrowck/return_ref_to_local.rs  |  6 ++
 gcc/testsuite/rust/borrowck/subset.rs | 27 +
 gcc/testsuite/rust/borrowck/test_move.rs  | 16 +++
 .../borrowck/test_move_behind_reference.rs| 27 +
 .../rust/borrowck/test_move_conditional.rs| 28 ++
 gcc/testsuite/rust/borrowck/tmp.rs| 79 +++
 gcc/testsuite/rust/borrowck/use_while_mut.rs  |  7 ++
 .../rust/borrowck/use_while_mut_fr.rs |  8 ++
 .../borrowck/well_formed_function_inputs.rs   | 16 +++
 12 files changed, 359 insertions(+)
 create mode 100644 gcc/testsuite/rust/borrowck/borrowck.exp
 create mode 100644 gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
 create mode 100644 gcc/testsuite/rust/borrowck/reference.rs
 create mode 100644 gcc/testsuite/rust/borrowck/return_ref_to_local.rs
 create mode 100644 gcc/testsuite/rust/borrowck/subset.rs
 create mode 100644 gcc/testsuite/rust/borrowck/test_move.rs
 create mode 100644 gcc/testsuite/rust/borrowck/test_move_behind_reference.rs
 create mode 100644 gcc/testsuite/rust/borrowck/test_move_conditional.rs
 create mode 100644 gcc/testsuite/rust/borrowck/tmp.rs
 create mode 100644 gcc/testsuite/rust/borrowck/use_while_mut.rs
 create mode 100644 gcc/testsuite/rust/borrowck/use_while_mut_fr.rs
 create mode 100644 gcc/testsuite/rust/borrowck/well_formed_function_inputs.rs

diff --git a/gcc/testsuite/rust/borrowck/borrowck.exp 
b/gcc/testsuite/rust/borrowck/borrowck.exp
new file mode 100644
index 000..6e96a7d11d8
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/borrowck.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2021-2023 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Compile tests, no torture testing.
+#
+# These tests raise errors in the front end; torture testing doesn't apply.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs 
b/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
new file mode 100644
index 000..7856934a6b3
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/position_dependant_outlives.rs
@@ -0,0 +1,11 @@
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
+
+pub fn position_dependent_outlives<'a>(x: &'a mut i32, cond: bool) -> &'a mut 
i32 {
+let y = &mut *x;
+if cond {
+return y;
+} else {
+*x = 0;
+return x;
+}
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/borrowck/reference.rs 
b/gcc/testsuite/rust/borrowck/reference.rs
new file mode 100644
index 000..b825a9686b7
--- /dev/null
+++ b/gcc/testsuite/rust/borrowck/reference.rs
@@ -0,0 +1,99 @@
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
+
+
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Reference<'a> {
+value: &'a i32,
+}
+
+impl<'a> Reference<'a> {
+fn new<'a>(value: &'a i32) -> Reference<'a> {
+Reference { value: value }
+}
+}
+
+struct ReferenceMut<'a> {
+value: &'a mut i32,
+}
+
+impl<'a> ReferenceMut<'a> {
+fn new<'a>(value: &'a mut i32) -> ReferenceMut<'a> {
+ReferenceMut { value: value }
+}
+}
+
+fn immutable_bo

[COMMITTED 003/145] gccrs: Remove redundant macro definition

2025-03-17 Thread arthur . cohen
From: zhanghe9702 

gcc/rust/ChangeLog:
* backend/rust-tree.h: removing the CLASSTYPE_VBASECLASSES macro
which is duplicated three times.

Signed-off-by: Zhang He 
---
 gcc/rust/backend/rust-tree.h | 12 
 1 file changed, 12 deletions(-)

diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 1847267c557..bb99684b2bf 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -139,12 +139,6 @@
should be initialized.)  */
 #define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
 
-/* A vector of BINFOs for the direct and indirect virtual base classes
-   that this type uses in a post-order depth-first left-to-right
-   order.  (In other words, these bases appear in the order that they
-   should be initialized.)  */
-#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
-
 /* We used to have a variant type for lang_type.  Keep the name of the
checking accessor for the sole survivor.  */
 #define LANG_TYPE_CLASS_CHECK(NODE) (TYPE_LANG_SPECIFIC (NODE))
@@ -783,12 +777,6 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
 #define CLASSTYPE_PRIMARY_BINFO(NODE)  
\
   (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)
 
-/* A vector of BINFOs for the direct and indirect virtual base classes
-   that this type uses in a post-order depth-first left-to-right
-   order.  (In other words, these bases appear in the order that they
-   should be initialized.)  */
-#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
-
 /* The type corresponding to NODE when NODE is used as a base class,
i.e., NODE without virtual base classes or tail padding.  */
 #define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base)
-- 
2.45.2



[COMMITTED 006/145] gccrs: borrowck: Build Polonius automatically

2025-03-17 Thread arthur . cohen
From: Jakub Dupak 

This is minimalistic version to build Polonius with Cargo.

gcc/rust/ChangeLog:

* Make-lang.in: Build Polonius.

Signed-off-by: Jakub Dupak 
---
 gcc/rust/Make-lang.in | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 33176df6d7a..795e899f51c 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -264,6 +264,7 @@ rust.srcman:
 # Clean hooks.
 
 rust.mostlyclean:
+   rm -rf rust/ffi-polonius/release libffi_polonius.a
 #  cd $(srcdir)/rust; rm -f *.o y.tab.h y.tab.c lex.yy.c
 
 rust.clean: rust.mostlyclean
@@ -487,3 +488,9 @@ rust/%.o: rust/checks/errors/borrowck/%.cc
 rust/%.o: rust/metadata/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+
+rust/libffi_polonius.a: \
+   rust/checks/errors/borrowck/ffi-polonius/Cargo.toml \
+   $(wildcard $(srcdir)/rust/checks/errors/borrowck/ffi-polonius/src/*)
+   cargo build --manifest-path 
$(srcdir)/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml --release 
--target-dir rust/ffi-polonius
+   cp rust/ffi-polonius/release/libffi_polonius.a rust/libffi_polonius.a
\ No newline at end of file
-- 
2.45.2



[COMMITTED 067/145] gccrs: Parse raw ref operator

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

The raw ref operator is an unstable feature required to obtain a pointer
to unaligned adresses (mainly unaligned struct fields) without UB.

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::ref): Adapt constructor to the new
API.
* ast/rust-ast-collector.cc (TokenCollector::visit): Emit a raw weak
keyword when required.
* ast/rust-ast.cc (BorrowExpr::as_string): Change as_string
representation to handle raw ref operator.
* ast/rust-expr.h (class BorrowExpr): Add raw discriminant.
* expand/rust-macro-builtins-include.cc: Adapt constructor to the new
API.
* parse/rust-parse-impl.h: Handle the raw weak keyword.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-ast-builder.cc  |  5 +-
 gcc/rust/ast/rust-ast-collector.cc| 17 ++-
 gcc/rust/ast/rust-ast.cc  | 18 ++--
 gcc/rust/ast/rust-expr.h  | 16 ---
 .../expand/rust-macro-builtins-include.cc |  7 ++-
 gcc/rust/parse/rust-parse-impl.h  | 46 ---
 6 files changed, 86 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index f4ef003adbb..4679aa7b0f1 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -19,6 +19,7 @@
 #include "rust-ast-builder.h"
 #include "rust-ast-full-decls.h"
 #include "rust-ast-full.h"
+#include "rust-common.h"
 #include "rust-expr.h"
 #include "rust-token.h"
 #include "rust-make-unique.h"
@@ -122,8 +123,10 @@ Builder::let (std::unique_ptr pattern, 
std::unique_ptr type,
 std::unique_ptr
 Builder::ref (std::unique_ptr &&of, bool mut) const
 {
+  auto mutability = mut ? Mutability::Mut : Mutability::Imm;
   return std::unique_ptr (
-new BorrowExpr (std::move (of), mut, /* is double */ false, {}, loc));
+new BorrowExpr (std::move (of), mutability,
+   /* raw */ false, /* is double */ false, {}, loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index d43aef80760..bc8bc9caabe 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -843,8 +843,21 @@ TokenCollector::visit (BorrowExpr &expr)
   push (Rust::Token::make (AMP, expr.get_locus ()));
   if (expr.get_is_double_borrow ())
 push (Rust::Token::make (AMP, UNDEF_LOCATION));
-  if (expr.get_is_mut ())
-push (Rust::Token::make (MUT, UNDEF_LOCATION));
+
+  if (expr.is_raw_borrow ())
+{
+  push (Rust::Token::make_identifier (expr.get_locus (),
+ Values::WeakKeywords::RAW));
+  if (expr.get_is_mut ())
+   push (Rust::Token::make (MUT, UNDEF_LOCATION));
+  else
+   push (Rust::Token::make (CONST, UNDEF_LOCATION));
+}
+  else
+{
+  if (expr.get_is_mut ())
+   push (Rust::Token::make (MUT, UNDEF_LOCATION));
+}
 
   visit (expr.get_borrowed_expr ());
 }
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 8045a688510..38cb7cfdc64 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rust-ast.h"
 #include "optional.h"
 #include "rust-builtin-ast-nodes.h"
+#include "rust-common.h"
 #include "rust-system.h"
 #include "rust-ast-full.h"
 #include "rust-diagnostics.h"
@@ -1570,12 +1571,19 @@ BorrowExpr::as_string () const
 
   std::string str ("&");
 
-  if (double_borrow)
-str += "&";
-
-  if (is_mut)
-str += "mut ";
+  if (raw_borrow)
+{
+  str += "raw ";
+  str += get_is_mut () ? "const " : "mut ";
+}
+  else
+{
+  if (double_borrow)
+   str += "&";
 
+  if (get_is_mut ())
+   str += "mut ";
+}
   str += main_or_left_expr->as_string ();
 
   return str;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 50c0cb146ed..6609ad80b37 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2,6 +2,7 @@
 #define RUST_AST_EXPR_H
 
 #include "rust-ast.h"
+#include "rust-common.h"
 #include "rust-path.h"
 #include "rust-macro.h"
 #include "rust-operators.h"
@@ -370,18 +371,20 @@ public:
  * overloaded. */
 class BorrowExpr : public OperatorExpr
 {
-  bool is_mut;
+  Mutability mutability;
+  bool raw_borrow;
   bool double_borrow;
 
 public:
   std::string as_string () const override;
 
-  BorrowExpr (std::unique_ptr borrow_lvalue, bool is_mut_borrow,
- bool is_double_borrow, std::vector outer_attribs,
- location_t locus)
+  BorrowExpr (std::unique_ptr borrow_lvalue, Mutability mutability,
+ bool raw_borrow, bool is_double_borrow,
+ std::vector outer_attribs, location_t locus)
 : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs),
locus),
-  is_mut (is_mut_borrow), double_borrow (is_double_bor

[COMMITTED 063/145] gccrs: Add dropck_eyepatch feature gate for may_dangle

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

Add a new feature gate for may_dangle generic param outer attributes.

gcc/rust/ChangeLog:

* checks/errors/rust-feature-gate.cc: Visit and gate may_dangle
attributes.
* checks/errors/rust-feature-gate.h: Update visit function prototype
and add a new member function to check on a set of attributes whether
one is may_dangle.
* checks/errors/rust-feature.cc (Feature::create): Add new
dropck_eyepatch feature.
* checks/errors/rust-feature.h: Likewise.
* util/rust-attribute-values.h: Add new may_dangle attribute value.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/checks/errors/rust-feature-gate.cc | 37 +
 gcc/rust/checks/errors/rust-feature-gate.h  |  8 +++--
 gcc/rust/checks/errors/rust-feature.cc  |  4 +++
 gcc/rust/checks/errors/rust-feature.h   |  1 +
 gcc/rust/util/rust-attribute-values.h   |  1 +
 5 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 69348cb90e8..16c5ecee6cb 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -18,6 +18,7 @@
 
 #include "rust-feature-gate.h"
 #include "rust-abi.h"
+#include "rust-attribute-values.h"
 #include "rust-ast-visitor.h"
 #include "rust-feature.h"
 
@@ -123,6 +124,19 @@ FeatureGate::check_rustc_attri (const 
std::vector &attributes)
 }
 }
 
+void
+FeatureGate::check_may_dangle_attribute (
+  const std::vector &attributes)
+{
+  for (const AST::Attribute &attr : attributes)
+{
+  if (attr.get_path ().as_string () == Values::Attributes::MAY_DANGLE)
+   gate (Feature::Name::DROPCK_EYEPATCH, attr.get_locus (),
+ "`may_dangle` has unstable semantics and may be removed in the "
+ "future");
+}
+}
+
 void
 FeatureGate::visit (AST::MacroRulesDefinition &rules_def)
 {
@@ -153,6 +167,8 @@ FeatureGate::visit (AST::TraitImpl &impl)
   if (impl.is_exclam ())
 gate (Feature::Name::NEGATIVE_IMPLS, impl.get_locus (),
  "negative_impls are not yet implemented");
+
+  AST::DefaultASTVisitor::visit (impl);
 };
 
 void
@@ -164,4 +180,25 @@ FeatureGate::visit (AST::BoxExpr &expr)
   AST::DefaultASTVisitor::visit (expr);
 }
 
+void
+FeatureGate::visit (AST::LifetimeParam &lifetime_param)
+{
+  check_may_dangle_attribute (lifetime_param.get_outer_attrs ());
+  AST::DefaultASTVisitor::visit (lifetime_param);
+}
+
+void
+FeatureGate::visit (AST::ConstGenericParam &const_param)
+{
+  check_may_dangle_attribute (const_param.get_outer_attrs ());
+  AST::DefaultASTVisitor::visit (const_param);
+}
+
+void
+FeatureGate::visit (AST::TypeParam ¶m)
+{
+  check_may_dangle_attribute (param.get_outer_attrs ());
+  AST::DefaultASTVisitor::visit (param);
+}
+
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h 
b/gcc/rust/checks/errors/rust-feature-gate.h
index bef7cf1b449..5ead1103086 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -40,8 +40,8 @@ public:
   void visit (AST::AttrInputMetaItemContainer &input) override {}
   void visit (AST::IdentifierExpr &ident_expr) override {}
   void visit (AST::Lifetime &lifetime) override {}
-  void visit (AST::LifetimeParam &lifetime_param) override {}
-  void visit (AST::ConstGenericParam &const_param) override {}
+  void visit (AST::LifetimeParam &lifetime_param) override;
+  void visit (AST::ConstGenericParam &const_param) override;
   void visit (AST::PathInExpression &path) override {}
   void visit (AST::TypePathSegment &segment) override {}
   void visit (AST::TypePathSegmentGeneric &segment) override {}
@@ -104,7 +104,7 @@ public:
   void visit (AST::MatchExpr &expr) override {}
   void visit (AST::AwaitExpr &expr) override {}
   void visit (AST::AsyncBlockExpr &expr) override {}
-  void visit (AST::TypeParam ¶m) override {}
+  void visit (AST::TypeParam ¶m) override;
   void visit (AST::LifetimeWhereClauseItem &item) override {}
   void visit (AST::TypeBoundWhereClauseItem &item) override {}
   void visit (AST::Module &module) override {}
@@ -188,6 +188,8 @@ public:
 private:
   void gate (Feature::Name name, location_t loc, const std::string &error_msg);
   void check_rustc_attri (const std::vector &attributes);
+  void
+  check_may_dangle_attribute (const std::vector &attributes);
   std::set valid_features;
 };
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature.cc 
b/gcc/rust/checks/errors/rust-feature.cc
index f993bbb7245..b9a648e62ef 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/rust-feature.cc
@@ -48,6 +48,9 @@ Feature::create (Feature::Name name)
 case Feature::Name::BOX_SYNTAX:
   return Feature (Feature::Name::BOX_SYNTAX, Feature::State::ACTIVE,
  "box_syntax", "1.0.0", 49733, tl::nullopt, "");
+case Feature::Name::DROPC

[COMMITTED 076/145] gccrs: Introduce first implementation of parse_clobber_abi

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_clobber_abi): title.
(parseAsmArg): title.
* expand/rust-macro-builtins-asm.h (parse_clobber_abi): title.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 76 +-
 gcc/rust/expand/rust-macro-builtins-asm.h  |  7 +-
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index f26c4610230..9d904d6223e 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -26,6 +26,80 @@ parseDirSpec (Parser &parser, TokenId 
last_token_id)
   return tl::nullopt;
 }
 
+int
+parse_clobber_abi (Parser &parser, TokenId last_token_id,
+  AsmArg &args)
+{
+  // clobber_abi := "clobber_abi("  *("," ) [","] ")"
+
+  // PARSE EVERYTHING COMMITTEDLY IN THIS FUNCTION, WE CONFIRMED VIA 
clobber_abi
+  // identifier keyword
+
+  if (!parser.skip_token (LEFT_PAREN))
+{
+  // TODO: Raise error exactly like rustc if left parenthesis is not
+  // encountered.
+  return -1;
+}
+
+  if (parser.skip_token (RIGHT_PAREN))
+{
+  // TODO: We encountered a "clobber_abi()", which should be illegal?
+  // 
https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_builtin_macros/src/asm.rs#L381
+  return -1;
+}
+
+  ClobberAbis new_abis;
+
+  auto token = parser.peek_current_token ();
+
+  while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN)
+{
+  // Check if it is a string literal or not, codename:  in ABNF
+  if (token->get_id () == STRING_LITERAL)
+   {
+ // TODO: Caring for span in here.
+ new_abis.push_back (token->as_string ());
+   }
+  else
+   {
+ // TODO: We encountered something that is not string literal, which
+ // should be illegal, please emit the correct error
+ // 
https://github.com/rust-lang/rust/blob/b92758a9aef1cef7b79e2b72c3d8ba113e547f89/compiler/rustc_builtin_macros/src/asm.rs#L387
+   }
+
+  if (parser.skip_token (RIGHT_PAREN))
+   {
+ break;
+   }
+
+  if (!parser.skip_token (COMMA))
+   {
+ // TODO: If the skip of comma is unsuccessful, which should be
+ // illegal, pleaes emit the correct error.
+ return -1;
+   }
+
+  // Done processing the local clobber abis, push that to the main Args in
+  // argument
+
+  for (auto abi : new_abis)
+   {
+ args.clobber_abis.push_back (abi);
+   }
+
+  return 0;
+}
+}
+
+int
+parse_options (Parser &parser, TokenId last_token_id,
+  AsmArg &args, bool is_global_asm)
+{
+  // Parse everything commitedly
+  if (!p.skip_token (LEFT_PAREN))
+{}
+}
 bool
 check_identifier (Parser &p, std::string ident)
 {
@@ -115,7 +189,7 @@ parseAsmArg (Parser &parser, TokenId 
last_token_id,
   // Ok after the left paren is good, we better be parsing correctly
   // everything in here, which is operand in ABNF
 
-  // TODO: Parse clobber abi
+  // TODO: Parse clobber abi, eat the identifier named "clobber_abi" if 
true
   if (check_identifier (parser, "clobber_abi"))
{
  std::cout << "Clobber abi tee hee" << std::endl;
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 3a67c7e3152..ebb939a0548 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -37,7 +37,7 @@ typedef std::string symbol_name;
 typedef std::vector Templates;
 typedef std::vector Operands;
 typedef std::map RegisterArgs;
-typedef std::map ClobberAbis;
+typedef std::vector ClobberAbis;
 typedef std::map NamedValues;
 
 struct AsmArg
@@ -84,4 +84,9 @@ parse_options (Parser &parser, TokenId 
last_token_id,
 tl::optional
 parse_reg (Parser &parser, TokenId last_token_id, AsmArg 
&args,
   bool is_explicit);
+
+int
+parse_clobber_abi (Parser &parser, TokenId last_token_id,
+  AsmArg &args);
+
 } // namespace Rust
\ No newline at end of file
-- 
2.45.2



[COMMITTED 079/145] gccrs: First draft of parse_option finished

2025-03-17 Thread arthur . cohen
From: jjasmine 

Finish up on parse_option, formatted parse_clobber_abi
gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_clobber_abi): format
(check_and_set): helper function, is try_set_option equivalent
(parse_options): new function
* expand/rust-macro-builtins-asm.h (enum InlineAsmOptions):
removed
(check_and_set): decl of helper function
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 84 +-
 gcc/rust/expand/rust-macro-builtins-asm.h  |  8 +--
 2 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 74b81d2aed2..971dd7b7e75 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -79,6 +79,8 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
  // illegal, pleaes emit the correct error.
  return -1;
}
+
+  token = parser.peek_current_token ();
 }
 
   // Done processing the local clobber abis, push that to the main Args in
@@ -92,12 +94,26 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
   return 0;
 }
 
+void
+check_and_set (Parser &p, AsmArg &args, std::string option)
+{
+  if (args.options.count (option) == 1)
+{
+  // TODO: report an error of duplication
+
+  return;
+}
+  else
+{
+  args.options.insert (option);
+}
+}
 int
 parse_options (Parser &parser, TokenId last_token_id,
   AsmArg &args, bool is_global_asm)
 {
   // Parse everything commitedly
-  if (!p.skip_token (LEFT_PAREN))
+  if (!parser.skip_token (LEFT_PAREN))
 {
   // We have shifted `options` to search for the left parenthesis next, we
   // should error out if this is not possible.
@@ -108,9 +124,73 @@ parse_options (Parser &parser, TokenId 
last_token_id,
   auto token = parser.peek_current_token ();
   while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN)
 {
-  parser.skip_token ();
+  if (!is_global_asm && check_identifier (parser, "pure"))
+   {
+ check_and_set (parser, args, "pure");
+   }
+  else if (!is_global_asm && check_identifier (parser, "nomem"))
+   {
+ check_and_set (parser, args, "nomem");
+   }
+  else if (!is_global_asm && check_identifier (parser, "readonly"))
+   {
+ check_and_set (parser, args, "readonly");
+   }
+  else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
+   {
+ check_and_set (parser, args, "preserves_flags");
+   }
+  else if (!is_global_asm && check_identifier (parser, "noreturn"))
+   {
+ check_and_set (parser, args, "noreturn");
+   }
+  else if (!is_global_asm && check_identifier (parser, "noreturn"))
+   {
+ check_and_set (parser, args, "noreturn");
+   }
+  else if (!is_global_asm && check_identifier (parser, "nostack"))
+   {
+ check_and_set (parser, args, "nostack");
+   }
+  else if (!is_global_asm && check_identifier (parser, "may_unwind"))
+   {
+ check_and_set (parser, args, "may_unwind");
+   }
+  else if (check_identifier (parser, "att_syntax"))
+   {
+ check_and_set (parser, args, "att_syntax");
+   }
+  else if (check_identifier (parser, "raw"))
+   {
+ check_and_set (parser, args, "raw");
+   }
+  else
+   {
+ // TODO: Unexpected error, please return the correct error
+ rust_error_at (token->get_locus (),
+"Unexpected token encountered in parse_options");
+   }
+  if (!parser.skip_token (RIGHT_PAREN))
+   {
+ break;
+   }
+
+  if (!parser.skip_token (COMMA))
+   {
+ // TODO: If the skip of comma is unsuccessful, which should be
+ // illegal, pleaes emit the correct error.
+ return -1;
+   }
+
   token = parser.peek_current_token ();
 }
+
+  // TODO: Per rust asm.rs regarding options_spans
+  // I'm guessing this has to do with some error reporting.
+  // let new_span = span_start.to(p.prev_token.span);
+  // args.options_spans.push(new_span);
+
+  return 0;
 }
 bool
 check_identifier (Parser &p, std::string ident)
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index ebb939a0548..fd86c309c9a 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -21,11 +21,6 @@ enum InlineAsmDirSpec
   Label, // TODO: This is not present in ABNF
 };
 
-enum InlineAsmOptions
-{
-
-};
-
 // Place holder for classes
 enum InlineAsmRegOrRegClass
 {
@@ -39,6 +34,7 @@ typedef std::vector Operands;
 typedef std::map RegisterArgs;
 typedef std::vector ClobberAbis;
 typedef std::map NamedValues;
+typedef std::set InlineAsmOptions;
 
 struct AsmArg
 {
@@ -70,6 +66,8 @@ parse_asm (location_t invoc_locus

[COMMITTED 092/145] gccrs: Scaffolding parse_reg

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct InlineAsmRegOrRegClass):
Scaffolding parse_reg
* expand/rust-macro-builtins-asm.cc (parse_reg): Likewise.
(parse_operand): Likewise.
(parseAsmArg): Likewise.
---
 gcc/rust/ast/rust-expr.h  |  6 +++
 .../errors/borrowck/ffi-polonius/Cargo.lock   | 39 +++
 gcc/rust/expand/rust-macro-builtins-asm.cc| 49 ++-
 3 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 719a76cdbb3..309174057c0 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4743,6 +4743,12 @@ struct InlineAsmRegOrRegClass
 std::string Symbol;
   };
 
+  Type type;
+  union
+  {
+struct Reg reg;
+struct RegClass regClass;
+  };
   Identifier name;
   location_t locus;
 };
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
new file mode 100644
index 000..55cc71157ae
--- /dev/null
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
@@ -0,0 +1,39 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "datafrog"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
+
+[[package]]
+name = "ffi-polonius"
+version = "0.1.0"
+dependencies = [
+ "polonius-engine",
+]
+
+[[package]]
+name = "log"
+version = "0.4.21"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+
+[[package]]
+name = "polonius-engine"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c4e8e505342045d397d0b6674dcb82d6faf5cf40484d30eeb88fc82ef14e903f"
+dependencies = [
+ "datafrog",
+ "log",
+ "rustc-hash",
+]
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 68a617ada4d..f6940ffb339 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -125,6 +125,53 @@ parse_clobber_abi (Parser &parser, 
TokenId last_token_id,
   return 0;
 }
 
+int
+parse_reg (Parser &parser, TokenId last_token_id,
+  AST::InlineAsm &inlineAsm, bool is_explicit)
+{
+  if (!parser.skip_token (LEFT_PAREN))
+{
+  // TODO: we expect a left parenthesis here, please return the correct
+  // error.
+  return 0;
+}
+
+  // after successful left parenthesis parsing, we should return ast of
+  // InlineAsmRegOrRegClass of reg or reg class
+  auto token = parser.peek_current_token ();
+  auto tok_id = token->get_id ();
+
+  if (tok_id == IDENTIFIER)
+{
+  // construct a InlineAsmRegOrRegClass
+}
+  else if (tok_id == STRING_LITERAL)
+{
+  // TODO: there is STRING_LITERAL, and BYTE_STRING_LITERAL, should we 
check
+  // for both?
+
+  // construct a InlineAsmRegOrRegClass
+}
+  else
+{
+  // TODO
+}
+  if (!parser.skip_token (RIGHT_PAREN))
+{
+  // we expect a left parenthesis here, please return the correct error.
+  return 0;
+}
+
+  return 0;
+}
+
+int
+parse_operand (Parser &parser, TokenId last_token_id,
+  AST::InlineAsm &inlineAsm)
+{
+  return 0;
+}
+
 void
 check_and_set (Parser &parser, AST::InlineAsm &inlineAsm,
   AST::InlineAsmOptions option)
@@ -340,7 +387,7 @@ parseAsmArg (Parser &parser, TokenId 
last_token_id,
   return 0;
 }
 
-static tl::optional
+tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   bool is_global_asm)
 {
-- 
2.45.2



[COMMITTED 083/145] gccrs: Add a simple no-op test for asm!

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_nop.rs: Simple test for asm!
---
 gcc/testsuite/rust/compile/inline_asm_nop.rs | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_nop.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_nop.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop.rs
new file mode 100644
index 000..ffe3161cd73
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_nop.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!("nop");
+}
-- 
2.45.2



[COMMITTED 080/145] gccrs: Introduced is_global_asm to InlineAsm AST

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-expr.h: Introduced is_global_asm to InlineAsm AST
---
 gcc/rust/ast/rust-expr.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index a5afbffee99..84fb5e8ab33 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4841,6 +4841,7 @@ public:
   TupleClobber clobber_abi;
   InlineAsmOptions options;
   std::vector line_spans;
+  bool is_global_asm;
 };
 
 } // namespace AST
-- 
2.45.2



[COMMITTED 075/145] gccrs: Working on parseAsmArg

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (enum InlineAsmRegOrRegClass): 
title.
(parseAsmArg): title.
(check_identifier): title.
(parse_operand): title.
(parse_options): title.
(parse_reg): title.
(parseDirSpec): title.
(parse_asm): title.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 151 ++---
 gcc/rust/expand/rust-macro-builtins-asm.h  |  87 
 2 files changed, 159 insertions(+), 79 deletions(-)
 create mode 100644 gcc/rust/expand/rust-macro-builtins-asm.h

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 7958d91537a..f26c4610230 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -16,74 +16,32 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
-#include "rust-macro-builtins.h"
-#include "rust-macro-builtins-helpers.h"
-#include "rust-macro-invoc-lexer.h"
+#include "rust-macro-builtins-asm.h"
 
 namespace Rust {
 
-struct AsmParseError
-{
-};
-
-// This is just an enum to hold some operands right now.
-enum InlineAsmDirSpec
-{
-  In,
-  Out,
-  InOut,
-  SplitInOut,
-  Const,
-  Sym,
-  Label,
-};
-
-enum InlineAsmOptions
-{
-
-};
-
-typedef std::string symbol_name;
-typedef std::vector Templates;
-typedef std::vector Operands;
-typedef std::map RegisterArgs;
-typedef std::map ClobberAbis;
-typedef std::map NamedValues;
-
-struct AsmArg
-{
-  Templates templates;
-  Operands operands;
-  std::map named_values;
-  RegisterArgs register_arguments;
-  ClobberAbis clobber_abis;
-  InlineAsmOptions options;
-  std::vector
-options_span; // TODO: @badumbatish @jjasmine I have no idea what span do, 
i
- // copied it out of rustc_builtin_macros/src/asm.rs
-};
-
-tl::optional
-parseAsmArg (Parser &p, bool is_global_asm);
-static tl::optional
-parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-static tl::optional
-parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-static tl::optional
-parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
-  bool is_global_asm);
-
 tl::optional
-parseDirSpec (Parser &p, TokenId last_token_id)
+parseDirSpec (Parser &parser, TokenId last_token_id)
 {
   return tl::nullopt;
 }
-tl::optional
-parseAsmArg (Parser &p, bool is_global_asm)
+
+bool
+check_identifier (Parser &p, std::string ident)
 {
-  return tl::nullopt;
-}
+  auto token = p.peek_current_token ();
 
+  if (token->get_id () == IDENTIFIER
+  && (token->as_string () == ident || ident == ""))
+{
+  p.skip_token ();
+  return true;
+}
+  else
+{
+  return false;
+}
+}
 tl::optional
 parse_format_string (Parser &parser, TokenId last_token_id)
 {
@@ -125,6 +83,59 @@ MacroBuiltin::nonglobal_asm_handler (location_t invoc_locus,
   return parse_asm (invoc_locus, invoc, is_global_asm);
 }
 
+tl::optional
+parseAsmArg (Parser &parser, TokenId last_token_id,
+bool is_global_asm)
+{
+  auto token = parser.peek_current_token ();
+  AsmArg arg;
+  tl::optional fm_string;
+  while (token->get_id () != last_token_id)
+{
+  std::cout << token->get_token_description () << std::endl;
+
+  token = parser.peek_current_token ();
+
+  // We accept a comma token here.
+  if (token->get_id () != COMMA)
+   {
+ break;
+   }
+  parser.skip_token ();
+
+  // And if that token comma is also the trailing comma, we break
+  // TODO: Check with mentor see what last_token_id means
+  token = parser.peek_current_token ();
+  if (token->get_id () == COMMA && token->get_id () == last_token_id)
+   {
+ parser.skip_token ();
+ break;
+   }
+
+  // Ok after the left paren is good, we better be parsing correctly
+  // everything in here, which is operand in ABNF
+
+  // TODO: Parse clobber abi
+  if (check_identifier (parser, "clobber_abi"))
+   {
+ std::cout << "Clobber abi tee hee" << std::endl;
+ continue;
+   }
+
+  // TODO: Parse options
+  if (check_identifier (parser, "options"))
+   {
+ std::cout << "Parse optoins" << std::endl;
+ continue;
+   }
+
+  // Ok after we have check that neither clobber_abi nor options works, the
+  // only other logical choice is reg_operand
+  fm_string = parse_format_string (parser, last_token_id);
+}
+  return tl::nullopt;
+}
+
 static tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   bool is_global_asm)
@@ -171,26 +182,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   fm_string = parse_format_string (parser, last_token_id);
 }
 
-  // operands stream
-  token = parser.peek_current_token ();
-  while (token->get_id () != last_token_id)
-{
-  std::cout << token->get_token_descript

[COMMITTED 062/145] gccrs: Allow multiple outer attributes on generic params

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

Previously generic params only allowed one outer attribute in front of
them.

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Visit outer
attributes.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Change outer
attribute visit, we need to visit all of them.
* ast/rust-ast.cc (LifetimeParam::as_string): Change as_string
implementation to allow multiple outer attributes.
(TypeParam::as_string): Likewise.
* ast/rust-ast.h (class LifetimeParam): Allow multiple outer
attributes.
* ast/rust-item.h (class TypeParam): Likewise.
* ast/rust-path.h: Likewise.
* parse/rust-parse-impl.h (Parser::parse_generic_param): Change call
to outer attribute parsing to collect several attributes.
(Parser::parse_lifetime_param): Likewise.
(Parser::parse_type_param): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-ast-collector.cc |  3 +++
 gcc/rust/ast/rust-ast-visitor.cc   |  6 +++---
 gcc/rust/ast/rust-ast.cc   | 12 ++--
 gcc/rust/ast/rust-ast.h| 13 ++---
 gcc/rust/ast/rust-item.h   | 14 +++---
 gcc/rust/ast/rust-path.h   | 10 +-
 gcc/rust/parse/rust-parse-impl.h   | 14 +++---
 7 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index a7f6ed57623..a75722587f5 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -476,6 +476,7 @@ TokenCollector::visit (LifetimeParam &lifetime_param)
 
   // TODO what to do with outer attr? They are not mentioned in the reference.
 
+  visit_items_as_lines (lifetime_param.get_outer_attrs ());
   auto lifetime = lifetime_param.get_lifetime ();
   visit (lifetime);
 
@@ -495,6 +496,7 @@ TokenCollector::visit (ConstGenericParam ¶m)
   // Syntax:
   // const IDENTIFIER : Type ( = Block | IDENTIFIER | -?LITERAL )?
 
+  visit_items_as_lines (param.get_outer_attrs ());
   push (Rust::Token::make (CONST, param.get_locus ()));
   auto id = param.get_name ().as_string ();
   push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
@@ -1509,6 +1511,7 @@ TokenCollector::visit (TypeParam ¶m)
   // TypeParamBounds :
   //TypeParamBound ( + TypeParamBound )* +?
 
+  visit_items_as_lines (param.get_outer_attrs ());
   auto id = param.get_type_representation ().as_string ();
   push (Rust::Token::make_identifier (param.get_locus (), std::move (id)));
   if (param.has_type_param_bounds ())
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index ba3eb67cbe7..2c1674e21ea 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -69,7 +69,7 @@ DefaultASTVisitor::visit (AST::Lifetime &lifetime)
 void
 DefaultASTVisitor::visit (AST::LifetimeParam &lifetime_param)
 {
-  visit (lifetime_param.get_outer_attribute ());
+  visit_outer_attrs (lifetime_param);
   visit (lifetime_param.get_lifetime ());
   for (auto &lifetime_bound : lifetime_param.get_lifetime_bounds ())
 visit (lifetime_bound);
@@ -78,7 +78,7 @@ DefaultASTVisitor::visit (AST::LifetimeParam &lifetime_param)
 void
 DefaultASTVisitor::visit (AST::ConstGenericParam &const_param)
 {
-  visit (const_param.get_outer_attribute ());
+  visit_outer_attrs (const_param);
   if (const_param.has_type ())
 visit (const_param.get_type ());
   if (const_param.has_default_value ())
@@ -665,7 +665,7 @@ DefaultASTVisitor::visit (AST::AsyncBlockExpr &expr)
 void
 DefaultASTVisitor::visit (AST::TypeParam ¶m)
 {
-  visit (param.get_outer_attribute ());
+  visit_outer_attrs (param);
   for (auto &bound : param.get_type_param_bounds ())
 visit (bound);
   if (param.has_type ())
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index bc896928ce6..8045a688510 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -2399,11 +2399,11 @@ LifetimeParam::as_string () const
 {
   std::string str ("LifetimeParam: ");
 
-  str += "\n Outer attribute: ";
+  str += "\n Outer attribute:";
   if (!has_outer_attribute ())
 str += "none";
-  else
-str += outer_attr.as_string ();
+  for (auto &attr : outer_attrs)
+str += " " + attr.as_string ();
 
   str += "\n Lifetime: " + lifetime.as_string ();
 
@@ -2495,11 +2495,11 @@ TypeParam::as_string () const
 {
   std::string str ("TypeParam: ");
 
-  str += "\n Outer attribute: ";
+  str += "\n Outer attribute:";
   if (!has_outer_attribute ())
 str += "none";
-  else
-str += outer_attr.as_string ();
+  for (auto &attr : outer_attrs)
+str += " " + attr.as_string ();
 
   str += "\n Identifier: " + type_representation.as_string ();
 
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 0693b10bd2e..ee1c58c8fd6 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1602,7 +1602,7 @@ cl

[COMMITTED 081/145] gccrs: Make InlineAsm non-abstract for usage in parsing.

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-expr.h: Make InlineAsm non-abstract for usage in parsing.
---
 gcc/rust/ast/rust-expr.h | 44 
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 84fb5e8ab33..03336cdcc59 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4809,11 +4809,8 @@ struct InlineAsmPlaceHolder
 struct InlineAsmTemplatePiece
 {
   bool is_placeholder;
-  union
-  {
-std::string string;
-InlineAsmPlaceHolder placeholder;
-  };
+  std::string string;
+  InlineAsmPlaceHolder placeholder;
 };
 
 struct TupleClobber
@@ -4832,16 +4829,47 @@ struct TupleTemplateStr
 };
 
 // Inline Assembly Node
-class InlineAsm : public ExprWithoutBlock
+class InlineAsm : private ExprWithoutBlock
 {
+private:
+  location_t locus;
+  // TODO: Not sure how outer_attrs plays with InlineAsm, I put it here in 
order
+  // to override, very hacky.
+  std::vector outer_attrs;
+
 public:
   std::vector template_;
   std::vector template_strs;
   std::vector operands;
-  TupleClobber clobber_abi;
-  InlineAsmOptions options;
+  std::vector clobber_abi;
+  // std::set options;
+  std::set options;
+
   std::vector line_spans;
+
   bool is_global_asm;
+
+  InlineAsm (location_t locus, bool is_global_asm)
+: locus (locus), is_global_asm (is_global_asm)
+  {}
+  void accept_vis (ASTVisitor &vis) override{};
+
+  std::string as_string () const override { return "InlineAsm AST Node"; }
+
+  location_t get_locus () const override { return locus; }
+
+  void mark_for_strip () override {}
+
+  bool is_marked_for_strip () const override { return false; }
+
+  std::vector &get_outer_attrs () override { return outer_attrs; }
+
+  void set_outer_attrs (std::vector v) override { outer_attrs = v; }
+
+  ExprWithoutBlock *clone_expr_without_block_impl () const override
+  {
+return nullptr;
+  }
 };
 
 } // namespace AST
-- 
2.45.2



[COMMITTED 077/145] gccrs: Working on parse_options for a bit more

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_options): title.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 9d904d6223e..d47d95c594f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -98,7 +98,19 @@ parse_options (Parser &parser, TokenId 
last_token_id,
 {
   // Parse everything commitedly
   if (!p.skip_token (LEFT_PAREN))
-{}
+{
+  // We have shifted `options` to search for the left parenthesis next, we
+  // should error out if this is not possible.
+  // TODO: report some error.
+  return -1;
+}
+
+  auto token = parser.peek_current_token ();
+  while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN)
+{
+  parser.skip_token ();
+  token = parser.peek_current_token ();
+}
 }
 bool
 check_identifier (Parser &p, std::string ident)
-- 
2.45.2



[COMMITTED 085/145] gccrs: Add tests parsing with trailing commas inline asm

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_nop_2.rs: New test.
---
 gcc/testsuite/rust/compile/inline_asm_nop_2.rs | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_nop_2.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_nop_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
new file mode 100644
index 000..8437e8fc66c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!("nop",);
+}
-- 
2.45.2



[COMMITTED 082/145] gccrs: Replace scaffolded InlineAsm with real InlineAsm.

2025-03-17 Thread arthur . cohen
From: jjasmine 

Replace scaffolded InlineAsm with real InlineAsm node in rust-expr.h

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parseDirSpec): replace
scaffolded InlineAsm with real InlineAsm.
(parse_clobber_abi): likewise.
(check_and_set): likewise.
(parse_options): likewise.
(parseAsmArg): likewise.
(parse_asm): likewise.
* expand/rust-macro-builtins-asm.h (struct AsmParseError): likewise.
(enum InlineAsmDirSpec): likewise.
(enum InlineAsmRegOrRegClass): likewise.
(struct AsmArg): likewise.
(parseAsmArg): likewise.
(check_and_set): likewise.
(parse_operand): likewise.
(parse_options): likewise.
(parse_reg): likewise.
(parse_clobber_abi): likewise.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 54 ++
 gcc/rust/expand/rust-macro-builtins-asm.h  | 66 --
 2 files changed, 40 insertions(+), 80 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 971dd7b7e75..6e602c463ed 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -20,15 +20,15 @@
 
 namespace Rust {
 
-tl::optional
+int
 parseDirSpec (Parser &parser, TokenId last_token_id)
 {
-  return tl::nullopt;
+  return 0;
 }
 
 int
 parse_clobber_abi (Parser &parser, TokenId last_token_id,
-  AsmArg &args)
+  AST::InlineAsm &inlineAsm)
 {
   // clobber_abi := "clobber_abi("  *("," ) [","] ")"
 
@@ -49,7 +49,7 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
   return -1;
 }
 
-  ClobberAbis new_abis;
+  std::vector new_abis;
 
   auto token = parser.peek_current_token ();
 
@@ -59,7 +59,7 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
   if (token->get_id () == STRING_LITERAL)
{
  // TODO: Caring for span in here.
- new_abis.push_back (token->as_string ());
+ new_abis.push_back ({token->as_string (), token->get_locus ()});
}
   else
{
@@ -88,16 +88,17 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
 
   for (auto abi : new_abis)
 {
-  args.clobber_abis.push_back (abi);
+  inlineAsm.clobber_abi.push_back (abi);
 }
 
   return 0;
 }
 
 void
-check_and_set (Parser &p, AsmArg &args, std::string option)
+check_and_set (Parser &p, AST::InlineAsm &inlineAsm,
+  std::string option)
 {
-  if (args.options.count (option) == 1)
+  if (inlineAsm.options.count (option) == 1)
 {
   // TODO: report an error of duplication
 
@@ -105,13 +106,14 @@ check_and_set (Parser &p, AsmArg &args, 
std::string option)
 }
   else
 {
-  args.options.insert (option);
+  inlineAsm.options.insert (option);
 }
 }
 int
 parse_options (Parser &parser, TokenId last_token_id,
-  AsmArg &args, bool is_global_asm)
+  AST::InlineAsm &inlineAsm)
 {
+  bool is_global_asm = inlineAsm.is_global_asm;
   // Parse everything commitedly
   if (!parser.skip_token (LEFT_PAREN))
 {
@@ -126,43 +128,43 @@ parse_options (Parser &parser, TokenId 
last_token_id,
 {
   if (!is_global_asm && check_identifier (parser, "pure"))
{
- check_and_set (parser, args, "pure");
+ check_and_set (parser, inlineAsm, "pure");
}
   else if (!is_global_asm && check_identifier (parser, "nomem"))
{
- check_and_set (parser, args, "nomem");
+ check_and_set (parser, inlineAsm, "nomem");
}
   else if (!is_global_asm && check_identifier (parser, "readonly"))
{
- check_and_set (parser, args, "readonly");
+ check_and_set (parser, inlineAsm, "readonly");
}
   else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
{
- check_and_set (parser, args, "preserves_flags");
+ check_and_set (parser, inlineAsm, "preserves_flags");
}
   else if (!is_global_asm && check_identifier (parser, "noreturn"))
{
- check_and_set (parser, args, "noreturn");
+ check_and_set (parser, inlineAsm, "noreturn");
}
   else if (!is_global_asm && check_identifier (parser, "noreturn"))
{
- check_and_set (parser, args, "noreturn");
+ check_and_set (parser, inlineAsm, "noreturn");
}
   else if (!is_global_asm && check_identifier (parser, "nostack"))
{
- check_and_set (parser, args, "nostack");
+ check_and_set (parser, inlineAsm, "nostack");
}
   else if (!is_global_asm && check_identifier (parser, "may_unwind"))
{
- check_and_set (parser, args, "may_unwind");
+ check_and_set (parser, inlineAsm, "may_unwind");
}
   else if (check_identifier (parser, "att_syntax"))
{
- check_and_set (parser, args, "att_syntax");
+ check_and

[PATCH] testsuite: update early-break tests for non-load-lanes targets [PR119286]

2025-03-17 Thread Tamar Christina
Hi All,

Broadly speaking, these tests were failing because the BB limitation for SLP'ing
loads in an || in an early break makes the loads end up in different BBs and so
today we can't SLP them.  This results in load_lanes being required to vectorize
them because the alternative is loads with permutes which we don't allow.

The original checks were only checking partial vectors, which ended up working
because e.g. Adv. SIMD isn't a partial vector target, so it failed, and SVE was
a partial vector target but also has load lanes so it passes.

GCN however is a partial vector target without load lanes which makes the tests
fail.  As we require load_lanes for now, also check for them.

Bootstrapped Regtested on aarch64-none-linux-gnu,
arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
-m32, -m64 and no issues.

Cross checked the failing cases on amdgcn-amdhsa
and all pass now.

Ok for master?

Thanks,
Tamar

gcc/testsuite/ChangeLog:

PR target/119286
* gcc.dg/vect/bb-slp-41.c: Add pragma novector.
* gcc.dg/vect/vect-early-break_133_pfa11.c: Should never vectorize today
as indexes can be out of range.
* gcc.dg/vect/vect-early-break_128.c: Require load_lanes as well.
* gcc.dg/vect/vect-early-break_133_pfa10.c: Likewise.
* gcc.dg/vect/vect-early-break_133_pfa8.c: Likewise.
* gcc.dg/vect/vect-early-break_133_pfa9.c: Likewise.
* gcc.dg/vect/vect-early-break_22.c: Likewise.
* gcc.dg/vect/vect-early-break_26.c: Likewise.
* gcc.dg/vect/vect-early-break_43.c: Likewise.
* gcc.dg/vect/vect-early-break_44.c: Likewise.
* gcc.dg/vect/vect-early-break_6.c: Likewise.
* gcc.dg/vect/vect-early-break_56.c: Expect failures on group misalign.

---
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c 
b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c
index 
72245115f305de8ef26c9c481f160a05db8c3dcb..5a2bd4d2a33e41dbb33dc105b72f0ae6fd0e81ef
 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-41.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-41.c
@@ -51,6 +51,7 @@ int main ()
   foo (a1, b);
   bar (a2, b);
 
+#pragma GCC novector
   for (i = 0; i < ARR_SIZE; i++)
 if (a1[i] != a2[i])
   return 1;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_128.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_128.c
index 
ed6baf2d451f3887076a1e9143035363128efe70..3d51d52358fc2308ca3614bd3c6fe079f9d839fa
 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_128.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_128.c
@@ -3,8 +3,8 @@
 /* { dg-require-effective-target vect_early_break } */
 /* { dg-require-effective-target vect_int } */
 
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { target 
vect_partial_vectors } } } */
-/* { dg-final { scan-tree-dump-not "vectorizing stmts using SLP" "vect" { 
target { ! vect_partial_vectors } } } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { target { 
vect_partial_vectors && vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-not "vectorizing stmts using SLP" "vect" { 
target { { ! vect_partial_vectors } || { ! vect_load_lanes } } } } } */
 /* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */
 
 #ifndef N
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa10.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa10.c
index 
dd05046982524f15662be8df517716b581b8a2d9..2a58fb01401282fa857ffd56b79fc6e25936d03e
 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa10.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa10.c
@@ -6,9 +6,9 @@
 /* { dg-additional-options "-Ofast" } */
 
 /* Alignment requirement too big, load lanes targets can't safely vectorize 
this.  */
-/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { 
vect_partial_vectors || vect_load_lanes } } } } */
-/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! { 
vect_partial_vectors || vect_load_lanes } } } } } */
-/* { dg-final { scan-tree-dump-not "Alignment of access forced using peeling" 
"vect" { target { ! { vect_partial_vectors || vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { 
vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! 
vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-not "Alignment of access forced using peeling" 
"vect" { target { ! vect_load_lanes } } } } */
 
 unsigned test4(char x, char *restrict vect_a, char *restrict vect_b, int n)
 {  
diff --git a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa11.c 
b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa11.c
index 
085dd9b81bb6943440f34d044cbd24ee2121657c..514bd37191744bf1df29c4967d52a9acee605205
 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa11.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-early-break_133_pfa11.c
@@ -3,9 +3,8 @@
 /* { dg-require-effective-target vect_early_break } */
 /* { dg-require-effective-target

[COMMITTED 087/145] gccrs: Implemented parse_clobber_abi to pass new tests

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_clobber_abi):
implemented parse_clobber_abi
(parse_format_string): likewise.
(parseAsmArg): likewise.
(parse_asm): likewise.
* expand/rust-macro-builtins-asm.h (parseAsmArg): likewise.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 81 --
 gcc/rust/expand/rust-macro-builtins-asm.h  |  3 +-
 2 files changed, 61 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 6e602c463ed..bcf8b6fb3f2 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -31,14 +31,31 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
   AST::InlineAsm &inlineAsm)
 {
   // clobber_abi := "clobber_abi("  *("," ) [","] ")"
-
   // PARSE EVERYTHING COMMITTEDLY IN THIS FUNCTION, WE CONFIRMED VIA 
clobber_abi
   // identifier keyword
-
+  auto token = parser.peek_current_token ();
   if (!parser.skip_token (LEFT_PAREN))
 {
   // TODO: Raise error exactly like rustc if left parenthesis is not
   // encountered.
+  token = parser.peek_current_token ();
+
+  // TODO: Error reporting shifted to the left 1 character, I'm not sure
+  // why.
+  if (token->get_id () == last_token_id)
+   {
+ rust_error_at (parser.peek_current_token ()->get_locus (),
+"expected `(`, found end of macro arguments");
+ return -1;
+   }
+
+  else
+   {
+ rust_error_at (
+   parser.peek_current_token ()->get_locus (),
+   "expected `(`, found `%s`",
+   parser.peek_current_token ()->get_token_description ());
+   }
   return -1;
 }
 
@@ -46,12 +63,15 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
 {
   // TODO: We encountered a "clobber_abi()", which should be illegal?
   // 
https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_builtin_macros/src/asm.rs#L381
+  rust_error_at (
+   parser.peek_current_token ()->get_locus (),
+   "at least one abi must be provided as an argument to `clobber_abi`");
   return -1;
 }
 
   std::vector new_abis;
 
-  auto token = parser.peek_current_token ();
+  token = parser.peek_current_token ();
 
   while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN)
 {
@@ -198,7 +218,6 @@ bool
 check_identifier (Parser &p, std::string ident)
 {
   auto token = p.peek_current_token ();
-
   if (token->get_id () == IDENTIFIER
   && (token->as_string () == ident || ident == ""))
 {
@@ -218,17 +237,11 @@ parse_format_string (Parser &parser, 
TokenId last_token_id)
   if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
 {
   // very nice, we got a supposedly formatted string.
-  std::cout << token->get_token_description () << std::endl;
   parser.skip_token ();
-  return "formatted string";
+  return token->as_string ();
 }
   else
 {
-  parser.skip_token ();
-  std::cout << token->get_token_description () << std::endl;
-
-  rust_error_at (token->get_locus (),
-"asm template must be a string literal");
   return tl::nullopt;
 }
 }
@@ -253,22 +266,32 @@ MacroBuiltin::nonglobal_asm_handler (location_t 
invoc_locus,
 
 int
 parseAsmArg (Parser &parser, TokenId last_token_id,
-AST::InlineAsm &inlineAsm)
+AST::InlineAsm &inlineAsm,
+bool consumed_comma_without_formatted_string)
 {
   auto token = parser.peek_current_token ();
   tl::optional fm_string;
   while (token->get_id () != last_token_id)
 {
-  std::cout << token->get_token_description () << std::endl;
-
   token = parser.peek_current_token ();
 
   // We accept a comma token here.
-  if (token->get_id () != COMMA)
+  if (token->get_id () != COMMA && consumed_comma_without_formatted_string)
+   {
+ // if it is not a comma, but we consumed it previously, this is fine
+ // but we have to set it to false tho.
+ consumed_comma_without_formatted_string = false;
+   }
+  else if (token->get_id () == COMMA
+  && !consumed_comma_without_formatted_string)
+   {
+ consumed_comma_without_formatted_string = false;
+ parser.skip_token ();
+   }
+  else
{
  break;
}
-  parser.skip_token ();
 
   // And if that token comma is also the trailing comma, we break
   // TODO: Check with mentor see what last_token_id means
@@ -285,7 +308,7 @@ parseAsmArg (Parser &parser, TokenId 
last_token_id,
   // TODO: Parse clobber abi, eat the identifier named "clobber_abi" if 
true
   if (check_identifier (parser, "clobber_abi"))
{
- std::cout << "Clobber abi tee hee" << std::endl;
+ 

[COMMITTED 088/145] gccrs: Parsing of options(...) done.

2025-03-17 Thread arthur . cohen
From: jjasmine 

This is without any mutually exclusive options checked, or
any relationship with reg_operands. Very primitive.

gcc/rust/ChangeLog:

* ast/rust-expr.h: parsing of options(...)
* expand/rust-macro-builtins-asm.cc (check_and_set):
likewise.
(parse_options): likewise.
(parseAsmArg): likewise.
* expand/rust-macro-builtins-asm.h (check_and_set):
likewise.

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_legal_options.rs: New test.
---
 gcc/rust/ast/rust-expr.h  |  2 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc| 30 +--
 gcc/rust/expand/rust-macro-builtins-asm.h |  2 +-
 .../rust/compile/inline_asm_legal_options.rs  | 12 
 4 files changed, 28 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_legal_options.rs

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 03336cdcc59..719a76cdbb3 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4843,7 +4843,7 @@ public:
   std::vector operands;
   std::vector clobber_abi;
   // std::set options;
-  std::set options;
+  std::set options;
 
   std::vector line_spans;
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index bcf8b6fb3f2..443c8a3bce3 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -116,7 +116,7 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
 
 void
 check_and_set (Parser &p, AST::InlineAsm &inlineAsm,
-  std::string option)
+  AST::InlineAsmOptions option)
 {
   if (inlineAsm.options.count (option) == 1)
 {
@@ -148,43 +148,40 @@ parse_options (Parser &parser, TokenId 
last_token_id,
 {
   if (!is_global_asm && check_identifier (parser, "pure"))
{
- check_and_set (parser, inlineAsm, "pure");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::PURE);
}
   else if (!is_global_asm && check_identifier (parser, "nomem"))
{
- check_and_set (parser, inlineAsm, "nomem");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::NOMEM);
}
   else if (!is_global_asm && check_identifier (parser, "readonly"))
{
- check_and_set (parser, inlineAsm, "readonly");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::READONLY);
}
   else if (!is_global_asm && check_identifier (parser, "preserves_flags"))
{
- check_and_set (parser, inlineAsm, "preserves_flags");
+ check_and_set (parser, inlineAsm,
+AST::InlineAsmOptions::PRESERVES_FLAGS);
}
   else if (!is_global_asm && check_identifier (parser, "noreturn"))
{
- check_and_set (parser, inlineAsm, "noreturn");
-   }
-  else if (!is_global_asm && check_identifier (parser, "noreturn"))
-   {
- check_and_set (parser, inlineAsm, "noreturn");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::NORETURN);
}
   else if (!is_global_asm && check_identifier (parser, "nostack"))
{
- check_and_set (parser, inlineAsm, "nostack");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::NOSTACK);
}
   else if (!is_global_asm && check_identifier (parser, "may_unwind"))
{
- check_and_set (parser, inlineAsm, "may_unwind");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::MAY_UNWIND);
}
   else if (check_identifier (parser, "att_syntax"))
{
- check_and_set (parser, inlineAsm, "att_syntax");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::ATT_SYNTAX);
}
   else if (check_identifier (parser, "raw"))
{
- check_and_set (parser, inlineAsm, "raw");
+ check_and_set (parser, inlineAsm, AST::InlineAsmOptions::RAW);
}
   else
{
@@ -201,6 +198,7 @@ parse_options (Parser &parser, TokenId 
last_token_id,
{
  // TODO: If the skip of comma is unsuccessful, which should be
  // illegal, pleaes emit the correct error.
+ std::cout << "Illegal comma" << std::endl;
  return -1;
}
 
@@ -315,13 +313,13 @@ parseAsmArg (Parser &parser, TokenId 
last_token_id,
   // TODO: Parse options
   if (check_identifier (parser, "options"))
{
- std::cout << "Parse optoins" << std::endl;
+ parse_options (parser, last_token_id, inlineAsm);
  continue;
}
 
   // Ok after we have check that neither clobber_abi nor options works, the
   // only other logical choice is reg_operand
-  std::cout << "reg_operand" << std::endl;
+  // std::cout << "reg_operand" << std::endl;
   fm_string = parse_format_string (parser, last_token_id);
 }
   return 0;
diff --git a/gcc/rust/expand/rust-macro-bu

[COMMITTED 095/145] gccrs: Remove global_asm and non_global_asm handler

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc
(MacroBuiltin::global_asm_handler):
Remove global_asm and non_global_asm handler
(MacroBuiltin::nonglobal_asm_handler): Likewise.
(MacroBuiltin::asm_handler): Likewise.
* expand/rust-macro-builtins.cc (enum class): Likewise.
(inline_asm_maker): Likewise.
* expand/rust-macro-builtins.h: Likewise.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 15 ++-
 gcc/rust/expand/rust-macro-builtins.cc | 20 ++--
 gcc/rust/expand/rust-macro-builtins.h  |  8 +++-
 3 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 1bfc6e9f456..8c2b88c997d 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -307,20 +307,9 @@ parse_format_string (Parser &parser, 
TokenId last_token_id)
 }
 
 tl::optional
-MacroBuiltin::global_asm_handler (location_t invoc_locus,
- AST::MacroInvocData &invoc)
+MacroBuiltin::asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
+  bool is_global_asm)
 {
-  // Just to clarify the code
-  bool is_global_asm = true;
-  return parse_asm (invoc_locus, invoc, is_global_asm);
-}
-
-tl::optional
-MacroBuiltin::nonglobal_asm_handler (location_t invoc_locus,
-AST::MacroInvocData &invoc)
-{
-  // Just to clarify the code
-  bool is_global_asm = false;
   return parse_asm (invoc_locus, invoc, is_global_asm);
 }
 
diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index e4144d10605..7940f33686c 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -92,6 +92,22 @@ format_args_maker (AST::FormatArgs::Newline nl)
   };
 }
 
+enum class isGlobalAsm
+{
+  Yes,
+  No,
+};
+
+AST::MacroTranscriberFunc
+inline_asm_maker (isGlobalAsm is_global_asm)
+{
+  bool global_asm = is_global_asm == isGlobalAsm::Yes ? true : false;
+
+  return [global_asm] (location_t loc, AST::MacroInvocData &invoc) {
+return MacroBuiltin::asm_handler (loc, invoc, global_asm);
+  };
+}
+
 std::unordered_map
   MacroBuiltin::builtin_transcribers = {
 {"assert", MacroBuiltin::assert_handler},
@@ -108,8 +124,8 @@ std::unordered_map
 {"include", MacroBuiltin::include_handler},
 {"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
 {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
-{"asm", MacroBuiltin::nonglobal_asm_handler},
-{"global_asm", MacroBuiltin::global_asm_handler},
+{"asm", inline_asm_maker (isGlobalAsm::No)},
+{"global_asm", inline_asm_maker (isGlobalAsm::Yes)},
 /* Unimplemented macro builtins */
 {"option_env", MacroBuiltin::sorry},
 {"concat_idents", MacroBuiltin::sorry},
diff --git a/gcc/rust/expand/rust-macro-builtins.h 
b/gcc/rust/expand/rust-macro-builtins.h
index 10377e92134..6db0b7a9559 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -159,11 +159,9 @@ public:
   static tl::optional line_handler (location_t invoc_locus,
   AST::MacroInvocData &invoc);
 
-  static tl::optional
-  nonglobal_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
-
-  static tl::optional
-  global_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
+  static tl::optional asm_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc,
+ bool is_global_asm);
 
   static tl::optional
   format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
-- 
2.45.2



[COMMITTED 086/145] gccrs: Added faulty tests for inline asm cloberring

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_faulty_clobber.rs: New test.
* rust/compile/inline_asm_faulty_clobber_1.rs: New test.
* rust/compile/inline_asm_faulty_clobber_2.rs: New test.
---
 .../rust/compile/inline_asm_faulty_clobber.rs  | 10 ++
 .../rust/compile/inline_asm_faulty_clobber_1.rs| 10 ++
 .../rust/compile/inline_asm_faulty_clobber_2.rs| 10 ++
 3 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
new file mode 100644
index 000..8d040ea40b4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!("nop", clobber_abi());  // { dg-error "at least one abi must be 
provided as an argument to `clobber_abi`" }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
new file mode 100644
index 000..77af10177c4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!("nop", clobber_abi);  // { dg-error "expected `\\(`, found end of 
macro arguments" }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
new file mode 100644
index 000..ae3607ffa77
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!("nop", clobber_abi+);  // { dg-error "expected `\\(`, found `\\+`" }
+}
\ No newline at end of file
-- 
2.45.2



[COMMITTED 091/145] gccrs: Resolve static decl warning

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.h (parseAsmArg):
Resolve static decl warning
(parse_nonglobal_asm):
Resolve static decl warning
---
 gcc/rust/expand/rust-macro-builtins-asm.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 163ad161b5a..469dc5ae906 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -11,11 +11,11 @@ int
 parseAsmArg (Parser &p, TokenId last_token_id,
 AST::InlineAsm &inlineAsm,
 bool consumed_comma_without_formatted_string);
-static tl::optional
+tl::optional
 parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-static tl::optional
+tl::optional
 parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-static tl::optional
+tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   bool is_global_asm);
 
-- 
2.45.2



[COMMITTED 098/145] gccrs: Working towards parse_reg and parse_reg_operand

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_reg):
Working towards parse_reg and parse_reg_operand
(parse_reg_operand):
Working towards parse_reg and parse_reg_operand
(parse_asm_arg):
Add todo about errors
* expand/rust-macro-builtins-asm.h (parse_global_asm):
remove dead code.
(parse_nonglobal_asm):
remove dead code.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 29 +++---
 gcc/rust/expand/rust-macro-builtins-asm.h  |  4 ---
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 3ce9bf9d78b..9e02400d77f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -141,11 +141,10 @@ parse_reg (Parser &parser, TokenId 
last_token_id,
   // InlineAsmRegOrRegClass of reg or reg class
   auto token = parser.peek_current_token ();
   auto tok_id = token->get_id ();
-
-  if (tok_id == IDENTIFIER)
+  AST::InlineAsmRegOrRegClass regClass;
+  if (parser.skip_token (IDENTIFIER))
 {
   // construct a InlineAsmRegOrRegClass
-  AST::InlineAsmRegOrRegClass regClass;
   regClass.type = RegType::RegClass;
   regClass.regClass.Symbol = token->as_string ();
 }
@@ -156,18 +155,27 @@ parse_reg (Parser &parser, TokenId 
last_token_id,
 
   // construct a InlineAsmRegOrRegClass
   // parse_format_string
+  regClass.type = RegType::Reg;
+  inlineAsmCtx.is_explicit = true;
+  regClass.regClass.Symbol = token->as_string ();
 }
   else
 {
-  // TODO
+  // TODO: This should emit error
+  //  return
+  //  
Err(p.dcx().create_err(errors::ExpectedRegisterClassOrExplicitRegister
+  //  {
+  //   span: p.token.span,
+  //   }));
 }
   if (!parser.skip_token (RIGHT_PAREN))
 {
-  // we expect a left parenthesis here, please return the correct error.
+  // TODO: we expect a left parenthesis here, please return the correct
+  // error.
   return tl::nullopt;
 }
 
-  return tl::nullopt;
+  return regClass;
 }
 
 int
@@ -193,7 +201,7 @@ parse_reg_operand (Parser &parser, TokenId 
last_token_id,
   //   };
 
   using RegisterType = AST::InlineAsmOperand::RegisterType;
-
+  AST::InlineAsmOperand reg_operand;
   auto token = parser.peek_current_token ();
   auto iden_token = parser.peek_current_token ();
   auto &inlineAsm = inlineAsmCtx.inlineAsm;
@@ -221,8 +229,9 @@ parse_reg_operand (Parser &parser, TokenId 
last_token_id,
 {}
   else if (!is_global_asm && check_identifier (parser, "inlateout"))
 {}
-  else if (false && check_identifier (parser, "const"))
+  else if (parser.peek_current_token ()->get_id () == CONST)
 {
+  rust_unreachable ();
   // todo: Please handle const
 }
   else if (false && check_identifier (parser, "sym"))
@@ -237,7 +246,7 @@ parse_reg_operand (Parser &parser, TokenId 
last_token_id,
 {
   return tl::nullopt;
 }
-  return tl::nullopt;
+  return reg_operand;
 }
 void
 check_and_set (Parser &parser, InlineAsmContext &inlineAsmCtx,
@@ -410,6 +419,8 @@ parse_asm_arg (Parser &parser, TokenId 
last_token_id,
}
   else
{
+ // TODO: we consumed comma, and there happens to also be a comma
+ // error should be: expected expression, found `,`
  break;
}
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index a35d7707e6c..c7fcf301735 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -34,10 +34,6 @@ int
 parse_asm_arg (Parser &p, TokenId last_token_id,
   InlineAsmContext &inlineAsmCtx);
 
-tl::optional
-parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-tl::optional
-parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
 tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   bool is_global_asm);
-- 
2.45.2



[COMMITTED 099/145] gccrs: Got AST::Fragment to be created from InlineAsm

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct AnonConst):
Got AST::Fragment to be created from InlineAsm.
(struct InlineAsmOperand): Likewise.
(class InlineAsm): Likewise.
* expand/rust-macro-builtins-asm.cc (parse_reg_operand): Likewise.
(parse_asm): likewise
---
 gcc/rust/ast/rust-expr.h   | 129 -
 gcc/rust/expand/rust-macro-builtins-asm.cc |  31 -
 2 files changed, 150 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 76e5fa7c447..1284c7367fe 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -6,6 +6,7 @@
 #include "rust-path.h"
 #include "rust-macro.h"
 #include "rust-operators.h"
+#include 
 
 namespace Rust {
 namespace AST {
@@ -4723,6 +4724,23 @@ struct AnonConst
 {
   NodeId id;
   std::unique_ptr value;
+  AnonConst () {}
+  AnonConst (const AnonConst &other)
+  {
+id = other.id;
+value = other.value == nullptr
+ ? nullptr
+ : std::unique_ptr (other.value->clone_expr ());
+  }
+
+  AnonConst operator= (const AnonConst &other)
+  {
+id = other.id;
+value = other.value == nullptr
+ ? nullptr
+ : std::unique_ptr (other.value->clone_expr ());
+return *this;
+  }
 };
 
 struct InlineAsmRegOrRegClass
@@ -4767,6 +4785,25 @@ struct InlineAsmOperand
   {
 InlineAsmRegOrRegClass reg;
 std::unique_ptr expr;
+
+In () {}
+In (const struct In &other)
+{
+  reg = other.reg;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+}
+
+In operator= (const struct In &other)
+{
+  reg = other.reg;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+
+  return *this;
+}
   };
 
   struct Out
@@ -4774,6 +4811,26 @@ struct InlineAsmOperand
 InlineAsmRegOrRegClass reg;
 bool late;
 std::unique_ptr expr; // can be null
+
+Out () {}
+Out (const struct Out &other)
+{
+  reg = other.reg;
+  late = other.late;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+}
+
+Out operator= (const struct Out &other)
+{
+  reg = other.reg;
+  late = other.late;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+  return *this;
+}
   };
 
   struct InOut
@@ -4781,6 +4838,26 @@ struct InlineAsmOperand
 InlineAsmRegOrRegClass reg;
 bool late;
 std::unique_ptr expr; // this can't be null
+
+InOut () {}
+InOut (const struct InOut &other)
+{
+  reg = other.reg;
+  late = other.late;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+}
+
+InOut operator= (const struct InOut &other)
+{
+  reg = other.reg;
+  late = other.late;
+  expr = other.expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.expr->clone_expr ());
+  return *this;
+}
   };
 
   struct SplitInOut
@@ -4789,6 +4866,33 @@ struct InlineAsmOperand
 bool late;
 std::unique_ptr in_expr;
 std::unique_ptr out_expr; // could be null
+
+SplitInOut () {}
+SplitInOut (const struct SplitInOut &other)
+{
+  reg = other.reg;
+  late = other.late;
+  in_expr = other.in_expr == nullptr
+ ? nullptr
+ : std::unique_ptr (other.in_expr->clone_expr ());
+  out_expr = other.out_expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.out_expr->clone_expr ());
+}
+
+SplitInOut operator= (const struct SplitInOut &other)
+{
+  reg = other.reg;
+  late = other.late;
+  in_expr = other.in_expr == nullptr
+ ? nullptr
+ : std::unique_ptr (other.in_expr->clone_expr ());
+  out_expr = other.out_expr == nullptr
+  ? nullptr
+  : std::unique_ptr (other.out_expr->clone_expr ());
+
+  return *this;
+}
   };
 
   struct Const
@@ -4799,6 +4903,18 @@ struct InlineAsmOperand
   struct Sym
   {
 std::unique_ptr sym;
+
+Sym () {}
+Sym (const struct Sym &other)
+{
+  sym = std::unique_ptr (other.sym->clone_expr ());
+}
+
+Sym operator= (const struct Sym &other)
+{
+  sym = std::unique_ptr (other.sym->clone_expr ());
+  return *this;
+}
   };
   RegisterType registerType;
 
@@ -4809,6 +4925,12 @@ struct InlineAsmOperand
   struct Const cnst;
   struct Sym sym;
 
+  InlineAsmOperand () {}
+  InlineAsmOperand (const InlineAsmOperand &other)
+: in (other.in), out (other.out), inOut (other.inOut),
+  splitInOut (other.splitInOut), cnst (other.cnst), sym (other.sym)
+  {}
+
   locati

[COMMITTED 074/145] gccrs: Almost done with top level parsing

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (struct AsmParseError): title.
(enum InlineAsmDirSpec): title.
(enum InlineAsmOptions): title.
(struct AsmArg): title.
(parseAsmArg): title.
(parse_global_asm): title.
(parse_nonglobal_asm): title.
(parse_asm): title.
(parseDirSpec): title.
(parse_format_string): title.
(MacroBuiltin::global_asm_handler): title.
(MacroBuiltin::nonglobal_asm_handler): title.
* expand/rust-macro-builtins.cc: title.
* expand/rust-macro-builtins.h: title.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 178 +
 gcc/rust/expand/rust-macro-builtins.cc |   6 +-
 gcc/rust/expand/rust-macro-builtins.h  |   6 +
 3 files changed, 186 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index e50694dffe5..7958d91537a 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -18,3 +18,181 @@
 
 #include "rust-macro-builtins.h"
 #include "rust-macro-builtins-helpers.h"
+#include "rust-macro-invoc-lexer.h"
+
+namespace Rust {
+
+struct AsmParseError
+{
+};
+
+// This is just an enum to hold some operands right now.
+enum InlineAsmDirSpec
+{
+  In,
+  Out,
+  InOut,
+  SplitInOut,
+  Const,
+  Sym,
+  Label,
+};
+
+enum InlineAsmOptions
+{
+
+};
+
+typedef std::string symbol_name;
+typedef std::vector Templates;
+typedef std::vector Operands;
+typedef std::map RegisterArgs;
+typedef std::map ClobberAbis;
+typedef std::map NamedValues;
+
+struct AsmArg
+{
+  Templates templates;
+  Operands operands;
+  std::map named_values;
+  RegisterArgs register_arguments;
+  ClobberAbis clobber_abis;
+  InlineAsmOptions options;
+  std::vector
+options_span; // TODO: @badumbatish @jjasmine I have no idea what span do, 
i
+ // copied it out of rustc_builtin_macros/src/asm.rs
+};
+
+tl::optional
+parseAsmArg (Parser &p, bool is_global_asm);
+static tl::optional
+parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
+static tl::optional
+parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
+static tl::optional
+parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
+  bool is_global_asm);
+
+tl::optional
+parseDirSpec (Parser &p, TokenId last_token_id)
+{
+  return tl::nullopt;
+}
+tl::optional
+parseAsmArg (Parser &p, bool is_global_asm)
+{
+  return tl::nullopt;
+}
+
+tl::optional
+parse_format_string (Parser &parser, TokenId last_token_id)
+{
+  auto token = parser.peek_current_token ();
+
+  if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
+{
+  // very nice, we got a supposedly formatted string.
+  std::cout << token->get_token_description () << std::endl;
+  parser.skip_token ();
+  return "formatted string";
+}
+  else
+{
+  parser.skip_token ();
+  std::cout << token->get_token_description () << std::endl;
+
+  rust_error_at (token->get_locus (),
+"asm template must be a string literal");
+  return tl::nullopt;
+}
+}
+
+tl::optional
+MacroBuiltin::global_asm_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc)
+{
+  // Just to clarify the code
+  bool is_global_asm = true;
+  return parse_asm (invoc_locus, invoc, is_global_asm);
+}
+
+tl::optional
+MacroBuiltin::nonglobal_asm_handler (location_t invoc_locus,
+AST::MacroInvocData &invoc)
+{
+  // Just to clarify the code
+  bool is_global_asm = false;
+  return parse_asm (invoc_locus, invoc, is_global_asm);
+}
+
+static tl::optional
+parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
+  bool is_global_asm)
+{
+  // From the rule of asm.
+  // We first peek and see if it is a format string or not.
+  // If yes, we process the first ever format string, and move on to the
+  // recurrent of format string Else we exit out
+
+  // After that, we peek and see if it is a reoccuring stream of format string
+  // or not. If it is, keep on going to do this format string. Else, move on
+
+  // After that, we peek and see if it is a reoccuring stream of operands or 
not
+  // If it is, keep on going to do this operand thingy.
+  // Else, move on
+
+  // We check if there is an optional "," at the end, per ABNF spec.
+  // If it is, consume it.
+
+  // Done
+  MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
+  Parser parser (lex);
+  auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
+
+  // Parse the first ever formatted string, success or not, will skip 1 token
+  auto fm_string = parse_format_string (parser, last_token_id);
+  if (fm_string == tl::nullopt)
+return tl::nullopt;
+
+  // formatted string stream
+  auto token = parser.peek_current_token ();
+ 

[COMMITTED 101/145] gccrs: Slim down the test cases

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_faulty_clobber.rs: compress
the test
* rust/compile/inline_asm_nop.rs: compress
the test
* rust/compile/inline_asm_faulty_clobber_1.rs: Removed.
* rust/compile/inline_asm_faulty_clobber_2.rs: Removed.
* rust/compile/inline_asm_nop_2.rs: Removed.
---
 .../rust/compile/inline_asm_faulty_clobber.rs|  2 ++
 .../rust/compile/inline_asm_faulty_clobber_1.rs  | 12 
 .../rust/compile/inline_asm_faulty_clobber_2.rs  | 12 
 gcc/testsuite/rust/compile/inline_asm_nop.rs |  1 +
 gcc/testsuite/rust/compile/inline_asm_nop_2.rs   | 12 
 5 files changed, 3 insertions(+), 36 deletions(-)
 delete mode 100644 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
 delete mode 100644 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
 delete mode 100644 gcc/testsuite/rust/compile/inline_asm_nop_2.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
index 1358b5eb490..ea3dac7734e 100644
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
@@ -8,5 +8,7 @@ macro_rules! asm {
 fn main() {
 unsafe {
 asm!("nop", clobber_abi());  // { dg-error "at least one abi must be 
provided as an argument to 'clobber_abi'" }
+asm!("nop", clobber_abi+);  // { dg-error "expected '\\(', found 
'\\+'" }
+asm!("nop", clobber_abi);  // { dg-error "expected '\\(', found end of 
macro arguments" }
 }
 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
deleted file mode 100644
index 56889923939..000
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_builtin_macro]
-macro_rules! asm {
-() => {}
-}
-
-fn main() {
-unsafe {
-asm!("nop", clobber_abi);  // { dg-error "expected '\\(', found end of 
macro arguments" }
-}
-}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
deleted file mode 100644
index 98cd0525f55..000
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_builtin_macro]
-macro_rules! asm {
-() => {}
-}
-
-fn main() {
-unsafe {
-asm!("nop", clobber_abi+);  // { dg-error "expected '\\(', found 
'\\+'" }
-}
-}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_nop.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop.rs
index 7da9bef3e56..ba21d024079 100644
--- a/gcc/testsuite/rust/compile/inline_asm_nop.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_nop.rs
@@ -8,5 +8,6 @@ macro_rules! asm {
 fn main() {
 unsafe {
 asm!("nop");
+asm!("nop",);
 }
 }
diff --git a/gcc/testsuite/rust/compile/inline_asm_nop_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
deleted file mode 100644
index 76f53fadbe3..000
--- a/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(rustc_attrs)]
-
-#[rustc_builtin_macro]
-macro_rules! asm {
-() => {}
-}
-
-fn main() {
-unsafe {
-asm!("nop",);
-}
-}
-- 
2.45.2



[COMMITTED 100/145] gccrs: Refactoring for inline asm pr

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct AnonConst):
major refactoring of inline asm, mostly concerns
naming convention, trinary conditionals, warnings,
adding rust_unreachables in not-yet supported errors.
(struct InlineAsmRegOrRegClass): Likewise.
(struct InlineAsmOperand): Likewise.
* expand/rust-macro-builtins-asm.cc (parse_clobber_abi): Likewise.
(parse_reg): Likewise.
(parse_operand): Likewise.
(parse_reg_operand): Likewise.
(check_and_set): Likewise.
(parse_options): Likewise.
(parse_format_string): Likewise.
(parse_asm_arg): Likewise.
(parse_asm): Likewise.
* expand/rust-macro-builtins-asm.h (parse_asm_arg): Likewise.
(check_identifier): Likewise.
(check_and_set): Likewise.
(parse_operand): Likewise.
(parse_reg_operand): Likewise.
(parse_options): Likewise.
(parse_reg): Likewise.
(parse_clobber_abi): Likewise.
* expand/rust-macro-builtins.cc (enum class): Likewise.
(inline_asm_maker): Likewise.
* checks/errors/borrowck/ffi-polonius/Cargo.lock: Removed. Likewise.

gcc/testsuite/ChangeLog:
* rust/compile/inline_asm_faulty_clobber.rs: Likewise.
* rust/compile/inline_asm_faulty_clobber_1.rs: Likewise.
* rust/compile/inline_asm_faulty_clobber_2.rs: Likewise.
* rust/compile/inline_asm_illegal_options.rs: Likewise.
---
 gcc/rust/ast/rust-expr.h  |  88 ++-
 .../errors/borrowck/ffi-polonius/Cargo.lock   |  39 -
 gcc/rust/expand/rust-macro-builtins-asm.cc| 139 ++
 gcc/rust/expand/rust-macro-builtins-asm.h |  28 ++--
 gcc/rust/expand/rust-macro-builtins.cc|  10 +-
 .../rust/compile/inline_asm_faulty_clobber.rs |   2 +-
 .../compile/inline_asm_faulty_clobber_1.rs|   2 +-
 .../compile/inline_asm_faulty_clobber_2.rs|   2 +-
 .../compile/inline_asm_illegal_options.rs |   4 +-
 9 files changed, 142 insertions(+), 172 deletions(-)
 delete mode 100644 gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 1284c7367fe..ad742bfe85d 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -6,7 +6,7 @@
 #include "rust-path.h"
 #include "rust-macro.h"
 #include "rust-operators.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace AST {
@@ -4723,22 +4723,20 @@ enum class InlineAsmOption
 struct AnonConst
 {
   NodeId id;
-  std::unique_ptr value;
+  std::unique_ptr expr;
   AnonConst () {}
   AnonConst (const AnonConst &other)
   {
 id = other.id;
-value = other.value == nullptr
- ? nullptr
- : std::unique_ptr (other.value->clone_expr ());
+if (other.expr)
+  expr = other.expr->clone_expr ();
   }
 
   AnonConst operator= (const AnonConst &other)
   {
 id = other.id;
-value = other.value == nullptr
- ? nullptr
- : std::unique_ptr (other.value->clone_expr ());
+if (other.expr)
+  expr = other.expr->clone_expr ();
 return *this;
   }
 };
@@ -4763,7 +4761,7 @@ struct InlineAsmRegOrRegClass
 
   Type type;
   struct Reg reg;
-  struct RegClass regClass;
+  struct RegClass reg_class;
 
   Identifier name;
   location_t locus;
@@ -4790,17 +4788,15 @@ struct InlineAsmOperand
 In (const struct In &other)
 {
   reg = other.reg;
-  expr = other.expr == nullptr
-  ? nullptr
-  : std::unique_ptr (other.expr->clone_expr ());
+  if (other.expr)
+   expr = other.expr->clone_expr ();
 }
 
 In operator= (const struct In &other)
 {
   reg = other.reg;
-  expr = other.expr == nullptr
-  ? nullptr
-  : std::unique_ptr (other.expr->clone_expr ());
+  if (other.expr)
+   expr = other.expr->clone_expr ();
 
   return *this;
 }
@@ -4817,18 +4813,16 @@ struct InlineAsmOperand
 {
   reg = other.reg;
   late = other.late;
-  expr = other.expr == nullptr
-  ? nullptr
-  : std::unique_ptr (other.expr->clone_expr ());
+  if (other.expr)
+   expr = other.expr->clone_expr ();
 }
 
 Out operator= (const struct Out &other)
 {
   reg = other.reg;
   late = other.late;
-  expr = other.expr == nullptr
-  ? nullptr
-  : std::unique_ptr (other.expr->clone_expr ());
+  if (other.expr)
+   expr = other.expr->clone_expr ();
   return *this;
 }
   };
@@ -4844,18 +4838,17 @@ struct InlineAsmOperand
 {
   reg = other.reg;
   late = other.late;
-  expr = other.expr == nullptr
-  ? nullptr
-  : std::unique_ptr (other.expr->clone_expr ());
+  if (other.expr)
+   expr = other.expr->clone_expr ();
 }
 
 InOut operator= (const struct InOut &other)
 {
   reg = other.reg;
 

[COMMITTED 089/145] gccrs: Wraps inline_asm tests in unsafe {}

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_faulty_clobber.rs:
Wraps inline_asm tests in unsafe {}
* rust/compile/inline_asm_faulty_clobber_1.rs: likewise.
* rust/compile/inline_asm_faulty_clobber_2.rs: likewise.
* rust/compile/inline_asm_ident_first.rs: likewise.
* rust/compile/inline_asm_nop.rs: likewise.
* rust/compile/inline_asm_nop_2.rs: likewise.
---
 gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs   | 4 +++-
 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs | 4 +++-
 gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs | 4 +++-
 gcc/testsuite/rust/compile/inline_asm_ident_first.rs  | 4 +++-
 gcc/testsuite/rust/compile/inline_asm_nop.rs  | 4 +++-
 gcc/testsuite/rust/compile/inline_asm_nop_2.rs| 4 +++-
 6 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
index 8d040ea40b4..67dc10bd75b 100644
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!("nop", clobber_abi());  // { dg-error "at least one abi must be 
provided as an argument to `clobber_abi`" }
+unsafe {
+asm!("nop", clobber_abi());  // { dg-error "at least one abi must be 
provided as an argument to `clobber_abi`" }
+}
 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
index 77af10177c4..2906ea4292a 100644
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_1.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!("nop", clobber_abi);  // { dg-error "expected `\\(`, found end of 
macro arguments" }
+unsafe {
+asm!("nop", clobber_abi);  // { dg-error "expected `\\(`, found end of 
macro arguments" }
+}
 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
index ae3607ffa77..e5bf1d1f7f6 100644
--- a/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_faulty_clobber_2.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!("nop", clobber_abi+);  // { dg-error "expected `\\(`, found `\\+`" }
+unsafe {
+asm!("nop", clobber_abi+);  // { dg-error "expected `\\(`, found 
`\\+`" }
+}
 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_ident_first.rs 
b/gcc/testsuite/rust/compile/inline_asm_ident_first.rs
index 9a4eb7ee402..a425b8e5ad4 100644
--- a/gcc/testsuite/rust/compile/inline_asm_ident_first.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_ident_first.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!(i_am_a_dummy); // { dg-error "asm template must be a string literal" }
+unsafe {
+asm!(i_am_a_dummy); // { dg-error "asm template must be a string 
literal" }
+}
 }
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_nop.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop.rs
index ffe3161cd73..7da9bef3e56 100644
--- a/gcc/testsuite/rust/compile/inline_asm_nop.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_nop.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!("nop");
+unsafe {
+asm!("nop");
+}
 }
diff --git a/gcc/testsuite/rust/compile/inline_asm_nop_2.rs 
b/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
index 8437e8fc66c..76f53fadbe3 100644
--- a/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_nop_2.rs
@@ -6,5 +6,7 @@ macro_rules! asm {
 }
 
 fn main() {
-asm!("nop",);
+unsafe {
+asm!("nop",);
+}
 }
-- 
2.45.2



[COMMITTED 084/145] gccrs: Top level parsing test for asm!

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_ident_first.rs: New test.
---
 gcc/testsuite/rust/compile/inline_asm_ident_first.rs | 10 ++
 1 file changed, 10 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_ident_first.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_ident_first.rs 
b/gcc/testsuite/rust/compile/inline_asm_ident_first.rs
new file mode 100644
index 000..9a4eb7ee402
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_ident_first.rs
@@ -0,0 +1,10 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+asm!(i_am_a_dummy); // { dg-error "asm template must be a string literal" }
+}
\ No newline at end of file
-- 
2.45.2



[COMMITTED 131/145] gccrs: Store parse result of parse_format_string(s)

2025-03-17 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct TupleTemplateStr):
Store parse result of parse_format_string(s)
* expand/rust-macro-builtins-asm.cc (parse_format_strings):
Likewise

Signed-off-by: badumbatish 
---
 gcc/rust/ast/rust-expr.h   |  7 +--
 gcc/rust/expand/rust-macro-builtins-asm.cc | 17 -
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9787e9ae123..f3ebf0bbdde 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -5057,9 +5057,12 @@ struct TupleClobber
 struct TupleTemplateStr
 {
   // as gccrs still doesn't contain a symbol class I have put them as strings
-  std::string symbol;
-  std::string optional_symbol;
   location_t loc;
+  std::string symbol;
+
+  TupleTemplateStr (location_t loc, const std::string &symbol)
+: loc (loc), symbol (symbol)
+  {}
 };
 
 // Inline Assembly Node
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 87c90a290ac..94927fd0849 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -784,12 +784,20 @@ parse_format_strings (InlineAsmContext inline_asm_ctx)
   auto last_token_id = inline_asm_ctx.last_token_id;
   auto fm_string = parse_format_string (inline_asm_ctx);
 
+  auto &inline_asm = inline_asm_ctx.inline_asm;
+  auto token = parser.peek_current_token ();
   if (fm_string == tl::nullopt)
 {
   rust_error_at (parser.peek_current_token ()->get_locus (),
 "%s template must be a string literal", "asm");
   return tl::unexpected (COMMITTED);
 }
+  else
+{
+  auto template_str
+   = AST::TupleTemplateStr (token->get_locus (), fm_string.value ());
+  inline_asm.template_strs.push_back (template_str);
+}
 
   // formatted string stream
 
@@ -803,15 +811,22 @@ parse_format_strings (InlineAsmContext inline_asm_ctx)
   // in here, which is formatted string in ABNF
   inline_asm_ctx.consumed_comma_without_formatted_string = false;
 
+  token = parser.peek_current_token ();
   fm_string = parse_format_string (inline_asm_ctx);
   if (fm_string == tl::nullopt)
{
  inline_asm_ctx.consumed_comma_without_formatted_string = true;
  break;
}
+  else
+   {
+ auto template_str
+   = AST::TupleTemplateStr (token->get_locus (), fm_string.value ());
+ inline_asm.template_strs.push_back (template_str);
+   }
 }
 
-  return tl::expected (inline_asm_ctx);
+  return inline_asm_ctx;
 }
 
 // bool
-- 
2.45.2



[COMMITTED 097/145] gccrs: Renamed parseAsmArg to conform to other function names

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parseAsmArg):
Renamed parseAsmArg to conform to other function names
(parse_asm_arg): Likewise.
(parse_asm): Likewise.
* expand/rust-macro-builtins-asm.h (parseAsmArg): Likewise.
(parse_asm_arg): Likewise.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 6 +++---
 gcc/rust/expand/rust-macro-builtins-asm.h  | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index f7703ddd730..3ce9bf9d78b 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -385,8 +385,8 @@ MacroBuiltin::asm_handler (location_t invoc_locus, 
AST::MacroInvocData &invoc,
 }
 
 int
-parseAsmArg (Parser &parser, TokenId last_token_id,
-InlineAsmContext &inlineAsmCtx)
+parse_asm_arg (Parser &parser, TokenId last_token_id,
+  InlineAsmContext &inlineAsmCtx)
 {
   auto token = parser.peek_current_token ();
   tl::optional fm_string;
@@ -505,7 +505,7 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
 }
 
   // operands stream, also handles the optional ","
-  parseAsmArg (parser, last_token_id, inlineAsmCtx);
+  parse_asm_arg (parser, last_token_id, inlineAsmCtx);
 
   return tl::nullopt;
 }
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
b/gcc/rust/expand/rust-macro-builtins-asm.h
index 65763780979..a35d7707e6c 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -31,8 +31,8 @@ public:
 };
 
 int
-parseAsmArg (Parser &p, TokenId last_token_id,
-InlineAsmContext &inlineAsmCtx);
+parse_asm_arg (Parser &p, TokenId last_token_id,
+  InlineAsmContext &inlineAsmCtx);
 
 tl::optional
 parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
-- 
2.45.2



[COMMITTED 078/145] gccrs: Fix clobber_api brackets

2025-03-17 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_clobber_abi): title.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index d47d95c594f..74b81d2aed2 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -79,17 +79,17 @@ parse_clobber_abi (Parser &parser, TokenId 
last_token_id,
  // illegal, pleaes emit the correct error.
  return -1;
}
+}
 
-  // Done processing the local clobber abis, push that to the main Args in
-  // argument
-
-  for (auto abi : new_abis)
-   {
- args.clobber_abis.push_back (abi);
-   }
+  // Done processing the local clobber abis, push that to the main Args in
+  // argument
 
-  return 0;
+  for (auto abi : new_abis)
+{
+  args.clobber_abis.push_back (abi);
 }
+
+  return 0;
 }
 
 int
-- 
2.45.2



Re: [PATCH] cobol: Eliminate CPPFLAGS assignment from Make-lang.in [PR119213].

2025-03-17 Thread Andreas Schwab
On Mär 17 2025, Robert Dubner wrote:

> I did it, reflexively, because I think that lining stuff like that up iss
> easier to understand and more clear than.
>
>   PR cobol/119213
>   * Make-lang.in: Eliminate CPPFLAGS= assignment.
>   * cdf.y: Modify #includes that reference libgcobol.
>   * cobol1.cc: Modify #includes that reference libgcobol.
>   * except.cc: Modify #includes that reference libgcobol.
>   * gcobolspec.cc: Modify #includes that reference libgcobol.
>   * genapi.cc: Modify #includes that reference libgcobol.
>   * gengen.cc: Modify #includes that reference libgcobol.
>   * genmath.cc: Modify #includes that reference libgcobol.
>   * genutil.cc: Modify #includes that reference libgcobol.
>   * parse.y: Modify #includes that reference libgcobol.
>   * scan.l: Modify #includes that reference libgcobol.
>   * structs.cc: Modify #includes that reference libgcobol.
>   * symbols.cc: Modify #includes that reference libgcobol.
>   * symfind.cc: Modify #includes that reference libgcobol.
>   * util.cc: Modify #includes that reference libgcobol.

You can replace any repetition by "Likewise."

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


RE: [PATCH] cobol: Eliminate CPPFLAGS assignment from Make-lang.in [PR119213].

2025-03-17 Thread Robert Dubner



> -Original Message-
> From: Jakub Jelinek 
> Sent: Monday, March 17, 2025 17:04
> To: Robert Dubner ; Iain Sandoe
> ; GCC Patches 
> Subject: Re: [PATCH] cobol: Eliminate CPPFLAGS assignment from Make-
> lang.in [PR119213].
> 
> On Mon, Mar 17, 2025 at 09:50:53PM +0100, Jakub Jelinek wrote:
> > https://www.gnu.org/prep/standards/html_node/Change-Logs.html
> > contains some of the reasons and something about the formatting etc.
> > When you repeat the same description over and over, normally one just
> writes
> > * cdf.y: Modify #includes that reference libgcobol.
> > * cobol1.cc: Likewise.
> > * except.cc: Likewise.
> > etc. (or Ditto. instead of Likewise.).
> > The filenames can have different length and in most cases (the above
> case
> > is kind of special since it is a global modification of the files, not
a
> > change in a particular function) there is also often large function
> name,
> > so if you tried to align the descriptions and still had to fit on 80
> > columns, it really wouldn't fit or you could have there just one or
two
> > short words.  Often the description doesn't fit on
> > the same line fully and needs to be wrapped, the space in there is
> precious
> > and consistency is more important than some beatiful look, especially
> when
> > different people would have different opinions on what is nice.
> >
> > There is another rule, if the description contains multiple sentences,
> > dot is followed by 2 spaces unless it is at the end of line (but that
is
> a
> > general formatting rule also e.g. in code comments).
> 
> Consider e.g. the following libstdc++-v3/ChangeLog entry:
>   PR libstdc++/115215
>   PR libstdc++/115218
>   * include/std/ranges
>   (concat_view::iterator::_S_invoke_with_runtime_index): Use
>   __builtin_unreachable in recursive lambda to certify it always
>   exits via 'return'.
>   (concat_view::iterator::iterator): In the const-converting
>   constructor, direct initialize _M_it.
>   (views::_Concat::operator()): Adjust constraints in the
>   single-argument case as per LWG 4082.
>   * testsuite/std/ranges/concat/1.cc (test01): Call it at runtime
>   too.
>   (test04): New test.
> 
> Aligning in that case would be terrible, the length of
> (concat_view::iterator::_S_invoke_with_runtime_index)
> and
> (views::_Concat::operator())
> are significantly different.  In fact the first one is so large
> that it can't be on the same line with the filename.
> 
> I'll also note that when code in the FE or library doesn't use
> function overloading or namespaces or too many methods as opposed to
> just normal functions, one can just use the name of the function
> and e.g. doesn't need to supply the argument types, because it
> isn't ambiguous.
> As mentioned in the above documentation, the function names or
> filenames shouldn't be truncated or wildcards used in them because
> people actively search the ChangeLog for filenames and function names.
> 
>   Jakub

I am old enough that when my kid tells me that "Dad, two spaces after a
period is just so Boomer," I just say, "I know", and I keep typing them.
I do it everywhere, so it shouldn't be a problem here.  I see that I am
doing it here, without even thinking about it.

"Consistency over disagreement" is a powerful consideration.

I'll look at the documentation.

Thank you very much.  

Bob D.


[COMMITTED] cobol: Eliminate CPPFLAGS assignment from Make-lang.in

2025-03-17 Thread Robert Dubner
I'll close out PR119213.

And next time I'll use "Likewise."

>From 8d6c8efdd9495259cc5ed1d6537c694791bd4661 Mon Sep 17 00:00:00 2001
From: Bob Dubner mailto:rdub...@symas.com
Date: Mon, 17 Mar 2025 13:13:50 -0400
Subject: [PATCH] cobol: Eliminate CPPFLAGS assignment from Make-lang.in
 [PR119213].

A number of gcc/cobol files had to be modified to
'#include "../../libgcobol/xxx.h" instead of "xxx.h"

gcc/cobol

PR cobol/119213
* Make-lang.in: Eliminate CPPFLAGS= assignment.
* cdf.y: Modify #includes that reference libgcobol.
* cobol1.cc: Modify #includes that reference libgcobol.
* except.cc: Modify #includes that reference libgcobol.
* gcobolspec.cc: Modify #includes that reference libgcobol.
* genapi.cc: Modify #includes that reference libgcobol.
* gengen.cc: Modify #includes that reference libgcobol.
* genmath.cc: Modify #includes that reference libgcobol.
* genutil.cc: Modify #includes that reference libgcobol.
* parse.y: Modify #includes that reference libgcobol.
* scan.l: Modify #includes that reference libgcobol.
* structs.cc: Modify #includes that reference libgcobol.
* symbols.cc: Modify #includes that reference libgcobol.
* symfind.cc: Modify #includes that reference libgcobol.
* util.cc: Modify #includes that reference libgcobol.
---
 gcc/cobol/Make-lang.in  | 45 ++---
 gcc/cobol/cdf.y |  6 +++---
 gcc/cobol/cobol1.cc |  8 
 gcc/cobol/except.cc | 10 -
 gcc/cobol/gcobolspec.cc |  7 +++
 gcc/cobol/genapi.cc | 14 ++---
 gcc/cobol/gengen.cc |  4 ++--
 gcc/cobol/genmath.cc| 10 -
 gcc/cobol/genutil.cc| 14 ++---
 gcc/cobol/parse.y   | 16 +++
 gcc/cobol/scan.l|  6 +++---
 gcc/cobol/structs.cc|  4 ++--
 gcc/cobol/symbols.cc|  6 +++---
 gcc/cobol/symfind.cc|  6 +++---
 gcc/cobol/util.cc   |  6 +++---
 15 files changed, 82 insertions(+), 80 deletions(-)

diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index 650b695e7ef5..5707768f1be7 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -43,26 +43,8 @@ cobol: cobol1$(exeext)
 cobol.serial = cobol1$(exeext)
 .PHONY: cobol
 
-BINCLUDE ?= ./gcc
-LIB_INCLUDE ?= $(srcdir)/../libgcobol
 LIB_SOURCE ?= $(srcdir)/../libgcobol
 
-#
-# At this point, as of 2022-10-21, CPPFLAGS is an empty string and can be
-# altered.  CFLAGS and CXXFLAGS are being established upstream, and thus
-# cannot, at this point, be changed.
-#
-# Note further that we are producing only a 64-bit version of
libgcobol.so, so
-# it is safe to hard-code the lib64 location.  This obviously has to
match the
-# installation code in libgcobol/Makefile.in
-#
-CPPFLAGS = \
- -std=c++14\
- -I$(BINCLUDE) \
- -I$(LIB_INCLUDE)  \
- -DEXEC_LIB=\"$(prefix)/lib64\"\
- $(END)
-
 YFLAGS = -Werror -Wmidrule-values -Wno-yacc \
--debug --verbose
 
@@ -96,16 +78,37 @@ cobol1_OBJS =\
 # There is source code in libgcobol/charmaps.cc and
 # libgcobol/valconv.cc that needs to be compiled into both libgcobol
 # and cobol1.  We copy those two source code files from libgcobol to
-# here to avoid the nightmare of one file appearing in more than one
-# place.  For simplicity, we make those compilations dependent on all
-# of the libgcobol/*.h files, which might lead to the occasional
+# build/gcc/cobol to avoid the nightmare of one file appearing in more
+# than one place.  For simplicity, we make those compilations dependent
+# on all of the libgcobol/*.h files, which might lead to the occasional
 # unnecessary compilation.  The impact of that is negligible.
 #
+# Various #includes in the files copied from gcc/libgcobol need to be
modified
+# so that the .h files can be found.
+
 cobol/charmaps.cc: $(LIB_SOURCE)/charmaps.cc
cp $^ $@
+   sed -i "s|\"ec[.]h\"|\"$(LIB_SOURCE)/ec.h\"|g" $@
+   sed -i "s|\"common-defs[.]h\"|\"$(LIB_SOURCE)/common-defs.h\"|g"
$@
+   sed -i "s|\"io[.]h\"|\"$(LIB_SOURCE)/io.h\"|g" $@
+   sed -i "s|\"gcobolio[.]h\"|\"$(LIB_SOURCE)/gcobolio.h\"|g" $@
+   sed -i "s|\"libgcobol[.]h\"|\"$(LIB_SOURCE)/libgcobol.h\"|g" $@
+   sed -i "s|\"gfileio[.]h\"|\"$(LIB_SOURCE)/gfileio.h\"|g" $@
+   sed -i "s|\"charmaps[.]h\"|\"$(LIB_SOURCE)/charmaps.h\"|g" $@
+   sed -i "s|\"valconv[.]h\"|\"$(LIB_SOURCE)/valconv.h\"|g" $@
+   sed -i "s|\"exceptl[.]h\"|\"$(LIB_SOURCE)/exceptl.h\"|g" $@
 
 cobol/valconv.cc: $(LIB_SOURCE)/valconv.cc
cp $^ $@
+   sed -i "s|\"ec[.]h\"|\"$(LIB_SOURCE)/ec.h\"|g" $@
+   sed -i "s|\"common-defs[.]h\"|\"$(LIB_SOURCE)/common-defs.h\"|g"
$@
+   sed -i "s|\"io[.]h\"|\"$(LIB_SOURCE)/io.h\"|g" $@
+   sed -i "s|\"gcobolio[.]h\"|\"$(LIB_SOURCE)/gcobolio.h\"|g" $@
+   s

[COMMITTED 144/145] gccrs: [gccrs#2987] Patch ICE when deriving Clone and Copy

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

gcc/rust/ChangeLog:
* expand/rust-expand-visitor.cc:
Fix ICE caused by unique_ptr UB and buggy iterator use

gcc/testsuite/ChangeLog:
* rust/compile/issue-2987.rs:
Add test for deriving Clone and Copy at the same time

Signed-off-by: Liam Naddell 
---
 gcc/rust/expand/rust-expand-visitor.cc   | 17 +
 gcc/testsuite/rust/compile/issue-2987.rs | 17 +
 2 files changed, 26 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2987.rs

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 61147e2d726..38399d0d74b 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -167,10 +167,10 @@ ExpandVisitor::expand_inner_items (
 
   for (auto it = items.begin (); it != items.end (); it++)
 {
-  auto &item = *it;
-  if (item->has_outer_attrs ())
+  Rust::AST::Item &item = **it;
+  if (item.has_outer_attrs ())
{
- auto &attrs = item->get_outer_attrs ();
+ auto &attrs = item.get_outer_attrs ();
 
  for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
   /* erase => No increment*/)
@@ -190,16 +190,17 @@ ExpandVisitor::expand_inner_items (
  if (maybe_builtin.has_value ())
{
  auto new_item
-   = builtin_derive_item (*item, current,
+   = builtin_derive_item (item, current,
   maybe_builtin.value ());
- // this inserts the derive *before* the item - is it a
- // problem?
+
  it = items.insert (it, std::move (new_item));
}
  else
{
+ // Macro is not a builtin, so it must be a
+ // user-defined derive macro.
  auto new_items
-   = derive_item (*item, to_derive, expander);
+   = derive_item (item, to_derive, expander);
  std::move (new_items.begin (), new_items.end (),
 std::inserter (items, it));
}
@@ -215,7 +216,7 @@ ExpandVisitor::expand_inner_items (
{
  attr_it = attrs.erase (attr_it);
  auto new_items
-   = expand_item_attribute (*item, current.get_path (),
+   = expand_item_attribute (item, current.get_path (),
 expander);
  it = items.erase (it);
  std::move (new_items.begin (), new_items.end (),
diff --git a/gcc/testsuite/rust/compile/issue-2987.rs 
b/gcc/testsuite/rust/compile/issue-2987.rs
new file mode 100644
index 000..1ab5fdc3647
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2987.rs
@@ -0,0 +1,17 @@
+// { dg-options "-w" } Currently there are a lot of warnings produced from 
inside clone/copy
+// builtins
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "clone"]
+trait Clone {
+fn clone(&self) -> Self;
+}
+
+#[derive(Copy)]
+#[derive(Clone)]
+struct Empty;
+
+#[derive(Copy,Clone)]
+struct Empty2;
-- 
2.45.2



[PATCH] c++: memfn pointer as NTTP argument considered unused [PR119233]

2025-03-17 Thread Patrick Palka
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/backports?

-- >8 --

This is just the member function pointer version of PR c++/105848,
wherein our non-dependent call pruning may cause us to not mark an
otherwise unused function pointer template argument as used.

PR c++/119233

gcc/cp/ChangeLog:

* pt.cc (mark_template_arguments_used): Also handle member
function pointers.

gcc/testsuite/ChangeLog:

* g++.dg/template/fn-ptr5.C: New test.
---
 gcc/cp/pt.cc|  6 ++
 gcc/testsuite/g++.dg/template/fn-ptr5.C | 28 +
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/fn-ptr5.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8aaae446868..50eda189c43 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22491,6 +22491,12 @@ mark_template_arguments_used (tree tmpl, tree args)
  gcc_checking_assert (ok || seen_error ());
}
}
+  /* A member function pointer.  */
+  else if (TREE_CODE (arg) == PTRMEM_CST)
+   {
+ bool ok = mark_used (PTRMEM_CST_MEMBER (arg), tf_none);
+ gcc_checking_assert (ok || seen_error ());
+   }
   /* A class NTTP argument.  */
   else if (VAR_P (arg)
   && DECL_NTTP_OBJECT_P (arg))
diff --git a/gcc/testsuite/g++.dg/template/fn-ptr5.C 
b/gcc/testsuite/g++.dg/template/fn-ptr5.C
new file mode 100644
index 000..db3113109ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/fn-ptr5.C
@@ -0,0 +1,28 @@
+// PR c++/119233
+// A version of fn-ptr3a.C using member instead of non-member function
+// pointers.
+
+struct B {
+  template
+  void f(T) { T::fail; } // { dg-error "fail" }
+};
+
+template
+struct A {
+  // P not called
+};
+
+template
+void wrap() {
+  // P not called
+}
+
+template
+void g() {
+  A<&B::f> a; // { dg-message "required from" }
+  wrap<&B::f>(); // { dg-message "required from" }
+}
+
+int main() {
+  g<0>();
+}
-- 
2.49.0.rc1.37.ge969bc8759



RE: [PATCH] COBOL v3: 3/14 80K bld: config and build machinery

2025-03-17 Thread Robert Dubner



> -Original Message-
> From: Andreas Schwab 
> Sent: Monday, March 17, 2025 04:13
> To: James K. Lowden 
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH] COBOL v3: 3/14 80K bld: config and build machinery
>
> On Mär 13 2025, James K. Lowden wrote:
>
> > On Tue, 11 Mar 2025 11:18:22 +0100
> > Andreas Schwab  wrote:
> >
> >> libgcobol/configure.tgt says it's supported on powerpc64le.
> >
> > Our intention, tell me if you disagree, is that cobol is enabled if
> >
> > 1.  --enable-languages=all, and
> > 2.  the host and target are "known good", x86_64 or aarch64
>
> But powerpc64le is known good as well.
>
> --
> Andreas Schwab, SUSE Labs, sch...@suse.de
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."

...and I answered you before I noticed the later message from Richard and 
Sam.  I will now sit on my hands.


[PATCH] cobol: Fifteen new cobol.dg testscases.

2025-03-17 Thread Robert Dubner
These tests have been curated for relative shortness of output.  The worst
case has 61 lines.

I am hoping that this one is...

Okay for trunk?


>From 457d94c65047856123185716e882af18833c67ee Mon Sep 17 00:00:00 2001
From: Bob Dubner mailto:rdub...@symas.com
Date: Mon, 17 Mar 2025 21:47:05 -0400
Subject: [PATCH] cobol: Fifteen new cobol.dg testscases.

gcc/testsuite

* cobol.dg/group1/check_88.cob: New testcase.
* cobol.dg/group1/comp5.cob: Likewise.
* cobol.dg/group1/declarative_1.cob: Likewise.
* cobol.dg/group1/display.cob: Likewise.
* cobol.dg/group1/display2.cob: Likewise.
* cobol.dg/group1/line-sequential.cob: Likewise.
* cobol.dg/group1/multiple-compares.cob: Likewise.
* cobol.dg/group1/multiply2.cob: Likewise.
* cobol.dg/group1/packed.cob: Likewise.
* cobol.dg/group1/perform-nested-exit.cob: Likewise.
* cobol.dg/group1/pointer1.cob: Likewise.
* cobol.dg/group1/simple-arithmetic.cob: Likewise.
* cobol.dg/group1/simple-classes.cob: Likewise.
* cobol.dg/group1/simple-if.cob: Likewise.
* cobol.dg/group1/simple-perform.cob: Likewise.
---
 gcc/testsuite/cobol.dg/group1/check_88.cob| 101 +
 gcc/testsuite/cobol.dg/group1/comp5.cob   |  72 +++
 .../cobol.dg/group1/declarative_1.cob | 116 +++
 gcc/testsuite/cobol.dg/group1/display.cob |  14 ++
 gcc/testsuite/cobol.dg/group1/display2.cob|   7 +
 .../cobol.dg/group1/line-sequential.cob   |  34 
 .../cobol.dg/group1/multiple-compares.cob | 192 ++
 gcc/testsuite/cobol.dg/group1/multiply2.cob   |  68 +++
 gcc/testsuite/cobol.dg/group1/packed.cob  |  73 +++
 .../cobol.dg/group1/perform-nested-exit.cob   |  84 
 gcc/testsuite/cobol.dg/group1/pointer1.cob|  98 +
 .../cobol.dg/group1/simple-arithmetic.cob |  61 ++
 .../cobol.dg/group1/simple-classes.cob|  68 +++
 gcc/testsuite/cobol.dg/group1/simple-if.cob   | 143 +
 .../cobol.dg/group1/simple-perform.cob|  52 +
 15 files changed, 1183 insertions(+)
 create mode 100644 gcc/testsuite/cobol.dg/group1/check_88.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/comp5.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/declarative_1.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/display.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/display2.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/line-sequential.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/multiple-compares.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/multiply2.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/packed.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/perform-nested-exit.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/pointer1.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/simple-arithmetic.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/simple-classes.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/simple-if.cob
 create mode 100644 gcc/testsuite/cobol.dg/group1/simple-perform.cob

diff --git a/gcc/testsuite/cobol.dg/group1/check_88.cob
b/gcc/testsuite/cobol.dg/group1/check_88.cob
new file mode 100644
index ..4a7723eb92a3
--- /dev/null
+++ b/gcc/testsuite/cobol.dg/group1/check_88.cob
@@ -0,0 +1,101 @@
+*> { dg-do run }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output {\->   <\-(\n|\r\n|\r)} }
+*> { dg-output {\->"""<\-(\n|\r\n|\r)} }
+*> { dg-output {\->000<\-(\n|\r\n|\r)} }
+*> { dg-output {\->ÿÿÿ<\-(\n|\r\n|\r)} }
+*> { dg-output { (\n|\r\n|\r)} }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output {\-><\-(\n|\r\n|\r)} }
+*> { dg-output { (\n|\r\n|\r)} }
+*> { dg-output {There should be no garbage after character
32(\n|\r\n|\r)} }
+*> { dg-output
{\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\*\-\-\-\-\
-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-(\n|\r\n|\r)} }
+*> { dg-output {üüü Bundesstraße
(\n|\r\n|\r)} }
+*> { dg-output {üüü Bundesstraße
(\n|\r\n|\r)} }
+*> { dg-output { (\n|\r\n|\r)} }
+*> { dg-output {There should be no spaces before the final
quote(\n|\r\n|\r)} }
+*> { dg-output {"üüü Bundesstraße"(\n|\r\n|\r)} }
+*> { dg-output { (\n|\r\n|\r)} }
+*> { dg-output {   IsLow   ""(\n|\r\n|\r)} }
+*> { dg-output {   IsZero  "000"(\n|\r\n|\r)} }
+*> { dg-output {   IsHi"ÿÿÿ"(\n|\r\n|\r)} }
+*> { dg-output {   IsBob   "bob"(\n|\r\n|\r)} }
+*> { dg-output {   IsQuote "(\n|\r\n|\r)} }
+*> { dg-output {   IsSpace "   "(\n|\r\n|\r)} }
+*> { dg-output { (\n|\r\n|\r)} }
+*> { dg-output {CheckBinary Properly True(\n|\r\n|\r)} }
+*> { dg-output {CheckBinary Properly False} }
+IDENTIFICATION DIVISION.
+PROGRAM-ID. check88.
+DATA DIVISION.
+WORKING-S

Re: [PATCH] c++: ICE when substituting packs into type aliases [PR118104]

2025-03-17 Thread Patrick Palka
On Mon, 17 Mar 2025, Marek Polacek wrote:

> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13?
> 
> -- >8 --
> r12-1094 mentions that adding the assert didn't lead to any regressions
> in the testsuite, but this test case demonstrates that we can reach it
> with valid code.
> 
> Here we arrive in use_pack_expansion_extra_args_p with t which is an
> expansion whose pattern is void(Ts, Us) and tparm packs are {Us, Ts},
> and parm_packs is { Ts -> , Us ->  }.  We want to
> expand the pack into void(int, A) and void(int, P...).  We compare
> int to A, which is fine, but then int to P... which crashes.  But
> the code is valid so this patch removes the assert.
> 
>   PR c++/118104
> 
> gcc/cp/ChangeLog:
> 
>   * pt.cc (use_pack_expansion_extra_args_p): Remove an assert.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/alias-decl-variadic3.C: New test.
>   * g++.dg/cpp0x/alias-decl-variadic4.C: New test.
> ---
>  gcc/cp/pt.cc  | 11 ++-
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C | 13 +
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic4.C | 11 +++
>  3 files changed, 34 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic4.C
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 8aaae446868..35c68a6e3f2 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -13180,7 +13180,16 @@ use_pack_expansion_extra_args_p (tree t,
>  
>if (has_expansion_arg && has_non_expansion_arg)
>   {
> -   gcc_checking_assert (false);
> +   /* We can get here with:
> +
> +   template  struct X {
> + template  using Y = Z;
> +   };
> +   template 
> +   using foo = X::Y;
> +
> +  where we compare int and A and then the second int and P...,
> +  whose expansion-ness doesn't match, but that's OK.  */
> return true;
>   }
>  }
> diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C 
> b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C
> new file mode 100644
> index 000..abac9d8b4c0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic3.C
> @@ -0,0 +1,13 @@
> +// PR c++/118104
> +// { dg-do compile { target c++11 } }
> +
> +template  struct X {
> +  template  using Y = X;
> +};
> +
> +template 
> +using any_pairs_list_4 = X::Y;
> +
> +int main() {
> +  any_pairs_list_4 array;
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic4.C 
> b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic4.C
> new file mode 100644
> index 000..c5311801a51
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic4.C
> @@ -0,0 +1,11 @@
> +// PR c++/118104
> +// { dg-do compile { target c++11 } }
> +
> +template struct Z { };
> +
> +template  struct X {
> +  template  using Y = Z;
> +};
> +
> +template 
> +using foo = X::Y;

This testcase seems to basically be a subset of the first one, maybe we
could merge them? e.g. keep the separate class template Z, and also
instantiate foo like in the first testcase.

> 
> base-commit: 051ca98a12908b9685d76b4432cff2f8f0f33368
> -- 
> 2.48.1
> 
> 



[COMMITTED 142/145] gccrs: Added options for ParseMode

2025-03-17 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::collect):
Added options for ParseMode
* ast/rust-fmt.h (collect_pieces): Likewise.
(struct Pieces): Likewise.
* expand/rust-macro-builtins-format-args.cc 
(MacroBuiltin::format_args_handler):
Likewise.

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Likewise.
* libformat_parser/src/bin.rs: Likewise.
* libformat_parser/src/lib.rs: Likewise.
---
 gcc/rust/ast/rust-fmt.cc  |  6 --
 gcc/rust/ast/rust-fmt.h   | 11 +--
 gcc/rust/expand/rust-macro-builtins-format-args.cc|  6 --
 .../libformat_parser/generic_format_parser/src/lib.rs |  1 +
 libgrust/libformat_parser/src/bin.rs  |  3 ++-
 libgrust/libformat_parser/src/lib.rs  |  7 +--
 6 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index cc48c2e3576..a29c8203ae8 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -29,9 +29,11 @@ ffi::RustHamster::to_string () const
 }
 
 Pieces
-Pieces::collect (const std::string &to_parse, bool append_newline)
+Pieces::collect (const std::string &to_parse, bool append_newline,
+ffi::ParseMode parse_mode)
 {
-  auto handle = ffi::collect_pieces (to_parse.c_str (), append_newline);
+  auto handle
+= ffi::collect_pieces (to_parse.c_str (), append_newline, parse_mode);
 
   // this performs multiple copies, can we avoid them maybe?
   // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 31100ea8f84..1db391bafe7 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -258,10 +258,16 @@ struct FormatArgsHandle
   RustString rust_string;
 };
 
+typedef enum
+{
+  Format,
+  InlineAsm,
+} ParseMode;
+
 extern "C" {
 
 FormatArgsHandle
-collect_pieces (const char *input, bool append_newline);
+collect_pieces (const char *input, bool append_newline, ParseMode parse_mode);
 
 FormatArgsHandle
 clone_pieces (const FormatArgsHandle &);
@@ -274,7 +280,8 @@ void destroy_pieces (FormatArgsHandle);
 
 struct Pieces
 {
-  static Pieces collect (const std::string &to_parse, bool append_newline);
+  static Pieces collect (const std::string &to_parse, bool append_newline,
+ffi::ParseMode parse_mode);
   ~Pieces ();
 
   Pieces (const Pieces &other);
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc 
b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index 031007b418b..8eb32d5f1b3 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 #include "rust-ast-fragment.h"
+#include "rust-fmt.h"
 #include "rust-macro-builtins-helpers.h"
 #include "rust-expand-format-args.h"
 
@@ -162,7 +163,8 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
   if (append_newline)
 fmt_str += '\n';
 
-  auto pieces = Fmt::Pieces::collect (fmt_str, append_newline);
+  auto pieces = Fmt::Pieces::collect (fmt_str, append_newline,
+ Fmt::ffi::ParseMode::Format);
 
   // TODO:
   // do the transformation into an AST::FormatArgs node
@@ -191,4 +193,4 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
   //   invoc.get_delim_tok_tree ().to_token_stream ());
 }
 
-} // namespace Rust
\ No newline at end of file
+} // namespace Rust
diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index 25f6b0ead17..ad4d3d9a546 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -78,6 +78,7 @@ enum InputStringKind {
 }
 
 /// The type of format string that we are parsing.
+#[repr(C)]
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum ParseMode {
 /// A normal format string as per `format_args!`.
diff --git a/libgrust/libformat_parser/src/bin.rs 
b/libgrust/libformat_parser/src/bin.rs
index 5f46497c946..a7947afb11c 100644
--- a/libgrust/libformat_parser/src/bin.rs
+++ b/libgrust/libformat_parser/src/bin.rs
@@ -5,6 +5,7 @@ fn main() {
 std::env::args().nth(1).unwrap().as_str(),
 None,
 None,
-false
+false,
+generic_format_parser::ParseMode::Format
 ));
 }
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index f4670bf9b1f..42ad62892bd 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -334,8 +334,9 @@ pub mod rust {
 style: Option,
 snippet: Option,
 append_newline: bool,
+parse_mode: ParseMode
 ) -> 

RE: [PATCH] COBOL v3: 3/14 80K bld: config and build machinery

2025-03-17 Thread Robert Dubner



> -Original Message-
> From: Andreas Schwab 
> Sent: Monday, March 17, 2025 04:13
> To: James K. Lowden 
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH] COBOL v3: 3/14 80K bld: config and build machinery
>
> On Mär 13 2025, James K. Lowden wrote:
>
> > On Tue, 11 Mar 2025 11:18:22 +0100
> > Andreas Schwab  wrote:
> >
> >> libgcobol/configure.tgt says it's supported on powerpc64le.
> >
> > Our intention, tell me if you disagree, is that cobol is enabled if
> >
> > 1.  --enable-languages=all, and
> > 2.  the host and target are "known good", x86_64 or aarch64
>
> But powerpc64le is known good as well.

Does that mean that in addition to compiling the compiler you've been able
to compile and run COBOL with it?  (I don't have a powerpc available on
which to check.)

If so, then that configure.ac case statement can be changed.  Are you
prepared to patch it?  I'll do it, if need be, but I hate pushing changes
that I can't personally test.

Bob D.

>
> --
> Andreas Schwab, SUSE Labs, sch...@suse.de
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."


[PATCH 2/4] rust: Use error_operand_p in rust-gcc.cc

2025-03-17 Thread Andrew Pinski
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 
---
 gcc/rust/rust-gcc.cc | 183 ---
 1 file changed, 85 insertions(+), 98 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index e877c034452..f8b29bc6cf1 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);
   result = result_struct;
 }
-  if (result == error_mark_node)
+  if (error_operand_p (result))
 return error_mark_node;
 
   tree fntype = build_function_type (result, args);
-  if (fntype == error_mark_node)
+  if (error_operand_p (fntype))
 return error_mark_node;
 
   return build_pointer_type (fntype);
@@ -521,21 +521,17 @@ function_type_variadic (const typed_identifier &receiver,
   size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
   tree *a

[PATCH 4/4] rust: Add comment inside block [PR119342]

2025-03-17 Thread Andrew Pinski
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 
---
 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 8a740f72513..53950a35fdc 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1772,6 +1772,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)
 {
-- 
2.43.0



[PATCH 3/4] rust: use range for inside rust-gcc.cc [PR119341]

2025-03-17 Thread Andrew Pinski
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 
---
 gcc/rust/rust-gcc.cc | 56 +---
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index f8b29bc6cf1..8a740f72513 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;
@@ -608,14 +606,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);
@@ -1721,10 +1718,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);
@@ -1778,10 +1773,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);
 }
@@ -1801,10 +1795,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);
 }
@@ -2248,10 +2240,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);
 }
@@ -2277,10 +2268,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;
@@ -2288,8 +2278,7 @@ write_global_definitions (const std::vector 
&type_decls,
++i;
 }
 
-  for (std::vector::const_iterator p = type_decls.begin ();
-   p != type_decls.end (); ++p)
+  for (tree type_tree : type_decls)
 {
   tree type_tree = (*p);
   if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
@@ -2300,20 +2289,17 @@ write_global_definitions (const std::vector 
&type_decls,
  ++i;
}
 }
-  for (std::vector::const_iterator

Re: [PATCH] c: Fix ICE in error recovery when checking struct compatibility [PR118061]

2025-03-17 Thread Joseph Myers
On Sun, 16 Mar 2025, Martin Uecker wrote:

> 
> Here is a small patch fixing an error recovery issue.
> 
> Bootstrapped and regression tested on x86_64.
> 
> 
> commit 465773af2bdd552184b935e5dc6b3db9e0e4e327
> Author: Martin Uecker 
> Date:   Sat Mar 1 17:21:25 2025 +0100
> 
> c: Fix ICE in error recovery when checking struct compatibility [PR118061]
> 
> Return early when comparing two structures for compatibility
> and the type of a member is erroneous.
> 
> PR c/118061
> 
> gcc/ChangeLog:
> * c/c-typeck.cc (tagged_types_tu_compatible_p): Handle
> errors in types of struct members.

This belongs in gcc/c/ChangeLog.  OK with that fix.

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



Re: [PATCH] c: Fix bug in typedef redefinitions of tagged types [PR118765]

2025-03-17 Thread Joseph Myers
On Sun, 16 Mar 2025, Martin Uecker wrote:

> This is a partial fix for PR118765.
> 
> 
> Bootstrapped and regression tested on x86_64.
> 
> 
> commit 84ba284a14bb5249d923affbf3f0f95a993c3a29
> Author: Martin Uecker 
> Date:   Sat Mar 1 21:32:21 2025 +0100
> 
> c: Fix bug in typedef redefinitions of tagged types [PR118765]
> 
> When we redefine a tagged type we incorrectly update TYPE_STUB_DECL
> of the previously defined type instead of the new one.  Because
> TYPE_STUB_DECL is used when determining whether two such types are
> the same, this can cause valid typedef redefinitions to be rejected
> later. This is only a partial fix for PR118765.
> 
> PR c/118765
> 
> gcc/ChangeLog:
> * c/c-decl.cc (finish_struct,finish_enum): Swap direction when
> copying TYPE_STRUB_DECL in redefinitions.

OK with this moved to gcc/c/ChangeLog.

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



Re: [PATCH] c: Fix tagname confusion for typedef redefinitions [PR118765]

2025-03-17 Thread Joseph Myers
On Sun, 16 Mar 2025, Martin Uecker wrote:

> This is a workaround for another issue related to PR118765.
> I do not yet understand what goes wrong in merge_decls in
> this case (somehow we end up with TYPE_DECLS where
> DECL_ORIGINAL_TYPE is not set correctly, so we can not
> determine the correct tag later), so I do not merge
> these TYPE_DECLS in this specific case as a workaround
> and add a "sorry" for the alignment case (or should this
> simply become an error?).

I'm not convinced a workaround for something not understood is a good idea 
here.

I think different alignment should be considered different types, so an 
error.

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



Re: [PATCH] Fortran: check type-spec in ALLOCATE of dummy with assumed length [PR119338]

2025-03-17 Thread Jerry D

On 3/17/25 2:47 PM, Harald Anlauf wrote:

Dear all,

F2003:C626 was only partly implemented: we missed the case of ALLOCATE
of character dummy arguments with assumed length, where the type-spec
must use asterisk, i.e. (*).

Regtesting found one testcase that had a previously undetected error
and needed adjustment, which I chose such that the original error
was kept.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald



Yes, OK and thanks for the fix.

Jerry


Re: [PATCH] gcc.dg/pr90838-2.c: Replace long with long long

2025-03-17 Thread Jakub Jelinek
On Mon, Mar 17, 2025 at 03:04:48PM -0700, H.J. Lu wrote:
> Since gcc.dg/pr90838-2.c is only for 64-bit integer, replace long with
> long long for ILP32 targets.
> 
>   * gcc.dg/pr90838-2.c (ctz4): Replace long with long long.
> 
> Signed-off-by: H.J. Lu 
> ---
>  gcc/testsuite/gcc.dg/pr90838-2.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/testsuite/gcc.dg/pr90838-2.c 
> b/gcc/testsuite/gcc.dg/pr90838-2.c
> index 83790694104..a38799866fa 100644
> --- a/gcc/testsuite/gcc.dg/pr90838-2.c
> +++ b/gcc/testsuite/gcc.dg/pr90838-2.c
> @@ -26,9 +26,9 @@ static const char table[128] = {
>  57, 58, 59, 60, 61, 62, 63, 64
>  };
>  
> -int ctz4 (unsigned long x)
> +int ctz4 (unsigned long long x)
>  {
> -  unsigned long lsb = x & -x;
> +  unsigned long long lsb = x & -x;
>return table[(lsb * magic) >> 58];
>  }
>  

Ok, thanks.

Jakub



[PATCH] gcc.dg/pr90838-2.c: Replace long with long long

2025-03-17 Thread H.J. Lu
Since gcc.dg/pr90838-2.c is only for 64-bit integer, replace long with
long long for ILP32 targets.

* gcc.dg/pr90838-2.c (ctz4): Replace long with long long.

Signed-off-by: H.J. Lu 
---
 gcc/testsuite/gcc.dg/pr90838-2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr90838-2.c b/gcc/testsuite/gcc.dg/pr90838-2.c
index 83790694104..a38799866fa 100644
--- a/gcc/testsuite/gcc.dg/pr90838-2.c
+++ b/gcc/testsuite/gcc.dg/pr90838-2.c
@@ -26,9 +26,9 @@ static const char table[128] = {
 57, 58, 59, 60, 61, 62, 63, 64
 };
 
-int ctz4 (unsigned long x)
+int ctz4 (unsigned long long x)
 {
-  unsigned long lsb = x & -x;
+  unsigned long long lsb = x & -x;
   return table[(lsb * magic) >> 58];
 }
 
-- 
2.48.1



[PATCH 1/4] rust: Use REAL_TYPE_P instead of manual checking

2025-03-17 Thread Andrew Pinski
This moves is_floating_point over to using REAL_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 REAL_TYPE_P
instead of manually checking the type.

Signed-off-by: Andrew Pinski 
---
 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 273ab7889b0..e877c034452 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1018,12 +1018,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 REAL_TYPE_P (TREE_TYPE (exp));
 }
 
 // Return an expression for the negation operation OP EXPR.
-- 
2.43.0



  1   2   3   4   >