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

2025-03-21 Thread Christophe Lyon
Depending on if/how the testing flags are overridden, the first value
we try("") might not do what we want.

For instance, if the whole testsuite is executed with
(A) -mthumb -march=armv7-m -mtune=cortex-m3 -mfloat-abi=softfp

bf16_neon_ok is first compiled with
(A) (B)
where B = -mcpu=unset -march=armv8.2-a+bf16

which is accepted, so a testcase like vld2q_lane_bf16_indices_1.c
is compiled with:
(A) (C) (B)
where C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a 
-mfpu=neon-fp16 -mfp16-format=ieee

because advsimd-intrinsics.exp has set additional_flags to (C)
via arm_neon_fp16_ok

So the testcase is compiled with
[...] -mfpu=neon-fp16 -mcpu=unset -march=armv8.2-a+bf16
(thus -mfpu=neon-fp16) and bf16 support is disabled.

The patch replaces "" with -mfpu=auto which matches the intended
effect of -march=armv8.2-a+bf16 as added by bf16_neon_ok, and the
testcase is now compiled with
(A) (C) -mfpu=auto (B)

However, since this effective-target is also used on aarch64 (which
does not support -mfpu=auto), we do this only on arm.

This patch improves coverage, and makes
v{ld,st}[234]q_lane_bf16_indices_1.c pass when testsuite flags are
overridden as described above (e.g. for M-profile).

gcc/testsuite/
* lib/target-supports.exp
(check_effective_target_arm_v8_2a_bf16_neon_ok_nocache):
Conditionally use -mfpu=auto.
---
 gcc/testsuite/lib/target-supports.exp | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index e2622a445c5..09b16a14024 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6871,12 +6871,19 @@ proc add_options_for_arm_fp16fml_neon { flags } {
 proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } {
 global et_arm_v8_2a_bf16_neon_flags
 set et_arm_v8_2a_bf16_neon_flags ""
+set fpu_auto ""
 
 if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
return 0;
 }
 
-foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" 
"-mfloat-abi=hard -mfpu=neon-fp-armv8" } {
+if { [istarget arm*-*-*] } {
+   set fpu_auto "-mfpu=auto"
+}
+
+foreach flags [list "$fpu_auto" \
+  "-mfloat-abi=softfp -mfpu=neon-fp-armv8" \
+  "-mfloat-abi=hard -mfpu=neon-fp-armv8" ] {
if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok object {
#include 
#if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
-- 
2.34.1



Re: [PATCH] cobol: Address some iconv issues.

2025-03-21 Thread Iain Sandoe



> On 21 Mar 2025, at 22:11, Robert Dubner  wrote:
> 

> So, please, stick with the default 1252 for existing code -- as you noted,
> changing the page breaks some tests.  

So … like so?

#if __APPLE__
“CP1252"
#else
"CP1252//"
#endif

(I’m not sure what the trailing ‘//‘ does on Linux  [it’s an error on the macOS 
iconf impl])

thanks
Iain



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

2025-03-21 Thread Richard Biener
On Thu, 20 Mar 2025, Jakub Jelinek wrote:

> On Thu, Mar 20, 2025 at 03:30:30PM -0500, Robert Dubner wrote:
> > Let me find one inky-dink example.  Talk amongst yourselves...here we go.
> > 
> > identification  division.
> > program-id. prog.
> > datadivision.
> > working-storage section.
> > 77 var8 PIC 999V9(8) COMP-5 .
> > 77 var555 PIC 999V COMP-5 VALUE 555..
> > procedure   division.
> > move 555. to var8
> > add 0.0001 TO var555 giving var8 rounded
> > if var8 not equal to 555.5556 display var8 " should be
> > 555.5556".
> > end program prog.
> > 
> > With your patches, the output is
> > 
> > 555. should be 555.5556
> 
> Thanks.
> Now, the code certainly could try to do the rounding of the last digits
> based on the remaining digits in the string that are being discarded,
> if followed by 0-4, don't change anything, if followed by 6-9, increase
> last digit, if followed by 5 and any non-zero digit, increase too, if followed
> by 5 and all zeros, round to even.
> But I'm afraid it can have double rounding, when round_to_decimal rounds
> for the precision 33 printing something e.g. with 4999 at
> the end to 5000 and this second rounding again.

I think this must go wrong at a different place than the previous output
thing given it's the

  if var8 not equal to 555.5556

test that misbehaves.  So it might be a similar issue at the input
side (I was not very careful when converting the string stuff, esp.
with regard to the precision specifiers in the format strings).

> So I really think we should go to mpfr, I can implement it tomorrow unless
> Richi wants to do that.

Go to mpfr for the string conversions?  Yeah, maybe that's a good
idea.

Richard.


[Patch] testsuite/lib/libgomp.exp: compile with -fdiagnostics-plain-output

2025-03-21 Thread Tobias Burnus

I tried to match in dg-warning the whole string, including [-OpenMP], but it 
failed.

I turned out that that was because of -fdiagnostics-urls ...

Solution do what other testsuites do: Use -fdiagnostics-plain-output.

Unless there are further comments, I intent to commit the attached patch later 
today.

Thanks,

Tobias
testsuite/lib/libgomp.exp: compile with -fdiagnostics-plain-output

libgomp.exp added -fno-diagnostics-show-caret and -fdiagnostics-color=never
as 'additional_flags' for compilation. However, it turned out that this now
is insufficient as the [...] part of diagnostics have a hyperlink URL.

Solution: Use the -fdiagnostics-plain-output flag instead, added in commit
r11-2701-g129a1319c0ab73. This flag currently implies the following flags:
   -fno-diagnostics-show-caret
   -fno-diagnostics-show-line-numbers
   -fdiagnostics-color=never
   -fdiagnostics-urls=never
   -fdiagnostics-path-format=separate-events
   -fdiagnostics-text-art-charset=none
   -fno-diagnostics-show-event-links

libgomp/ChangeLog:

	* testsuite/lib/libgomp.exp (libgomp_init): Add
	-fdiagnostics-plain-output to additional_flags; remove
	-fno-diagnostics-show-caret and -fdiagnostics-color=never.

diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp
index fd21371dce8..bc38e3ca6d9 100644
--- a/libgomp/testsuite/lib/libgomp.exp
+++ b/libgomp/testsuite/lib/libgomp.exp
@@ -233,11 +233,8 @@ proc libgomp_init { args } {
 # error-message parsing machinery.
 lappend ALWAYS_CFLAGS "additional_flags=-fmessage-length=0"
 
-# Disable caret
-lappend ALWAYS_CFLAGS "additional_flags=-fno-diagnostics-show-caret"
-
-# Disable color diagnostics
-lappend ALWAYS_CFLAGS "additional_flags=-fdiagnostics-color=never"
+# Disable caret, color, URL diagnostics
+lappend ALWAYS_CFLAGS "additional_flags=-fdiagnostics-plain-output"
 
 # Help GCC to find offload compilers' 'mkoffload'.
 global offload_additional_options


Re: [PATCH 3/3] libstdc++: Fix localized %c formatting for non-UTC times [PR117214]

2025-03-21 Thread Tomasz Kaminski
On Thu, Mar 20, 2025 at 10:39 AM Jonathan Wakely  wrote:

> The previous commit fixed most cases of %c formatting, but it
> incorrectly prints times using the system's local time zone. This only
> matters if the locale's %c format includes %Z, but some do.
>
> To print a correct value for %Z we can set tm.tm_zone to either "UTC" or
> the abbreviation passed to the formatter in the local-time-format-t
> structure.
>
> For local times with no info and for systems that don't support tm_zone
> (which is new in POSIX.1-2024) we just set tm_isdst = -1 so that no zone
> name is printed.
>
> In theory, a locale's %c format could use %z which should print a +hhmm
> offset from UTC. I'm unsure how to control that though. The new
> tm_gmtoff field in combination with tm_isdst != -1 seems like it should
> work, but using that without also setting tm_zone causes the system zone
> to be used for %Z again. That means local_time_format(lt, nullptr, &off)
> might work for a locale that uses %z but prints the wrong thing for %Z.
> This commit doesn't set tm_gmtoff even if _M_offset_sec is provided for
> a local-time-format-t value.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/117214
> * configure.ac: Use AC_STRUCT_TIMEZONE.
> * config.h.in: Regenerate.
> * configure: Regenerate.
> * include/bits/chrono_io.h (__formatter_chrono::_M_c): Set
> tm_isdst and tm_zone.
> * testsuite/std/time/format/pr117214.cc: Check %c formatting of
> zoned_time and local time.
> ---
>
> Tested x86_64-linux.
>
The c++ code parts LGTM, however the changes in config.h.in and
configure went over my head: they seem to check for new members,
but I cannot confirm if they are correct and according to best practices.

>
>  libstdc++-v3/config.h.in  |  18 ++
>  libstdc++-v3/configure| 179 +-
>  libstdc++-v3/configure.ac |   2 +
>  libstdc++-v3/include/bits/chrono_io.h |  32 +++-
>  .../testsuite/std/time/format/pr117214.cc |  65 +++
>  5 files changed, 287 insertions(+), 9 deletions(-)
>
> diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
> index 91e920044ee..be151f43dd6 100644
> --- a/libstdc++-v3/config.h.in
> +++ b/libstdc++-v3/config.h.in
> @@ -74,6 +74,10 @@
> don't. */
>  #undef HAVE_DECL_STRNLEN
>
> +/* Define to 1 if you have the declaration of `tzname', and to 0 if you
> don't.
> +   */
> +#undef HAVE_DECL_TZNAME
> +
>  /* Define to 1 if you have the  header file. */
>  #undef HAVE_DIRENT_H
>
> @@ -408,6 +412,9 @@
>  /* Define to 1 if `d_type' is a member of `struct dirent'. */
>  #undef HAVE_STRUCT_DIRENT_D_TYPE
>
> +/* Define to 1 if `tm_zone' is a member of `struct tm'. */
> +#undef HAVE_STRUCT_TM_TM_ZONE
> +
>  /* Define if strxfrm_l is available in . */
>  #undef HAVE_STRXFRM_L
>
> @@ -499,9 +506,17 @@
>  /* Define to 1 if the target supports thread-local storage. */
>  #undef HAVE_TLS
>
> +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
> +   `HAVE_STRUCT_TM_TM_ZONE' instead. */
> +#undef HAVE_TM_ZONE
> +
>  /* Define if truncate is available in . */
>  #undef HAVE_TRUNCATE
>
> +/* Define to 1 if you don't have `tm_zone' but do have the external array
> +   `tzname'. */
> +#undef HAVE_TZNAME
> +
>  /* Define to 1 if you have the  header file. */
>  #undef HAVE_UCHAR_H
>
> @@ -590,6 +605,9 @@
>  /* Define to 1 if you have the ANSI C header files. */
>  #undef STDC_HEADERS
>
> +/* Define to 1 if your  declares `struct tm'. */
> +#undef TM_IN_SYS_TIME
> +
>  /* Version number of package */
>  #undef VERSION
>
> diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
> index 78758285f21..67d2b8c7b72 100755
> --- a/libstdc++-v3/configure
> +++ b/libstdc++-v3/configure
> @@ -2731,6 +2731,63 @@ $as_echo "$ac_res" >&6; }
>eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
>
>  } # ac_fn_c_check_decl
> +
> +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
> +# 
> +# Tries to find if the field MEMBER exists in type AGGR, after including
> +# INCLUDES, setting cache variable VAR accordingly.
> +ac_fn_c_check_member ()
> +{
> +  as_lineno=${as_lineno-"$1"}
> as_lineno_stack=as_lineno_stack=$as_lineno_stack
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
> +$as_echo_n "checking for $2.$3... " >&6; }
> +if eval \${$4+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +$5
> +int
> +main ()
> +{
> +static $2 ac_aggr;
> +if (ac_aggr.$3)
> +return 0;
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINENO"; then :
> +  eval "$4=yes"
> +else
> +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +$5
> +int
> +main ()
> +{
> +static $2 ac_aggr;
> +if (sizeof ac_aggr.$3)
> +return 0;
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINE

Re: COBOL: Implementation of STOP RUN / GOBACK

2025-03-21 Thread Simon Sobisch




Am 21.03.2025 um 11:50 schrieb Jose E. Marchesi:



Am 20.03.2025 um 21:50 schrieb James K. Lowden:

On Mar 13, 2025, at 8:04 AM, Simon Sobisch  wrote:


exit() allows us to "pass to the operating system" directly; but it doesn't directly say 
"success" or "fail".


Obviously the statements
STOP RUN WITH NORMAL STATUS 41
and
STOP RUN ERROR 41

Should have a different result for the operating system.

Or, obviously not.
For OSes I'm familiar with, there is no *definition* of
success/failure.  There's just convention: 0 is success and nonzero
failure.  Even that is honored in the breach, see diff(1).
IMO unless the OS defines success/failure outside the value of the
exit status value (above, 41), the COBOL compiler cannot supply
meaning to STOP RUN NORMAL or ERROR.  It has no meaning in COBOL
because it has no meaning outside COBOL.
By that reasoning, the two statements above both return 41 because
there is no way to say more.  It is for the caller to decide what to
do.
I do not think -41 is an option; the compiler should not make
arbitrary changes to the user's data.
It is temping to raise(SIG_TERM) for error, but again the 41 is
lost.


STOP RUN WITH ERROR "Don't do that, Jon!"

When no numeric value is supplied, IMO:
  • STOP RUN WITH NORMAL STATUS becomes exit(EXIT_SUCCESS)
  • STOP RUN WITH ERROR becomes exit(EXIT_FAILURE)
That satisfies the Principle of Least Astonishment.  BTW those
values are defined by C, not POSIX.
--jkl



I agree that this could be a reasonable approach:
* STOP RUN WITH NORMAL STATUS becomes exit(EXIT_SUCCESS)
* STOP RUN WITH ERROR becomes exit(EXIT_FAILURE)
* Any text given goes to an internal DISPLAY (_possibly_ WITH ERROR
   doing a DISPLAY UPON SYSERR)

If I'd not now that "some heavy business applications" actually pass
the error using specific values (one for deadlock, another for general
db issues, one for logic issues, ...) I'd say "screw the numbers -
just DISPLAY them".


So:

   STOP RUN
   EXIT PROGRAM


That's not identical, EXIT PROGRAM just leaves the current module (if 
any, otherwise falls through),




   should:

   exit (EXIT_SUCCESS).


yes



Then:

   STOP RUN WITH NORMAL STATUS 

   should:

   fprintf (stderr, "STOPPED WITH NORMAL STATUS %d", number);
   exit (EXIT_SUCCESS);


no, applications already require the option to set that  as 
return code to the OS.




Then:

   STOP RUN WITH ERROR STATUS 

   should:

   fprintf (stderr, "STOPPED WITH ERROR STATUS %d", number);
   exit (EXIT_FAILURE);


same here - error code needed to OS.


Note that:

STOP RUN WITH ERROR

would be

   fprintf (stderr, "STOPPED WITH ERROR");
   exit (EXIT_FAILURE);


and additional both have an optional literal (instead of the number)

STOP RUN WITH ERROR "Bad boy"

STOP RUN WITH alphanumeric-variable
  *> possibly containing something like "order 999 was proceeded".


In this case we have exit (EXIT_SUCESS/EXIT_FAILURE) and

   fprintf (stderr, "STOPPED WITH ERROR %s", message);
   fprintf (stderr, "STOPPED NORMAL WITH MESSAGE %s", message);

or similar (and the stop message would likely be not all-caps and put 
under gettext, of course)


Simon


Re: [PATCH v2 2/2] PR119376: Disable clang musttail

2025-03-21 Thread Jason Merrill

On 3/20/25 12:28 PM, Jakub Jelinek wrote:

On Thu, Mar 20, 2025 at 09:19:02AM -0700, Andi Kleen wrote:

The inlining was just one of the issue, there are some related to
different semantics of escaped locals. gcc always errors out while
LLVM declares it undefined.

But maybe we can fix that one too.


I have 3 patches to be tested, the inline one, fnsplit one and ipa-icf one.
For the escaped locals, I guess we need to decide if [[clang::musttail]]
will be something different from [[gnu::musttail]] in GCC or not (and if
yes, what __attribute__((musttail)) will be).
The current difference in behavior is on
int foo (void);
void bar (int *);
int
baz (void)
{
   int a;
   bar (&a);
   [[clang::musttail]] return foo ();
}
Clang makes the attribute not just a request to tail call it or fail,
but also changes behavior and says if the code ever accesses a from the
above during foo () (which without the attribute is completely valid), then
it is UB.
So, clang can compile this into a tail call, while GCC takes the safer
approach and says it is invalid.  Users can of course adjust their code to
make it explicitly end lifetime before the tailcall, like with
int
qux (void)
{
   {
 int a;
 bar (&a);
   }
   [[clang::musttail]] return foo ();
}
and then gcc should tail call it too.


Yes, I guess Clang is effectively doing that implicitly.


Strangely, it there is a var with
non-trivial destructor which ends lifetime after the call, clang rejects it
like gcc:
struct S { S (); ~S (); int s; };
int
corge (void)
{
   S a;
   bar (&a.s);
   [[clang::musttail]] return foo ();
}


This doesn't seem so strange to me; the destructor call is sequenced 
after the call to foo, which is impossible if we turned foo into a 
tailcall.  This is a more visible side-effect than ending the storage 
duration of a.



Not sure I like this, but if others (e.g. Richi, Joseph, Jason) are ok with
it I can live with it.  But we'd need a good documentation, ideally some
some new warning about it (perhaps enabled in -Wextra) and testcase
coverage.
Looking around, clang warns for
int foo (int *);
int bar (int *x)
{
  *x = 42;
  int a = 0;
  [[clang::musttail]] return foo (&a);
}
by default (without -Wall/-Wextra) with
warning: address of stack memory associated with local variable 'a' passed to 
musttail function [-Wreturn-stack-address]


This could even be added to -Wreturn-local-addr.


Dunno if that warning is about other stuff or just that.
If just that, perhaps we'd need multiple levels for it, diagnose passing
those to musttail arguments by default and have in -Wextra stronger variant
that would diagnose even the
int baz (int *x)
{
  *x = 42;
  int a = 0;
  foo (&a);
  [[clang::musttail]] return foo (nullptr);
}
case, i.e. escaped variables that are still in scope.
That variant of the warning perhaps should suggest to users to end the
lifetime of those variables before the musttail call.


I agree that it would be good to warn about this case, perhaps even by 
default, but that it should be possible to disable this warning without 
also disabling the diagnostic about foo(&a).


Jason



[COMMITTED 001/146] gccrs: Fix bad recursive operator overload call

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

When we are typechecking the impl block for DerefMut for &mut T
the implementation follows the usual operator overload check
but this ended up just resolving directly to the Trait definition
which ends up being recursive which we usually handle. The issue
we had is that a dereference call can be for either the DEREF
or DEREF_MUT lang item here it was looking for a recurisve call
to the DEREF lang item but we were in the DEREF_MUT lang item
so this case was not accounted for.

Fixes #3032

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-reference.h: new get locus helper
* typecheck/rust-hir-trait-resolve.cc (AssociatedImplTrait::get_locus): 
implemention
* typecheck/rust-hir-type-check-expr.cc 
(TypeCheckExpr::resolve_operator_overload):
fix overload

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-reference.h |  2 +
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  6 ++
 .../typecheck/rust-hir-type-check-expr.cc | 21 +--
 gcc/testsuite/rust/compile/issue-3032-1.rs| 58 +++
 gcc/testsuite/rust/compile/issue-3032-2.rs| 49 
 gcc/testsuite/rust/compile/nr2/exclude|  4 +-
 6 files changed, 134 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3032-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3032-2.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h 
b/gcc/rust/typecheck/rust-hir-trait-reference.h
index bdfd9879111..41970335375 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -246,6 +246,8 @@ public:
 
   HIR::ImplBlock *get_impl_block ();
 
+  location_t get_locus () const;
+
   TyTy::BaseType *get_self ();
   const TyTy::BaseType *get_self () const;
 
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index ec331cf6e95..91842df85b2 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -669,6 +669,12 @@ AssociatedImplTrait::reset_associated_types ()
   trait->clear_associated_types ();
 }
 
+location_t
+AssociatedImplTrait::get_locus () const
+{
+  return impl->get_locus ();
+}
+
 Analysis::NodeMapping
 TraitItemReference::get_parent_trait_mappings () const
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index ba22eaff441..dfdf85a141d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1822,10 +1822,20 @@ TypeCheckExpr::resolve_operator_overload 
(LangItem::Kind lang_item_type,
   HIR::ImplBlock *parent = impl_item.first;
   HIR::Function *fn = impl_item.second;
 
-  if (parent->has_trait_ref ()
- && fn->get_function_name ().as_string ().compare (
-  associated_item_name)
-  == 0)
+  bool is_deref = lang_item_type == LangItem::Kind::DEREF
+ || lang_item_type == LangItem::Kind::DEREF_MUT;
+  bool is_deref_match = fn->get_function_name ().as_string ().compare (
+ LangItem::ToString (LangItem::Kind::DEREF))
+ == 0
+   || fn->get_function_name ().as_string ().compare (
+LangItem::ToString (LangItem::Kind::DEREF_MUT))
+== 0;
+
+  bool is_recursive_op
+   = fn->get_function_name ().as_string ().compare (associated_item_name)
+   == 0
+ || (is_deref && is_deref_match);
+  if (parent->has_trait_ref () && is_recursive_op)
{
  TraitReference *trait_reference
= TraitResolver::Lookup (*parent->get_trait_ref ().get ());
@@ -1842,7 +1852,8 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind 
lang_item_type,
 
  bool is_lang_item_impl
= trait_reference->get_mappings ().get_defid ()
- == respective_lang_item_id;
+   == respective_lang_item_id
+ || (is_deref && is_deref_match);
  bool self_is_lang_item_self
= fntype->get_self_type ()->is_equal (*adjusted_self);
  bool recursive_operator_overload
diff --git a/gcc/testsuite/rust/compile/issue-3032-1.rs 
b/gcc/testsuite/rust/compile/issue-3032-1.rs
new file mode 100644
index 000..e9eb02794ce
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3032-1.rs
@@ -0,0 +1,58 @@
+#![feature(negative_impls)]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "deref"]
+pub trait Deref {
+/// The resulting type after dereferencing.
+#[stable(feature = "rust1", since = "1.0.0")]
+// #[rustc_diagnostic_item = "deref_targe

[COMMITTED 009/146] gccrs: Fix name resolution 2.0 definition lookups in unsafe checker

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

gcc/rust/ChangeLog:

* checks/errors/rust-unsafe-checker.cc: Add includes.
(UnsafeChecker::visit): Use 2.0 version of resolver when name
resolution 2.0 is enabled.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 42 +--
 gcc/testsuite/rust/compile/nr2/exclude|  6 ---
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 4c8db3a554e..9ab18e2f656 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -23,6 +23,10 @@
 #include "rust-hir-item.h"
 #include "rust-attribute-values.h"
 #include "rust-system.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace HIR {
@@ -216,8 +220,23 @@ UnsafeChecker::visit (PathInExpression &path)
   NodeId ast_node_id = path.get_mappings ().get_nodeid ();
   NodeId ref_node_id;
 
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
-return;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto resolved = nr_ctx.lookup (ast_node_id);
+
+  if (!resolved.has_value ())
+   return;
+
+  ref_node_id = resolved.value ();
+}
+  else
+{
+  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+   return;
+}
 
   if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
 {
@@ -418,8 +437,23 @@ UnsafeChecker::visit (CallExpr &expr)
   // There are no unsafe types, and functions are defined in the name resolver.
   // If we can't find the name, then we're dealing with a type and should 
return
   // early.
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
-return;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto resolved = nr_ctx.lookup (ast_node_id);
+
+  if (!resolved.has_value ())
+   return;
+
+  ref_node_id = resolved.value ();
+}
+  else
+{
+  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+   return;
+}
 
   if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
 {
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 450fc254452..47d651b22bd 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -191,12 +191,6 @@ traits9.rs
 type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
-unsafe1.rs
-unsafe11.rs
-unsafe2.rs
-unsafe3.rs
-unsafe6.rs
-unsafe7.rs
 use_1.rs
 use_2.rs
 v0-mangle1.rs
-- 
2.45.2



[COMMITTED 015/146] gccrs: fix bad type inferencing on path's

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

This catch to inject inference variables into generic paths was a
catch all 'hack' that we needed before we handled generics correctly
as we do now.

Fixes #3009

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_segments): remove hack

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-path.cc |  8 ---
 gcc/testsuite/rust/compile/issue-3009.rs  | 24 +++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 3 files changed, 25 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3009.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index c6552099bed..231ddd604db 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -490,14 +490,6 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_node_id,
 }
 
   rust_assert (resolved_node_id != UNKNOWN_NODEID);
-  if (tyseg->needs_generic_substitutions () && !reciever_is_generic)
-{
-  location_t locus = segments.back ().get_locus ();
-  tyseg = SubstMapper::InferSubst (tyseg, locus);
-  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
-   return;
-}
-
   context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
 
   // name scope first
diff --git a/gcc/testsuite/rust/compile/issue-3009.rs 
b/gcc/testsuite/rust/compile/issue-3009.rs
new file mode 100644
index 000..2eb4ef39abd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3009.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+trait Sized {}
+
+struct Foo {
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+t: u64,
+}
+
+impl Foo {
+fn of() -> Foo {
+// { dg-warning "associated function is never used" "" { target *-*-* 
} .-1 }
+Foo { t: 14 }
+}
+}
+
+trait Bar {
+fn bar() -> Foo;
+}
+
+impl Bar for T {
+fn bar() -> Foo {
+Foo::of::()
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index ceada8bc51a..4ba27d31f88 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -221,4 +221,5 @@ issue-3032-2.rs
 if_let_expr_simple.rs
 iflet.rs
 issue-3033.rs
+issue-3009.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 006/146] gccrs: Use name resolution 2.0 in TraitItemReference

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

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check.cc: Add includes.
(TraitItemReference::get_type_from_fn): Use
ForeverStack::to_canonical_path when name resolution 2.0 is
enabled.

Signed-off-by: Owen Avery 
---
 gcc/rust/typecheck/rust-hir-type-check.cc | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc 
b/gcc/rust/typecheck/rust-hir-type-check.cc
index 45cb75d87fe..51ab87d14b8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -23,6 +23,10 @@
 #include "rust-hir-type-check-item.h"
 #include "rust-hir-type-check-pattern.h"
 #include "rust-hir-type-check-struct-field.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 extern bool
 saw_errors (void);
@@ -299,8 +303,23 @@ TraitItemReference::get_type_from_fn (/*const*/ 
HIR::TraitItemFunc &fn) const
 }
 
   auto &mappings = Analysis::Mappings::get ();
-  auto canonical_path
-= mappings.lookup_canonical_path (fn.get_mappings ().get_nodeid ());
+
+  tl::optional canonical_path;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.values.to_canonical_path (fn.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path
+   = mappings.lookup_canonical_path (fn.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path);
 
   RustIdent ident{*canonical_path, fn.get_locus ()};
   auto resolved = new TyTy::FnType (
-- 
2.45.2



[COMMITTED 008/146] gccrs: Improve path handling while testing name resolution 2.0

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

gcc/testsuite/ChangeLog:

* rust/compile/nr2/compile.exp: Handle paths using "file join"
and "file split".
* rust/compile/nr2/exclude: Remove debug-diagnostics-on.rs.

Signed-off-by: Owen Avery 
---
 gcc/testsuite/rust/compile/nr2/compile.exp | 18 +-
 gcc/testsuite/rust/compile/nr2/exclude |  5 -
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp 
b/gcc/testsuite/rust/compile/nr2/compile.exp
index 0afe36c3c40..f2724f6c454 100644
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ b/gcc/testsuite/rust/compile/nr2/compile.exp
@@ -44,23 +44,23 @@ namespace eval rust-nr2-ns {
 # Run tests in directories
 # Manually specifying these, in case some other test file
 # does something weird
-set test_dirs {. compile macros/builtin macros/mbe macros/proc}
+set test_dirs {{} {macros builtin} {macros mbe} {macros proc}}
 
 set tests_expect_ok ""
 set tests_expect_err ""
 
 foreach test_dir $test_dirs {
-foreach test [lsort [glob -nocomplain -tails -directory 
$srcdir/$subdir/../$test_dir *.rs]] {
-   if {$test_dir == "."} {
-   set test_lbl $test
-   } else {
-   set test_lbl "$test_dir/$test"
-}
+set directory [list {*}[file split $srcdir] {*}[file split $subdir]]
+   set directory [lreplace $directory end end]
+   set directory [list {*}$directory {*}$test_dir]
+foreach test [lsort [glob -nocomplain -tails -directory [file join 
{*}$directory] *.rs]] {
+   # use '/' as the path seperator for entries in the exclude file
+   set test_lbl [join [list {*}$test_dir $test] "/"]
set idx [lsearch -exact -sorted $exclude $test_lbl]
if {$idx == -1} {
-   lappend tests_expect_ok $srcdir/$subdir/../$test_dir/$test
+   lappend tests_expect_ok [file join {*}$directory $test]
} else {
-   lappend tests_expect_err $srcdir/$subdir/../$test_dir/$test
+   lappend tests_expect_err [file join {*}$directory $test]
set exclude [lreplace $exclude $idx $idx]
}
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 57bcca0a60e..450fc254452 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,8 +1,3 @@
-# relies on exact source file path match
-# TODO: patch this file or nr2/compile.exp to handle this
-debug-diagnostics-on.rs
-
-# main list
 attr-mismatch-crate-name.rs
 attr_deprecated.rs
 attr_deprecated_2.rs
-- 
2.45.2



[COMMITTED 011/146] gccrs: Use name resolution 2.0 in TraitResolver

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

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc: Add includes.
(TraitResolver::resolve_path_to_trait):
Use name resolution 2.0 resolver when enabled.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 24 ++--
 gcc/testsuite/rust/compile/nr2/exclude   |  2 --
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 91842df85b2..3d99794f3d6 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -20,6 +20,10 @@
 #include "rust-hir-type-check-expr.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// used for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace Resolver {
@@ -110,8 +114,24 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath 
&path,
  HIR::Trait **resolved) const
 {
   NodeId ref;
-  if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
-  &ref))
+  bool ok;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto ref_opt = nr_ctx.lookup (path.get_mappings ().get_nodeid ());
+
+  if ((ok = ref_opt.has_value ()))
+   ref = *ref_opt;
+}
+  else
+{
+  ok = resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
+  &ref);
+}
+
+  if (!ok)
 {
   rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
   return false;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 424ad686094..f4304dae1d8 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -65,7 +65,6 @@ issue-1272.rs
 issue-1289.rs
 issue-1447.rs
 issue-1483.rs
-issue-1589.rs
 issue-1725-1.rs
 issue-1725-2.rs
 issue-1786.rs
@@ -175,7 +174,6 @@ sizeof-stray-infer-var-bug.rs
 specify-crate-name.rs
 stmt_with_block_dot.rs
 struct-expr-parse.rs
-trait-cycle.rs
 traits1.rs
 traits10.rs
 traits11.rs
-- 
2.45.2



[COMMITTED 021/146] gccrs: Reorganize the CPU feature detection

2025-03-21 Thread arthur . cohen
From: Antoni Boucher 

Move the code from i386-rust.cc to i386-rust-and-jit.inc so that it can
be reused by libgccjit.

gcc/ChangeLog:

* config/i386/i386-rust-and-jit.inc: New file.
* config/i386/i386-rust.cc: Move code to i386-rust-and-jit.inc.
---
 gcc/config/i386/i386-rust-and-jit.inc | 93 ++
 gcc/config/i386/i386-rust.cc  | 96 +--
 2 files changed, 96 insertions(+), 93 deletions(-)
 create mode 100644 gcc/config/i386/i386-rust-and-jit.inc

diff --git a/gcc/config/i386/i386-rust-and-jit.inc 
b/gcc/config/i386/i386-rust-and-jit.inc
new file mode 100644
index 000..998f44cfa3f
--- /dev/null
+++ b/gcc/config/i386/i386-rust-and-jit.inc
@@ -0,0 +1,93 @@
+if (TARGET_64BIT)
+  ADD_TARGET_INFO ("target_arch", "x86_64");
+else
+  ADD_TARGET_INFO ("target_arch", "x86");
+
+// features officially "stabilised" in rustc
+if (TARGET_MMX)
+  ADD_TARGET_INFO ("target_feature", "mmx");
+if (TARGET_SSE)
+  ADD_TARGET_INFO ("target_feature", "sse");
+if (TARGET_SSE2)
+  ADD_TARGET_INFO ("target_feature", "sse2");
+if (TARGET_SSE3)
+  ADD_TARGET_INFO ("target_feature", "sse3");
+if (TARGET_SSSE3)
+  ADD_TARGET_INFO ("target_feature", "ssse3");
+if (TARGET_SSE4_1)
+  ADD_TARGET_INFO ("target_feature", "sse4.1");
+if (TARGET_SSE4_2)
+  ADD_TARGET_INFO ("target_feature", "sse4.2");
+if (TARGET_AES)
+  ADD_TARGET_INFO ("target_feature", "aes");
+if (TARGET_SHA)
+  ADD_TARGET_INFO ("target_feature", "sha");
+if (TARGET_AVX)
+  ADD_TARGET_INFO ("target_feature", "avx");
+if (TARGET_AVX2)
+  ADD_TARGET_INFO ("target_feature", "avx2");
+if (TARGET_AVX512F)
+  ADD_TARGET_INFO ("target_feature", "avx512f");
+if (TARGET_AVX512CD)
+  ADD_TARGET_INFO ("target_feature", "avx512cd");
+if (TARGET_AVX512DQ)
+  ADD_TARGET_INFO ("target_feature", "avx512dq");
+if (TARGET_AVX512BW)
+  ADD_TARGET_INFO ("target_feature", "avx512bw");
+if (TARGET_AVX512VL)
+  ADD_TARGET_INFO ("target_feature", "avx512vl");
+if (TARGET_AVX512VBMI)
+  ADD_TARGET_INFO ("target_feature", "avx512vbmi");
+if (TARGET_AVX512IFMA)
+  ADD_TARGET_INFO ("target_feature", "avx512ifma");
+if (TARGET_AVX512VPOPCNTDQ)
+  ADD_TARGET_INFO ("target_feature", "avx512vpopcntdq");
+if (TARGET_FMA)
+  ADD_TARGET_INFO ("target_feature", "fma");
+if (TARGET_RTM)
+  ADD_TARGET_INFO ("target_feature", "rtm");
+if (TARGET_SSE4A)
+  ADD_TARGET_INFO ("target_feature", "sse4a");
+if (TARGET_BMI)
+  {
+ADD_TARGET_INFO ("target_feature", "bmi1");
+ADD_TARGET_INFO ("target_feature", "bmi");
+  }
+if (TARGET_BMI2)
+  ADD_TARGET_INFO ("target_feature", "bmi2");
+if (TARGET_LZCNT)
+  ADD_TARGET_INFO ("target_feature", "lzcnt");
+if (TARGET_TBM)
+  ADD_TARGET_INFO ("target_feature", "tbm");
+if (TARGET_POPCNT)
+  ADD_TARGET_INFO ("target_feature", "popcnt");
+if (TARGET_RDRND)
+  {
+ADD_TARGET_INFO ("target_feature", "rdrand");
+ADD_TARGET_INFO ("target_feature", "rdrnd");
+  }
+if (TARGET_F16C)
+  ADD_TARGET_INFO ("target_feature", "f16c");
+if (TARGET_RDSEED)
+  ADD_TARGET_INFO ("target_feature", "rdseed");
+if (TARGET_ADX)
+  ADD_TARGET_INFO ("target_feature", "adx");
+if (TARGET_FXSR)
+  ADD_TARGET_INFO ("target_feature", "fxsr");
+if (TARGET_XSAVE)
+  ADD_TARGET_INFO ("target_feature", "xsave");
+if (TARGET_XSAVEOPT)
+  ADD_TARGET_INFO ("target_feature", "xsaveopt");
+if (TARGET_XSAVEC)
+  ADD_TARGET_INFO ("target_feature", "xsavec");
+if (TARGET_XSAVES)
+  ADD_TARGET_INFO ("target_feature", "xsaves");
+if (TARGET_VPCLMULQDQ)
+  {
+ADD_TARGET_INFO ("target_feature", "pclmulqdq");
+ADD_TARGET_INFO ("target_feature", "vpclmulqdq");
+  }
+if (TARGET_CMPXCHG16B)
+  ADD_TARGET_INFO ("target_feature", "cmpxchg16b");
+if (TARGET_MOVBE)
+  ADD_TARGET_INFO ("target_feature", "movbe");
diff --git a/gcc/config/i386/i386-rust.cc b/gcc/config/i386/i386-rust.cc
index b9099d3dfaf..de00076bff5 100644
--- a/gcc/config/i386/i386-rust.cc
+++ b/gcc/config/i386/i386-rust.cc
@@ -29,97 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 void
 ix86_rust_target_cpu_info (void)
 {
-  if (TARGET_64BIT)
-rust_add_target_info ("target_arch", "x86_64");
-  else
-rust_add_target_info ("target_arch", "x86");
-
-  // features officially "stabilised" in rustc
-  if (TARGET_MMX)
-rust_add_target_info ("target_feature", "mmx");
-  if (TARGET_SSE)
-rust_add_target_info ("target_feature", "sse");
-  if (TARGET_SSE2)
-rust_add_target_info ("target_feature", "sse2");
-  if (TARGET_SSE3)
-rust_add_target_info ("target_feature", "sse3");
-  if (TARGET_SSSE3)
-rust_add_target_info ("target_feature", "ssse3");
-  if (TARGET_SSE4_1)
-rust_add_target_info ("target_feature", "sse4.1");
-  if (TARGET_SSE4_2)
-rust_add_target_info ("target_feature", "sse4.2");
-  if (TARGET_AES)
-rust_add_target_info ("target_feature", "aes");
-  if (TARGET_SHA)
-rust_add_target_info ("target_feature", "sha");
-  if (TARGET_AVX)
-rust_add_target_info ("target_feature", "avx");
-  if (TARGET_AVX2)
-   

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

2025-03-21 Thread Richard Biener
On Thu, 20 Mar 2025, Robert Dubner wrote:

> Okay, I managed to figure out a way of getting the debug information back
> into the libgcobol.
> 
> The addition is done by the routine __gg__add_fixed_phase1()
> 
> The run-tiome inputs to that routine should be 1 and 555.
> 
> What's coming through in the patched code are 1 and 554
> 
> I haven't looked at the compile-time code yet.  But I have a nickel that
> says somebody is converting "555." to floating-point, and getting
> an internal value of 555.5554999, and that's getting truncated
> to the internal value of 554
>
> I haven't checked for sure, but I suppose I've been counting on the
> strfromf128 routines to round sensibly.  I guess if mpfr can handle that
> kind of thing, then we should switch to mpfr.  I am not that familiar with
> mpfr.

Note I have not consistently used real_value_truncate to the target
float128 format - I was debating on whether ->value should be
aribitrary precision or not.  Some real_* functions can take VOIDmode
(no format, whatever that does exactly), but to build a 'tree' we
have to use a type (and I've not consistently performed rounding
or truncation to the format there).

Now a question on COBOL:

77 var8 PIC 999V9(8) COMP-5

what precision/digits does this specify?  When then doing

 add 0.0001 TO var555 giving var8 rounded

what's the precision/digit specification for the literal floating
point values and how does that or that of var555 or var8
"promote" or "demote" to a common specification for the arithmetic
operation?

Does the COBOL standard expect a literal floating point value to
be represented exactly?  Maybe rounding then only applies at the
"giving var8 rounded" point, forcing the exact value to the
specification of var8?

Richard.

> > -Original Message-
> > From: Robert Dubner 
> > Sent: Thursday, March 20, 2025 17:50
> > To: Jakub Jelinek 
> > Cc: Richard Biener ; gcc-patches@gcc.gnu.org
> > Subject: RE: [PATCH][RFC] [cobol] change cbl_field_data_t::etc_t::value
> > from _Float128 to tree
> > 
> > It's time to slow down a bit and give me a chance to catch up.
> > 
> > First, all those tests are not arbitrary.  I was getting the correct
> > answers before, and it was not an insignificant effort to get them
> correct
> > in the first place.
> > 
> > If we don't get the same answers, then something isn't the same as it
> was
> > before.
> > 
> > I need to know what.
> > 
> > First-prime:
> > 
> > Also, keep in mind that this is COBOL, where words don't mean what you
> > think they mean.  Under Rounding, we have
> > 
> > The following forms of rounding are provided (examples presume an
> integer
> > destination):
> > 
> > -AWAY-FROM-ZERO: Rounding is to the nearest value farther from zero.
> > 
> > -NEAREST-AWAY-FROM-ZERO: Rounding is to the nearest value. If two values
> > are equally near, the value farther from zero is selected. This mode has
> > historically been associated with the ROUNDED clause in earlier versions
> > of standard COBOL.
> > 
> > -NEAREST-EVEN: Rounding is to the nearest value. If two values are
> equally
> > near, the value whose rightmost digit is even is selected. This mode is
> > sometimes called "Banker's rounding".
> > 
> > -NEAREST-TOWARD-ZERO: Rounding is to the nearest value. If two values
> are
> > equally near, the value nearer to zero is selected.
> > 
> > -PROHIBITED: No rounding is performed. If the value cannot be
> represented
> > exactly in the desired format, the EC-SIZE-TRUNCATION condition is set
> to
> > exist and the results of the operation are undefined.
> > 
> > -TOWARD-GREATER: Rounding is toward the nearest value whose algebraic
> > value is larger.
> > 
> > -TOWARD-LESSER: Rounding is toward the nearest value whose algebraic
> value
> > is smaller.
> > 
> > -TRUNCATION: Rounding is to the nearest value that is nearer to zero
> than
> > the algebraic value. This mode has historically been associated with the
> > absence of the ROUNDED clause as well as for the formation of
> intermediate
> > results in the prior COBOL standard.
> > 
> > Any of those can be set as the default.
> > 
> > Second, I just tried to debug the way I have been debugging for years --
> > and I can't.
> > 
> > I wanted to check that the attempt to add 0.0001 to 555. was
> > actually adding those two numbers.  This wasn't a rounding problem.
> Both
> > of those numbers have eight decimal places.  So, internally, 1 is
> supposed
> > to be added to a 64-bit integer value 555 to get 556
> > 
> > I am suspicious that the 0.0001 is becoming zero, which would result
> > in the 555. being unchanged.
> > 
> > To do an initial check of this, I tried to trap at
> __gg__add_fixed_phase1
> > 
> > But libgcobol.so has no debug info.  So, somehow, the way I used to
> cause
> > it to be "-ggdb -O0" has gotten lost.  I need it back.
> > 
> > What I have been doing, lo these many months, is compiling after d

[COMMITTED 116/146] gccrs: Fix scan-gimple testcases on LE platforms.

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

gcc/testsuite/ChangeLog:

* rust/compile/macros/builtin/eager1.rs: Switch to scan-assembler 
directive as the
GIMPLE dump does not contain strings on LE.
* rust/compile/macros/builtin/recurse2.rs: Likewise.
---
 .../rust/compile/macros/builtin/eager1.rs |  2 +-
 .../rust/compile/macros/builtin/recurse2.rs   | 26 +--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs 
b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
index 65a80fda62e..7c6f6f95d61 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
@@ -15,7 +15,7 @@ macro_rules! b {
 }
 
 fn main() {
-// { dg-final { scan-tree-dump-times {"test1canary"} 1 gimple } }
+// { dg-final { scan-assembler {"test1canary"} } }
 let _ = concat!(a!(), 1, b!());
 // should not error
 concat!(a!(), true, b!(),);
diff --git a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs 
b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
index 2e73ab54fb6..73e6ab4aa6c 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
@@ -15,7 +15,29 @@ macro_rules! a {
 };
 }
 
+extern "C" {
+fn printf(fmt: *const i8, ...);
+}
+
+fn print_ptr(s: &str) {
+unsafe {
+printf("%p\n\0" as *const str as *const i8, s as *const str);
+}
+}
+
+fn print_str(s: &str) {
+unsafe {
+printf(
+"%s\n\0" as *const str as *const i8,
+s as *const str as *const i8,
+);
+}
+}
+
+// { dg-final { scan-assembler {"abheyho"} } }
+static S: &str = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+
 fn main() {
-// { dg-final { scan-tree-dump-times {"abheyho"} 1 gimple } }
-let _ = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+print_ptr(S);
+print_str(S);
 }
-- 
2.45.2



[COMMITTED 088/146] gccrs: ast: Add new constructors for PathInExpression

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

This commit adds two new constructors for AST::PathInExpression: One using a 
provided lang-item, and one with an already built std::unique_ptr

gcc/rust/ChangeLog:

* ast/rust-path.h: Add two new constructors.
---
 gcc/rust/ast/rust-path.h | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 563ad52a9d6..39d42fd7e15 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -715,6 +715,24 @@ public:
   marked_for_strip (false)
   {}
 
+  PathInExpression (LangItem::Kind lang_item_kind,
+   std::vector outer_attrs, location_t locus)
+: outer_attrs (std::move (outer_attrs)),
+  has_opening_scope_resolution (false), locus (locus),
+  _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  path (Rust::make_unique (lang_item_kind, locus)),
+  marked_for_strip (false)
+  {}
+
+  PathInExpression (std::unique_ptr path,
+   std::vector outer_attrs, location_t locus,
+   bool has_opening_scope_resolution = false)
+: outer_attrs (std::move (outer_attrs)),
+  has_opening_scope_resolution (has_opening_scope_resolution),
+  locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  path (std::move (path)), marked_for_strip (false)
+  {}
+
   PathInExpression (const PathInExpression &other)
 : outer_attrs (other.outer_attrs),
   has_opening_scope_resolution (other.has_opening_scope_resolution),
@@ -738,7 +756,8 @@ public:
   // Creates an error state path in expression.
   static PathInExpression create_error ()
   {
-return PathInExpression ({}, {}, UNDEF_LOCATION);
+return PathInExpression (std::vector (), {},
+UNDEF_LOCATION);
   }
 
   // Returns whether path in expression is in an error state.
-- 
2.45.2



[COMMITTED 080/146] gccrs: add ptr to int and int to ptr type cast rules

2025-03-21 Thread arthur . cohen
From: Nobel 

Added rules to allow type casting pointer as integer types (u*,i*)
and integer types to be casted as pointer.

gcc/rust/ChangeLog:

* typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Nobel Singh 
---
 gcc/rust/typecheck/rust-casts.cc   | 27 --
 gcc/testsuite/rust/compile/ptr_int_cast.rs | 18 +++
 2 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/ptr_int_cast.rs

diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index cf4de4b3320..694cbaa5db6 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -210,6 +210,16 @@ TypeCastRules::cast_rules ()
  }
  break;
 
+ case TyTy::TypeKind::POINTER: {
+   // char can't be casted as a ptr
+   bool from_char
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
+   if (!from_char)
+ return TypeCoercionRules::CoercionResult{{},
+  to.get_ty ()->clone ()};
+ }
+ break;
+
case TyTy::TypeKind::INFER:
case TyTy::TypeKind::USIZE:
case TyTy::TypeKind::ISIZE:
@@ -254,12 +264,25 @@ TypeCastRules::cast_rules ()
 case TyTy::TypeKind::POINTER:
   switch (to.get_ty ()->get_kind ())
{
+   case TyTy::TypeKind::USIZE:
+   case TyTy::TypeKind::ISIZE:
+   case TyTy::TypeKind::UINT:
+ case TyTy::TypeKind::INT: {
+   // refs should not cast to numeric type
+   bool from_ptr
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
+   if (from_ptr)
+ {
+   return TypeCoercionRules::CoercionResult{
+ {}, to.get_ty ()->clone ()};
+ }
+ }
+ break;
+
case TyTy::TypeKind::REF:
case TyTy::TypeKind::POINTER:
  return check_ptr_ptr_cast ();
 
- // FIXME can you cast a pointer to a integral type?
-
default:
  return TypeCoercionRules::CoercionResult::get_error ();
}
diff --git a/gcc/testsuite/rust/compile/ptr_int_cast.rs 
b/gcc/testsuite/rust/compile/ptr_int_cast.rs
new file mode 100644
index 000..3a2a5d563d6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/ptr_int_cast.rs
@@ -0,0 +1,18 @@
+fn main(){
+let foo = 1337;
+let bar_ptr = &foo as *const i32;
+
+let bar_ptr_usize = bar_ptr as usize;
+let bar_ptr_isize = bar_ptr as isize;
+let bar_ptr_u64 = bar_ptr as u64;
+let bar_ptr_i64 = bar_ptr as i64;
+let bar_ptr_i8 = bar_ptr as i8;
+let bar_ptr_u8 = bar_ptr as u8;
+
+let _ = bar_ptr_usize as *const i32;
+let _ = bar_ptr_isize as *const i32;
+let _ = bar_ptr_u64 as *const i32;
+let _ = bar_ptr_i64 as *const i32;
+let _ = bar_ptr_i8 as *const i32;
+let _ = bar_ptr_u8 as *const i32;
+}
-- 
2.45.2



[COMMITTED 059/146] gccrs: ast: Use StackedContexts class in ContextualASTVisitor

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

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.h: Replace context with StackedContexts.
* ast/rust-ast-visitor.cc (ContextualASTVisitor::visit): Use new APIs.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit): Likewise.
---
 gcc/rust/ast/rust-ast-visitor.cc  | 16 +++
 gcc/rust/ast/rust-ast-visitor.h   | 10 --
 gcc/rust/checks/errors/rust-ast-validation.cc | 20 ---
 3 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 8f53e528131..a390aa20bcb 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1453,33 +1453,33 @@ DefaultASTVisitor::visit (AST::VariadicParam ¶m)
 void
 ContextualASTVisitor::visit (AST::Crate &crate)
 {
-  push_context (Context::CRATE);
+  ctx.enter (Kind::CRATE);
   DefaultASTVisitor::visit (crate);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::InherentImpl &impl)
 {
-  push_context (Context::INHERENT_IMPL);
+  ctx.enter (Kind::INHERENT_IMPL);
   DefaultASTVisitor::visit (impl);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::TraitImpl &impl)
 {
-  push_context (Context::TRAIT_IMPL);
+  ctx.enter (Kind::TRAIT_IMPL);
   DefaultASTVisitor::visit (impl);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::Trait &trait)
 {
-  push_context (Context::TRAIT);
+  ctx.enter (Kind::TRAIT);
   DefaultASTVisitor::visit (trait);
-  pop_context ();
+  ctx.exit ();
 }
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 50b93016d62..7e3423cd493 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -26,6 +26,7 @@
 #include "rust-item.h"
 #include "rust-path.h"
 #include "rust-system.h"
+#include "rust-stacked-contexts.h"
 
 namespace Rust {
 namespace AST {
@@ -452,7 +453,7 @@ public:
 class ContextualASTVisitor : public DefaultASTVisitor
 {
 protected:
-  enum class Context
+  enum class Kind
   {
 FUNCTION,
 INHERENT_IMPL,
@@ -461,6 +462,7 @@ protected:
 MODULE,
 CRATE,
   };
+
   using DefaultASTVisitor::visit;
 
   virtual void visit (AST::Crate &crate) override;
@@ -476,11 +478,7 @@ protected:
 DefaultASTVisitor::visit (item);
   }
 
-  std::vector context;
-
-  void push_context (Context ctx) { context.push_back (ctx); }
-
-  void pop_context () { context.pop_back (); }
+  StackedContexts ctx;
 };
 
 } // namespace AST
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index 7938286ffb5..59b28057bab 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -56,7 +56,7 @@ ASTValidation::visit (AST::LoopLabel &label)
 void
 ASTValidation::visit (AST::ConstantItem &const_item)
 {
-  if (!const_item.has_expr () && context.back () != Context::TRAIT_IMPL)
+  if (!const_item.has_expr () && ctx.peek () != Kind::TRAIT_IMPL)
 {
   rust_error_at (const_item.get_locus (),
 "associated constant in % without body");
@@ -82,23 +82,19 @@ ASTValidation::visit (AST::Function &function)
   "functions cannot be both % and %");
 
   if (qualifiers.is_const ()
-  && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+  && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
 rust_error_at (function.get_locus (), ErrorCode::E0379,
   "functions in traits cannot be declared %");
 
   // may change soon
   if (qualifiers.is_async ()
-  && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+  && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
 rust_error_at (function.get_locus (), ErrorCode::E0706,
   "functions in traits cannot be declared %");
 
   // if not an associated function but has a self parameter
-  if (context.back () != Context::TRAIT
-  && context.back () != Context::TRAIT_IMPL
-  && context.back () != Context::INHERENT_IMPL
-  && function.has_self_param ())
+  if (ctx.peek () != Kind::TRAIT && ctx.peek () != Kind::TRAIT_IMPL
+  && ctx.peek () != Kind::INHERENT_IMPL && function.has_self_param ())
 rust_error_at (
   function.get_self_param ().get_locus (),
   "% parameter is only allowed in associated functions");
@@ -140,11 +136,11 @@ ASTValidation::visit (AST::Function &function)
 {
   if (!function.has_body ())
{
- if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+ if (ctx.peek () == Kind::INHERENT_IMPL
+ || ctx.peek () == Kind::TRAIT_IMPL)
rust_error_at (function.get_locus (),
   "associated function in % w

[COMMITTED 083/146] gccrs: resolve: Name resolve trait bounds properly

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

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): 
Resolve additional
trait bounds.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Error out 
properly on unresolved
type-path instead of crashing.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Exclude additional-trait-bounds2 for 
different error message.
* rust/compile/additional-trait-bounds1.rs: New test.
* rust/compile/additional-trait-bounds2.rs: New test.
* rust/compile/additional-trait-bounds2nr2.rs: New test.
---
 gcc/rust/resolve/rust-ast-resolve-type.cc | 57 ++-
 .../resolve/rust-late-name-resolver-2.0.cc|  3 +-
 .../rust/compile/additional-trait-bounds1.rs  | 10 
 .../rust/compile/additional-trait-bounds2.rs  |  9 +++
 .../compile/additional-trait-bounds2nr2.rs| 11 
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 6 files changed, 87 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds1.rs
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds2.rs
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index ec5e8a762a7..cb5a18d5d47 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -18,6 +18,8 @@
 
 #include "rust-ast-resolve-type.h"
 #include "rust-ast-resolve-expr.h"
+#include "rust-canonical-path.h"
+#include "rust-type.h"
 
 namespace Rust {
 namespace Resolver {
@@ -495,10 +497,59 @@ ResolveTypeToCanonicalPath::visit 
(AST::TraitObjectTypeOneBound &type)
 }
 
 void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
 {
-  // FIXME is this actually allowed? dyn A+B
-  rust_unreachable ();
+  rust_assert (!type.get_type_param_bounds ().empty ());
+
+  auto &first_bound = type.get_type_param_bounds ().front ();
+
+  // Is it allowed or even possible to have a lifetime bound as a first bound?
+  if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME)
+rust_unreachable ();
+
+  auto &trait = static_cast (*first_bound);
+
+  CanonicalPath path = CanonicalPath::create_empty ();
+  bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
+
+  // right?
+  rust_assert (ok);
+
+  auto slice_path = "get_bound_type ())
+   {
+ case AST::TypeParamBound::TRAIT: {
+   auto bound_path = CanonicalPath::create_empty ();
+
+   auto &bound_type_path
+ = static_cast (*additional_bound)
+ .get_type_path ();
+   bool ok
+ = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path);
+
+   if (!ok)
+ continue;
+
+   str = bound_path.get ();
+   break;
+ }
+   case AST::TypeParamBound::LIFETIME:
+ rust_unreachable ();
+ break;
+   }
+  slice_path += " + " + str;
+}
+
+  slice_path += ">";
+
+  result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
 }
 
 void
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index ac5f1c57546..40f067319b5 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -282,7 +282,8 @@ Late::visit (AST::TypePath &type)
 ctx.map_usage (Usage (type.get_node_id ()),
   Definition (resolved->get_node_id ()));
   else
-rust_unreachable ();
+rust_error_at (type.get_locus (), "could not resolve type path %qs",
+  str.c_str ());
 
   DefaultResolver::visit (type);
 }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds1.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
new file mode 100644
index 000..449a72fe461
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
@@ -0,0 +1,10 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send {}
+impl dyn A + Send + Sync {}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
new file mode 100644
index 000..843228ae9a6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
@@ -0,0 +1,9 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "failed to resolve 
TypePath: NonExist in this scope" }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
new file mode 100644
index 000..6764f6e8012
--- /de

[COMMITTED 119/146] gccrs: nr2.0: Early resolve pending eager macro invocations

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

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc
(Early::visit): Resolve the pending eager invocations inside
builtin macro invocations.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 55330487fd7..342f1027273 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -238,6 +238,10 @@ Early::visit (AST::MacroInvocation &invoc)
 {
   auto path = invoc.get_invoc_data ().get_path ();
 
+  if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
+for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
+  pending_invoc->accept_vis (*this);
+
   // When a macro is invoked by an unqualified identifier (not part of a
   // multi-part path), it is first looked up in textual scoping. If this does
   // not yield any results, then it is looked up in path-based scoping. If the
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 9b490c18bab..0f482df2f00 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,11 +1,6 @@
 bounds1.rs
 break-rust2.rs
 break-rust3.rs
-macros/builtin/eager1.rs
-macros/builtin/eager2.rs
-macros/builtin/recurse2.rs
-macros/builtin/include3.rs
-macros/builtin/include4.rs
 canonical_paths1.rs
 cfg1.rs
 cfg3.rs
-- 
2.45.2



[COMMITTED 084/146] gccrs: typecheck: Add note about erorring out on additional trait bounds.

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

If additional trait bounds aren't auto traits, then the typechecker
must error out (Rust-GCC#3008)

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc: Add TODO note.
---
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index e9859a71f83..e9207effafb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -757,6 +757,11 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
   std::vector specified_bounds;
   for (auto &bound : type.get_type_param_bounds ())
 {
+  // TODO: here we need to check if there are additional bounds that aren't
+  // auto traits. this is an error. for example, `dyn A + Sized + Sync` is
+  // okay, because Sized and Sync are both auto traits but `dyn A + Copy +
+  // Clone` is not okay and should error out.
+
   if (bound->get_bound_type ()
  != HIR::TypeParamBound::BoundType::TRAITBOUND)
continue;
-- 
2.45.2



[COMMITTED 099/146] gccrs: fix ICE during HIR dump

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

These hir nodes have optional expressions which need guarded

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::do_qualifiedpathtype): add guard
(Dump::do_traitfunctiondecl): likewise
(Dump::visit): likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 2590eed19ae..5acf53e9296 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -404,7 +404,8 @@ Dump::do_qualifiedpathtype (QualifiedPathType &e)
   do_mappings (e.get_mappings ());
   visit_field ("type", e.get_type ());
 
-  visit_field ("trait", e.get_trait ());
+  if (e.has_as_clause ())
+visit_field ("trait", e.get_trait ());
 }
 
 void
@@ -521,7 +522,8 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
   else
 put_field ("function_params", "empty");
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
 
   if (e.has_where_clause ())
 put_field ("where_clause", e.get_where_clause ().as_string ());
@@ -1295,7 +1297,8 @@ Dump::visit (BreakExpr &e)
   else
 put_field ("label", "none");
 
-  visit_field ("break_expr ", e.get_expr ());
+  if (e.has_break_expr ())
+visit_field ("break_expr ", e.get_expr ());
 
   end ("BreakExpr");
 }
-- 
2.45.2



[COMMITTED 100/146] gccrs: nr2.0: Improve default, top-level, and late resolvers

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

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Make sure to scope visitation of the
children of type definition items.
* resolve/rust-default-resolver.h
(DefaultResolver::visit): Add overrides for TupleStruct, Union,
and TypeAlias.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Remove override for Enum.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Rely more on DefaultResolver::visit.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Remove override for BlockExpr.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-default-resolver.cc | 35 ++---
 gcc/rust/resolve/rust-default-resolver.h  |  3 ++
 .../resolve/rust-late-name-resolver-2.0.cc|  7 ---
 .../resolve/rust-late-name-resolver-2.0.h |  1 -
 .../rust-toplevel-name-resolver-2.0.cc| 50 ---
 .../resolve/rust-toplevel-name-resolver-2.0.h |  1 -
 gcc/testsuite/rust/compile/nr2/exclude|  9 
 7 files changed, 41 insertions(+), 65 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 57b1cc44815..7528e7950e6 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -88,27 +88,48 @@ DefaultResolver::visit (AST::TraitImpl &impl)
 void
 DefaultResolver::visit (AST::StructStruct &type)
 {
-  // do we need to scope anything here? no, right?
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
-  // we also can't visit `StructField`s by default, so there's nothing to do -
-  // correct? or should we do something like
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
+}
 
-  AST::DefaultASTVisitor::visit (type);
+void
+DefaultResolver::visit (AST::TupleStruct &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
-  // FIXME: ???
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
 }
 
 void
 DefaultResolver::visit (AST::Enum &type)
 {
-  // FIXME: Do we need to scope anything by default?
-
   auto variant_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
  variant_fn, type.get_identifier ());
 }
 
+void
+DefaultResolver::visit (AST::Union &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_identifier ());
+}
+
+void
+DefaultResolver::visit (AST::TypeAlias &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_new_type_name ());
+}
+
 void
 DefaultResolver::visit (AST::ClosureExprInner &expr)
 {
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 9fcddd15851..587d7d45803 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -52,7 +52,10 @@ public:
 
   // type dec nodes, which visit their fields or variants by default
   void visit (AST::StructStruct &) override;
+  void visit (AST::TupleStruct &) override;
   void visit (AST::Enum &) override;
+  void visit (AST::Union &) override;
+  void visit (AST::TypeAlias &) override;
 
   // Visitors that visit their expression node(s)
   void visit (AST::ClosureExprInner &) override;
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 86fd5f12173..bb099ab68ae 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -308,13 +308,6 @@ Late::visit (AST::StructStruct &s)
   ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
 }
 
-void
-Late::visit (AST::Enum &s)
-{
-  auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
-  ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
-}
-
 void
 Late::visit (AST::StructExprStruct &s)
 {
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 803a5ec1c00..2af73c38286 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -53,7 +53,6 @@ public:
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
   void visit (AST::StructStruct &) override;
-  void visit (A

[COMMITTED 093/146] gccrs: Remove Rust::make_unique

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

Since our bootstrap requirement has been bumped to C++14, we don't need
a custom implementation of std::make_unique anymore.

gcc/rust/ChangeLog:

* ast/rust-ast-builder-type.cc: Remove inclusion of
rust-make-unique.h.
* ast/rust-ast-builder.cc: Likewise.
(Builder::array): Use std::make_unique instead of
Rust::make_unique.
* ast/rust-ast.cc (Attribute::get_traits_to_derive): Likewise.
* ast/rust-macro.h: Remove inclusion of rust-make-unique.h.
(MacroRulesDefinition::mbe): Use std::make_unique instead of
Rust::make_unique.
(MacroRulesDefinition::decl_macro): Likewise.
* ast/rust-path.h
(PathInExpression::PathInExpression): Likewise.
(QualifiedPathInExpression::QualifiedPathInExpression):
Likewise.
* backend/rust-compile-pattern.cc
(CompilePatternCheckExpr::visit): Likewise.
* expand/rust-derive-copy.cc
(DeriveCopy::copy_impl): Likewise.
* expand/rust-expand-format-args.cc
(expand_format_args): Likewise.
* expand/rust-macro-builtins-asm.cc: Remove inclusion of
rust-make-unique.h.
(parse_asm): Use std::make_unique instead of Rust::make_unique.
* hir/rust-ast-lower-expr.cc
(ASTLoweringExpr::visit): Likewise.
* hir/tree/rust-hir-expr.cc
(StructExprStructFields::StructExprStructFields): Likewise.
(StructExprStructFields::operator=): Likewise.
* hir/tree/rust-hir.cc
(TypePath::to_trait_bound): Likewise.
* lex/rust-token.h: Remove inclusion of rust-make-unique.h.
(Token::Token): Use std::make_unique instead of
Rust::make_unique.
* metadata/rust-import-archive.cc: Remove inclusion of
rust-make-unique.h.
(Import::find_archive_export_data): Use std::make_unique instead
of Rust::make_unique.
* metadata/rust-imports.cc: Remove inclusion of
rust-make-unique.h.
(Import::find_export_data): Use std::make_unique instead of
Rust::make_unique.
(Import::find_object_export_data): Likewise.
* parse/rust-parse-impl.h: Remove inclusion of
rust-make-unique.h.
(Parser::parse_function_param): Use std::make_unique instead of
Rust::make_unique.
(Parser::parse_self_param): Likewise.
(Parser::parse_array_expr): Likewise.
* typecheck/rust-hir-type-check-enumitem.cc
(TypeCheckEnumItem::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.cc
(TypeCheckTopLevelExternItem::visit): Likewise.
(TypeCheckImplItem::visit): Likewise.
* typecheck/rust-hir-type-check-type.cc
(TypeResolveGenericParam::visit): Likewise.
* typecheck/rust-hir-type-check.cc: Remove inclusion of
rust-make-unique.h.
(TraitItemReference::get_type_from_fn): Use std::make_unique
instead of Rust::make_unique.
* typecheck/rust-tyty-bounds.cc
(TypeCheckBase::get_predicate_from_bound): Likewise.
* util/rust-make-unique.h: Removed.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-builder-type.cc |  1 -
 gcc/rust/ast/rust-ast-builder.cc  |  3 +-
 gcc/rust/ast/rust-ast.cc  |  4 +--
 gcc/rust/ast/rust-macro.h |  5 ++-
 gcc/rust/ast/rust-path.h  |  8 ++---
 gcc/rust/backend/rust-compile-pattern.cc  |  2 +-
 gcc/rust/expand/rust-derive-copy.cc   |  2 +-
 gcc/rust/expand/rust-expand-format-args.cc|  2 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc|  7 ++--
 gcc/rust/hir/rust-ast-lower-expr.cc   |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.cc| 10 +++---
 gcc/rust/hir/tree/rust-hir.cc |  4 +--
 gcc/rust/lex/rust-token.h |  7 ++--
 gcc/rust/metadata/rust-import-archive.cc  |  5 ++-
 gcc/rust/metadata/rust-imports.cc |  5 ++-
 gcc/rust/parse/rust-parse-impl.h  | 23 ++--
 .../typecheck/rust-hir-type-check-enumitem.cc |  6 ++--
 .../typecheck/rust-hir-type-check-implitem.cc |  4 +--
 .../typecheck/rust-hir-type-check-type.cc |  2 +-
 gcc/rust/typecheck/rust-hir-type-check.cc |  3 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc|  4 +--
 gcc/rust/util/rust-make-unique.h  | 35 ---
 22 files changed, 50 insertions(+), 94 deletions(-)
 delete mode 100644 gcc/rust/util/rust-make-unique.h

diff --git a/gcc/rust/ast/rust-ast-builder-type.cc 
b/gcc/rust/ast/rust-ast-builder-type.cc
index e76d0de0e9a..13126b44057 100644
--- a/gcc/rust/ast/rust-ast-builder-type.cc
+++ b/gcc/rust/ast/rust-ast-builder-type.cc
@@ -20,7 +20,6 @@
 #include "rust-ast-builder.h"
 #include "rust-ast-full.h"
 #include "rust-common.h"
-#include "rust-make-unique.h"
 
 namespace Rust {
 namespace AST {
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 2fb0

[COMMITTED 092/146] gccrs: ast: Add EnumItem::Kind

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

gcc/rust/ChangeLog:

* ast/rust-item.h: Add EnumItem::Kind for differentiating all variants 
that may be
used inside an enum declaration.
---
 gcc/rust/ast/rust-item.h | 52 
 1 file changed, 52 insertions(+)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 6b77449eb8d..ecd355f6b8a 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1994,6 +1994,41 @@ class EnumItem : public VisItem
   location_t locus;
 
 public:
+  enum class Kind
+  {
+Identifier,
+Tuple,
+Struct,
+
+// FIXME: In the future, we'll need to remove this possibility as well as
+// remove the EnumItemDiscriminant class. The feature for arbitrary
+// discriminants on all kinds of variants has been stabilized, and a
+// "discriminant" is no longer an enum item variant - it's simply an
+// optional part of all variants.
+//
+// Per the reference:
+//
+// EnumItem :
+//OuterAttribute* Visibility?
+//IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant?
+//
+// EnumItemTuple :
+//( TupleFields? )
+//
+// EnumItemStruct :
+//{ StructFields? }
+//
+// EnumItemDiscriminant :
+//= Expression
+//
+// So we instead need to remove the class, and add an optional expression 
to
+// the base EnumItem class
+//
+// gccrs#3340
+
+Discriminant,
+  };
+
   virtual ~EnumItem () {}
 
   EnumItem (Identifier variant_name, Visibility vis,
@@ -2002,6 +2037,8 @@ public:
   variant_name (std::move (variant_name)), locus (locus)
   {}
 
+  virtual Kind get_enum_item_kind () const { return Kind::Identifier; }
+
   // Unique pointer custom clone function
   std::unique_ptr clone_enum_item () const
   {
@@ -2043,6 +2080,11 @@ public:
   tuple_fields (std::move (tuple_fields))
   {}
 
+  EnumItem::Kind get_enum_item_kind () const override
+  {
+return EnumItem::Kind::Tuple;
+  }
+
   std::string as_string () const override;
 
   void accept_vis (ASTVisitor &vis) override;
@@ -2080,6 +2122,11 @@ public:
   struct_fields (std::move (struct_fields))
   {}
 
+  EnumItem::Kind get_enum_item_kind () const override
+  {
+return EnumItem::Kind::Struct;
+  }
+
   std::string as_string () const override;
 
   void accept_vis (ASTVisitor &vis) override;
@@ -2133,6 +2180,11 @@ public:
   EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
   EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
 
+  EnumItem::Kind get_enum_item_kind () const override
+  {
+return EnumItem::Kind::Discriminant;
+  }
+
   std::string as_string () const override;
 
   void accept_vis (ASTVisitor &vis) override;
-- 
2.45.2



[v2] C++: Adjust implicit '__cxa_bad_cast' prototype to reality

2025-03-21 Thread Thomas Schwinge
Hi!

On 2025-03-19T14:25:49+, Jonathan Wakely  wrote:
> On Wed, 19 Mar 2025 at 14:21, Marek Polacek  wrote:
>> On Wed, Mar 19, 2025 at 12:38:31PM +0100, Thomas Schwinge wrote:
>> > In 2001 Subversion r40924 (Git commit 
>> > 52a11cbfcf0cfb32628b6953588b6af4037ac0b6)
>> > "IA-64 ABI Exception Handling", '__cxa_bad_cast' changed from 'void *' to
>> > 'void' return type:
>> >
>> > --- libstdc++-v3/libsupc++/exception_support.cc
>> > +++ /dev/null
>> > @@ -1,388 +0,0 @@
>> > -[...]
>> > -// Helpers for rtti. Although these don't return, we give them return 
>> > types so
>> > -// that the type system is not broken.
>> > -extern "C" void *
>> > -__cxa_bad_cast ()
>> > -{
>> > -  [...]
>> > -}
>> > -[...]
>> >
>> > --- /dev/null
>> > +++ libstdc++-v3/libsupc++/unwind-cxx.h
>> > @@ -0,0 +1,163 @@
>> > +[...]
>> > +extern "C" void __cxa_bad_cast ();
>> > +[...]
>> >
>> > --- /dev/null
>> > +++ libstdc++-v3/libsupc++/eh_aux_runtime.cc
>> > @@ -0,0 +1,56 @@
>> > +[...]
>> > +extern "C" void
>> > +__cxa_bad_cast ()
>> > +{
>> > +  [...]
>> > +}
>> > +[...]
>> >
>> > The implicit prototype in the C++ front end however wasn't likewise 
>> > adjusted,
>> > and so for nvptx we generate code for 'void *' return type:
>> >
>> > // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> > .extern .func (.param .u64 %value_out) __cxa_bad_cast;
>> >
>> > {
>> > .param .u64 %value_in;
>> > call (%value_in),__cxa_bad_cast;
>> > trap;
>> > // (noreturn)
>> > exit;
>> > // (noreturn)
>> > ld.param.u64 %r30,[%value_in];
>> > }
>> >
>> > ..., which is in conflict with the library code with 'void' return type:
>> >
>> > // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> > .visible .func __cxa_bad_cast;
>> >
>> > // BEGIN GLOBAL FUNCTION DEF: __cxa_bad_cast
>> > .visible .func __cxa_bad_cast
>> > {
>> > [...]
>> > }
>> >
>> > ..., and we thus get execution test FAIL for 'g++.dg/rtti/dyncast2.C':
>> >
>> > error   : Prototype doesn't match for '__cxa_bad_cast' in 'input file 
>> > 7 at offset 51437', first defined in 'input file 7 at offset 51437'
>> > nvptx-run: cuLinkAddData failed: device kernel image is invalid 
>> > (CUDA_ERROR_INVALID_SOURCE, 300)
>> >
>> > With this patched, we get the expected:
>> >
>> >  // BEGIN GLOBAL FUNCTION DECL: __cxa_bad_cast
>> > -.extern .func (.param .u64 %value_out) __cxa_bad_cast;
>> > +.extern .func __cxa_bad_cast;
>> >
>> >  {
>> > -.param .u64 %value_in;
>> > -call (%value_in),__cxa_bad_cast;
>> > +call __cxa_bad_cast;
>> >  trap;
>> >  // (noreturn)
>> >  exit;
>> >  // (noreturn)
>> > -ld.param.u64 %r30,[%value_in];
>> >  }
>> >
>> > ..., and execution test PASS.
>> >
>> >   gcc/cp/
>> >   * rtti.cc (throw_bad_cast): Adjust implicit '__cxa_bad_cast'
>> >   prototype to reality.
>> > ---
>> >  gcc/cp/rtti.cc | 2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
>> > index dcf84f17163..a10fa383f79 100644
>> > --- a/gcc/cp/rtti.cc
>> > +++ b/gcc/cp/rtti.cc
>> > @@ -198,7 +198,7 @@ throw_bad_cast (void)
>> >fn = get_global_binding (name);
>> >if (!fn)
>> >   fn = push_throw_library_fn
>> > -   (name, build_function_type_list (ptr_type_node, NULL_TREE));
>> > +   (name, build_function_type_list (void_type_node, NULL_TREE));
>> >  }
>> >
>> >return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
>>
>> LGTM, matches what I see in abi-eh.html from the itanium-cxx-abi.
>>
>> The comment above mentions libstdc++/exception.cc but I don't see that
>> file.
>
> I think that was removed in 2001 by r39445 :-)

Yeah, I'd noticed that right after (of course) having sent my original
email; fixed in the "v2" that I've now pushed to trunk branch:
commit 618c42d23726be6e2086d452d6718abe5e0daca8
"C++: Adjust implicit '__cxa_bad_cast' prototype to reality", see
attached.

By the way, I've also tested this with 'fn = get_global_binding (name);'
commented out, to force always using the C++ front end-synthesized
prototype (per my understanding).

I've just realized that we might check if some users of 'throw_bad_cast'
have special code to handle the case of 'void *' return type in addition
to 'void', which can now be simplified -- I'll try to look into that next
week.


Grüße
 Thomas


>From 618c42d23726be6e2086d452d6718abe5e0daca8 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge 
Date: Wed, 19 Mar 2025 12:18:26 +0100
Subject: [PATCH] C++: Adjust implicit '__cxa_bad_cast' prototype to reality

In 2001 Subversion r40924 (Git commit 52a11cbfcf0cfb32628b6953588b6af4037ac0b6)
"IA-64 ABI Exception Handling", '__cxa_bad_cast' changed from 'void *' to
'void' return type:

--- libstdc++-v3/libsupc++/exception_support.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-[...]
-// Helpe

[COMMITTED 098/146] gccrs: use StackedContexts for block context

2025-03-21 Thread arthur . cohen
From: Prajwal S N 

Replaces the DIY vector stack with a StackedContexts object for block
scopes in the type checker context.

Fixes #3284.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check.h (class TypeCheckContext): add
header file and use StackedContexts for blocks
* typecheck/rust-typecheck-context.cc: update methods
* typecheck/rust-hir-trait-resolve.cc: refactor function calls
* typecheck/rust-hir-type-check-implitem.cc: refactor function calls
* typecheck/rust-hir-type-check-type.cc: refactor function calls

Signed-off-by: Prajwal S N 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  4 +--
 .../typecheck/rust-hir-type-check-implitem.cc |  5 ++--
 .../typecheck/rust-hir-type-check-type.cc |  7 ++---
 gcc/rust/typecheck/rust-hir-type-check.h  |  8 +++---
 gcc/rust/typecheck/rust-typecheck-context.cc  | 26 +++
 5 files changed, 15 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 14e26f4512b..82019328e16 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -278,7 +278,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 }
   self->inherit_bounds (specified_bounds);
 
-  context->push_block_context (TypeCheckBlockContextItem (trait_reference));
+  context->block_context ().enter (TypeCheckBlockContextItem 
(trait_reference));
   std::vector item_refs;
   for (auto &item : trait_reference->get_trait_items ())
 {
@@ -308,7 +308,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
   // resolve the blocks of functions etc because it can end up in a recursive
   // loop of trying to resolve traits as required by the types
   tref->on_resolved ();
-  context->pop_block_context ();
+  context->block_context ().exit ();
 
   return tref;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 4521822410c..937a8a8d0ef 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -335,9 +335,10 @@ TypeCheckImplItem::Resolve (
 
   // resolve
   TypeCheckImplItem resolver (parent, self, substitutions);
-  resolver.context->push_block_context (TypeCheckBlockContextItem (&parent));
+  resolver.context->block_context ().enter (
+TypeCheckBlockContextItem (&parent));
   item.accept_vis (resolver);
-  resolver.context->pop_block_context ();
+  resolver.context->block_context ().exit ();
 
   return resolver.result;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 859cdfedcd0..bb23f8441ed 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -591,10 +591,11 @@ TypeCheckType::resolve_segments (
   bool first_segment = i == offset;
   bool selfResolveOk = false;
 
-  if (first_segment && tySegIsBigSelf && context->have_block_context ()
- && context->peek_block_context ().is_impl_block ())
+  if (first_segment && tySegIsBigSelf
+ && context->block_context ().is_in_context ()
+ && context->block_context ().peek ().is_impl_block ())
{
- TypeCheckBlockContextItem ctx = context->peek_block_context ();
+ TypeCheckBlockContextItem ctx = context->block_context ().peek ();
  TyTy::BaseType *lookup = nullptr;
  selfResolveOk
= resolve_associated_type (seg->as_string (), ctx, &lookup);
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 08c3d354f79..ef1f2dd0214 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -22,6 +22,7 @@
 #include "rust-hir-map.h"
 #include "rust-tyty.h"
 #include "rust-hir-trait-reference.h"
+#include "rust-stacked-contexts.h"
 #include "rust-autoderef.h"
 #include "rust-tyty-region.h"
 #include "rust-tyty-variance-analysis.h"
@@ -186,10 +187,7 @@ public:
 TyTy::BaseType *return_type);
   void pop_return_type ();
 
-  bool have_block_context () const;
-  TypeCheckBlockContextItem peek_block_context ();
-  void push_block_context (TypeCheckBlockContextItem item);
-  void pop_block_context ();
+  StackedContexts &block_context ();
 
   void iterate (std::function cb);
 
@@ -282,7 +280,7 @@ private:
   std::vector>
 return_type_stack;
   std::vector loop_type_stack;
-  std::vector block_stack;
+  StackedContexts block_stack;
   std::map trait_context;
   std::map receiver_context;
   std::map associated_impl_traits;
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index e72ce41606d..8ff8839f733 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -177,30

[COMMITTED 019/146] gccrs: Use name resolver 2.0 in VisibilityResolver

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

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-visibility-resolver.cc:
Add includes.
(VisibilityResolver::resolve_module_path): Use name resolver 2.0
(when enabled) to lookup path resolutions.

Signed-off-by: Owen Avery 
---
 .../privacy/rust-visibility-resolver.cc   | 21 ++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc 
b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index 464ce86e177..f0da7456076 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -20,6 +20,10 @@
 #include "rust-ast.h"
 #include "rust-hir.h"
 #include "rust-hir-item.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace Privacy {
@@ -61,7 +65,22 @@ VisibilityResolver::resolve_module_path (const 
HIR::SimplePath &restriction,
 "cannot use non-module path as privacy restrictor");
 
   NodeId ref_node_id = UNKNOWN_NODEID;
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  if (auto id = nr_ctx.lookup (ast_node_id))
+   {
+ ref_node_id = *id;
+   }
+  else
+   {
+ invalid_path.emit ();
+ return false;
+   }
+}
+  else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
 {
   invalid_path.emit ();
   return false;
-- 
2.45.2



[COMMITTED 027/146] gccrs: typecheck: Remove unused parameter in TyTyCheckCallExpr

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

gcc/rust/ChangeLog:

* typecheck/rust-tyty-call.h: Remove unused context member.
---
 gcc/rust/typecheck/rust-tyty-call.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty-call.h 
b/gcc/rust/typecheck/rust-tyty-call.h
index 67cfe30057a..00ac655e5e4 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -73,14 +73,12 @@ private:
   TypeCheckCallExpr (HIR::CallExpr &c, TyTy::VariantDef &variant,
 Resolver::TypeCheckContext *context)
 : resolved (new TyTy::ErrorType (c.get_mappings ().get_hirid ())), call 
(c),
-  variant (variant), context (context),
-  mappings (Analysis::Mappings::get ())
+  variant (variant), mappings (Analysis::Mappings::get ())
   {}
 
   BaseType *resolved;
   HIR::CallExpr &call;
   TyTy::VariantDef &variant;
-  Resolver::TypeCheckContext *context;
   Analysis::Mappings &mappings;
 };
 
-- 
2.45.2



[COMMITTED 058/146] gccrs: stacked-contexts: Add peek() method

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

gcc/rust/ChangeLog:

* util/rust-stacked-contexts.h: Add new method to see what context we 
are currently in.
---
 gcc/rust/util/rust-stacked-contexts.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/util/rust-stacked-contexts.h 
b/gcc/rust/util/rust-stacked-contexts.h
index 39a0c08de79..fe0bc8a291b 100644
--- a/gcc/rust/util/rust-stacked-contexts.h
+++ b/gcc/rust/util/rust-stacked-contexts.h
@@ -71,6 +71,13 @@ public:
 return last;
   }
 
+  const T &peek ()
+  {
+rust_assert (!stack.empty ());
+
+return stack.back ();
+  }
+
   /**
* Are we currently inside of a special context?
*/
-- 
2.45.2



[COMMITTED 018/146] gccrs: fix bad type inference on local patterns

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

We do not need to inject inference variables on generic patterns
with generic blocks. This will just cause unconstrained inference
variables as they may not unify against something.

Fixes Rust-GCC#2323

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path): dont infer here

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 3 ++-
 gcc/testsuite/rust/compile/issue-2323.rs   | 9 +
 gcc/testsuite/rust/compile/nr2/exclude | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2323.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 231ddd604db..7b934b38eb3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -245,6 +245,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
 
   auto seg_is_module = mappings.lookup_module (ref).has_value ();
   auto seg_is_crate = mappings.is_local_hirid_crate (ref);
+  auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
   if (seg_is_module || seg_is_crate)
{
  // A::B::C::this_is_a_module::D::E::F
@@ -321,7 +322,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
-  else if (lookup->needs_generic_substitutions ())
+  else if (lookup->needs_generic_substitutions () && !seg_is_pattern)
{
  lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
}
diff --git a/gcc/testsuite/rust/compile/issue-2323.rs 
b/gcc/testsuite/rust/compile/issue-2323.rs
new file mode 100644
index 000..02a3f90b4d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2323.rs
@@ -0,0 +1,9 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub struct S(T);
+
+pub fn foo(x: T) {
+let y = S(x);
+y.0;
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 4ba27d31f88..eaa2a1e0d0b 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -222,4 +222,5 @@ if_let_expr_simple.rs
 iflet.rs
 issue-3033.rs
 issue-3009.rs
+issue-2323.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 030/146] gccrs: Push ribs by kind rather than by value

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

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::push): Accept argument of type Rib::Kind rather
than Rib.
* resolve/rust-forever-stack.hxx
(ForeverStack::push): Likewise.
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::scoped): Likewise.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::scoped): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h|  2 +-
 gcc/rust/resolve/rust-forever-stack.hxx  |  5 +++--
 gcc/rust/resolve/rust-name-resolution-context.cc | 15 ---
 gcc/rust/resolve/rust-name-resolution-context.h  |  9 +
 4 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 28509259497..c548eeae087 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -416,7 +416,7 @@ public:
* @param path An optional path if the Rib was created due to a "named"
*lexical scope, like a module's.
*/
-  void push (Rib rib, NodeId id, tl::optional path = {});
+  void push (Rib::Kind rib_kind, NodeId id, tl::optional path = 
{});
 
   /**
* Pop the innermost Rib from the stack
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 31f8ba498b3..58164a4d328 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -52,9 +52,10 @@ ForeverStack::Node::insert_child (Link link, Node child)
 
 template 
 void
-ForeverStack::push (Rib rib, NodeId id, tl::optional path)
+ForeverStack::push (Rib::Kind rib_kind, NodeId id,
+  tl::optional path)
 {
-  push_inner (rib, Link (id, path));
+  push_inner (rib_kind, Link (id, path));
 }
 
 template 
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 9bfaa094abe..1b375213878 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -103,13 +103,13 @@ NameResolutionContext::lookup (NodeId usage) const
 }
 
 void
-NameResolutionContext::scoped (Rib rib, NodeId id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, NodeId id,
   std::function lambda,
   tl::optional path)
 {
-  values.push (rib, id, path);
-  types.push (rib, id, path);
-  macros.push (rib, id, path);
+  values.push (rib_kind, id, path);
+  types.push (rib_kind, id, path);
+  macros.push (rib_kind, id, path);
   // labels.push (rib, id);
 
   lambda ();
@@ -121,17 +121,18 @@ NameResolutionContext::scoped (Rib rib, NodeId id,
 }
 
 void
-NameResolutionContext::scoped (Rib rib, Namespace ns, NodeId scope_id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, Namespace ns,
+  NodeId scope_id,
   std::function lambda,
   tl::optional path)
 {
   switch (ns)
 {
 case Namespace::Values:
-  values.push (rib, scope_id, path);
+  values.push (rib_kind, scope_id, path);
   break;
 case Namespace::Types:
-  types.push (rib, scope_id, path);
+  types.push (rib_kind, scope_id, path);
   break;
 case Namespace::Labels:
 case Namespace::Macros:
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index cd6fa931be5..183ce7f3c2e 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -185,8 +185,8 @@ public:
* function. This variant of the function enters a new scope in *all*
* namespaces, while the second variant enters a scope in *one* namespace.
*
-   * @param rib New `Rib` to create when entering this scope. A function `Rib`,
-   *or an item `Rib`... etc
+   * @param rib_kind New `Rib` to create when entering this scope. A function
+   *`Rib`, or an item `Rib`... etc
* @param scope_id node ID of the scope we are entering, e.g the block's
*`NodeId`.
* @param lambda Function to run within that scope
@@ -196,9 +196,10 @@ public:
*/
   // FIXME: Do we want to handle something in particular for expected within 
the
   // scoped lambda?
-  void scoped (Rib rib, NodeId scope_id, std::function lambda,
+  void scoped (Rib::Kind rib_kind, NodeId scope_id,
+  std::function lambda,
   tl::optional path = {});
-  void scoped (Rib rib, Namespace ns, NodeId scope_id,
+  void scoped (Rib::Kind rib_kind, Namespace ns, NodeId scope_id,
   std::function lambda,
   tl::optional path = {});
 
-- 
2.45.2



[COMMITTED 037/146] gccrs: FnParam cloning now keeps projections

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

FnParam type where monomorphized during cloning.

gcc/rust/ChangeLog:

* typecheck/rust-tyty.h: Reverse monomorphization during cloning and
make a new function to explicitly monomorphize.
* typecheck/rust-tyty.cc: Use monomorphization when required.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/typecheck/rust-tyty.cc | 2 +-
 gcc/rust/typecheck/rust-tyty.h  | 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index e2f1361a78e..1073dfa6adc 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -597,7 +597,7 @@ BaseType::monomorphized_clone () const
 {
   std::vector cloned_params;
   for (auto &p : fn->get_params ())
-   cloned_params.push_back (p.clone ());
+   cloned_params.push_back (p.monomorphized_clone ());
 
   BaseType *retty = fn->get_return_type ()->monomorphized_clone ();
   return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 4d1a082f80d..94f7bce00f8 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -791,6 +791,11 @@ public:
   void set_type (BaseType *new_type) { type = new_type; }
 
   FnParam clone () const
+  {
+return FnParam (pattern->clone_pattern (), type->clone ());
+  }
+
+  FnParam monomorphized_clone () const
   {
 return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
   }
-- 
2.45.2



[COMMITTED 003/146] gccrs: Fix variable shadowing in late resolution 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Visit the initialization expressions of let
statements before visiting their patterns.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 43f33dfab02..5fd49e7c2c9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -126,8 +126,14 @@ Late::new_label (Identifier name, NodeId id)
 void
 Late::visit (AST::LetStmt &let)
 {
-  // so we don't need that method
-  DefaultResolver::visit (let);
+  DefaultASTVisitor::visit_outer_attrs (let);
+  if (let.has_type ())
+visit (let.get_type ());
+  // visit expression before pattern
+  // this makes variable shadowing work properly
+  if (let.has_init_expr ())
+visit (let.get_init_expr ());
+  visit (let.get_pattern ());
 
   // how do we deal with the fact that `let a = blipbloup` should look for a
   // label and cannot go through function ribs, but `let a = blipbloup()` can?
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 383950ca863..c96fde25fc5 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -74,10 +74,8 @@ issue-1589.rs
 issue-1725-1.rs
 issue-1725-2.rs
 issue-1786.rs
-issue-1813.rs
 issue-1893.rs
 issue-1901.rs
-issue-1930.rs
 issue-1981.rs
 issue-2019-1.rs
 issue-2019-2.rs
@@ -142,7 +140,6 @@ match4.rs
 match5.rs
 match9.rs
 method2.rs
-multi_reference_type.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
 name_resolution2.rs
-- 
2.45.2



[COMMITTED 020/146] gccrs: Use name resolver 2.0 for module descendance checks

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

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc:
Include rust-immutable-name-resolution-context.h.
(is_child_module): Use ForeverStack::is_module_descendant if name
resolution 2.0 is enabled.
* resolve/rust-forever-stack.h
(ForeverStack::is_module_descendant): Add.
(ForeverStack::dfs_node): Add.
* resolve/rust-forever-stack.hxx
(ForeverStack::dfs_rib): Use ForeverStack::dfs_node.
(ForeverStack::dfs_node): Add.
(ForeverStack::is_module_descendant): Add.

Signed-off-by: Owen Avery 
---
 .../errors/privacy/rust-privacy-reporter.cc   |  9 
 gcc/rust/resolve/rust-forever-stack.h | 10 +
 gcc/rust/resolve/rust-forever-stack.hxx   | 41 +++
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 1ee2097b383..fa2de9c3f40 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -22,6 +22,7 @@
 #include "rust-hir-stmt.h"
 #include "rust-hir-item.h"
 #include "rust-attribute-values.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Privacy {
@@ -93,6 +94,14 @@ static bool
 is_child_module (Analysis::Mappings &mappings, NodeId parent,
 NodeId possible_child)
 {
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  return nr_ctx.values.is_module_descendant (parent, possible_child);
+}
+
   auto children = mappings.lookup_module_children (parent);
 
   if (!children)
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 8c5e207a70d..28509259497 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -521,6 +521,12 @@ public:
 
   std::string as_debug_string ();
 
+  /**
+   * Used to check if a module is a descendant of another module
+   * Intended for use in the privacy checker
+   */
+  bool is_module_descendant (NodeId parent, NodeId child) const;
+
 private:
   /**
* A link between two Nodes in our trie data structure. This class represents
@@ -635,6 +641,10 @@ private:
   tl::optional dfs_rib (Node &starting_point, NodeId to_find);
   tl::optional dfs_rib (const Node &starting_point,
 NodeId to_find) const;
+  // FIXME: Documentation
+  tl::optional dfs_node (Node &starting_point, NodeId to_find);
+  tl::optional dfs_node (const Node &starting_point,
+  NodeId to_find) const;
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 5a5a7c73f32..31f8ba498b3 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -625,13 +625,33 @@ ForeverStack::to_canonical_path (NodeId id) const
 template 
 tl::optional
 ForeverStack::dfs_rib (ForeverStack::Node &starting_point, NodeId 
to_find)
+{
+  return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
+return x.rib;
+  });
+}
+
+template 
+tl::optional
+ForeverStack::dfs_rib (const ForeverStack::Node &starting_point,
+ NodeId to_find) const
+{
+  return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
+return x.rib;
+  });
+}
+
+template 
+tl::optional::Node &>
+ForeverStack::dfs_node (ForeverStack::Node &starting_point,
+  NodeId to_find)
 {
   if (starting_point.id == to_find)
-return starting_point.rib;
+return starting_point;
 
   for (auto &child : starting_point.children)
 {
-  auto candidate = dfs_rib (child.second, to_find);
+  auto candidate = dfs_node (child.second, to_find);
 
   if (candidate.has_value ())
return candidate;
@@ -641,16 +661,16 @@ ForeverStack::dfs_rib (ForeverStack::Node 
&starting_point, NodeId to_find)
 }
 
 template 
-tl::optional
-ForeverStack::dfs_rib (const ForeverStack::Node &starting_point,
- NodeId to_find) const
+tl::optional::Node &>
+ForeverStack::dfs_node (const ForeverStack::Node &starting_point,
+  NodeId to_find) const
 {
   if (starting_point.id == to_find)
-return starting_point.rib;
+return starting_point;
 
   for (auto &child : starting_point.children)
 {
-  auto candidate = dfs_rib (child.second, to_find);
+  auto candidate = dfs_node (child.second, to_find);
 
   if (candidate.has_value ())
return candidate;
@@ -737,6 +757,13 @@ ForeverStack::as_debug_string ()
   return stream.str ();
 }
 
+template 
+bool
+ForeverStack::is_module_descendant (NodeId parent, NodeId child) const
+{
+  return dfs_node (dfs_node (root, parent).value (), child).has

[COMMITTED 014/146] gccrs: Make TyTy::TupleType::get_unit_type cache its return value

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

This removes a usage of Resolver::get_unit_type_node_id in
rust-hir-type-check-expr.cc (the HIR::TupleExpr overload of
TypeCheckExpr::visit).

gcc/rust/ChangeLog:

* typecheck/rust-tyty.cc
(TupleType::get_unit_type): Remove parameter, cache return
value.
* typecheck/rust-tyty.h
(TupleType::get_unit_type): Remove parameter.
* resolve/rust-late-name-resolver-2.0.cc
(Late::setup_builtin_types): Adjust calls to get_unit_type.
* resolve/rust-name-resolver.cc
(Resolver::generate_builtins): Likewise.
* typecheck/rust-hir-type-check-expr.cc
(TypeCheckExpr::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.cc
(TypeCheckTopLevelExternItem::visit): Likewise.
(TypeCheckImplItem::visit): Likewise.
* typecheck/rust-hir-type-check-item.cc
(TypeCheckItem::visit): Likewise.
* typecheck/rust-hir-type-check-stmt.cc
(TypeCheckStmt::visit): Likewise.
* typecheck/rust-hir-type-check-type.cc
(TypeCheckType::visit): Likewise.
* typecheck/rust-hir-type-check.cc
(TraitItemReference::get_type_from_fn): Likewise.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc|  2 +-
 gcc/rust/resolve/rust-name-resolver.cc|  3 +-
 .../typecheck/rust-hir-type-check-expr.cc | 43 +++
 .../typecheck/rust-hir-type-check-implitem.cc |  6 +--
 .../typecheck/rust-hir-type-check-item.cc |  3 +-
 .../typecheck/rust-hir-type-check-stmt.cc |  4 +-
 .../typecheck/rust-hir-type-check-type.cc |  2 +-
 gcc/rust/typecheck/rust-hir-type-check.cc |  2 +-
 gcc/rust/typecheck/rust-tyty.cc   |  8 +++-
 gcc/rust/typecheck/rust-tyty.h|  2 +-
 10 files changed, 31 insertions(+), 44 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 5fc97a0922b..812154eaf79 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -100,7 +100,7 @@ Late::setup_builtin_types ()
 }
 
   // ...here!
-  auto *unit_type = TyTy::TupleType::get_unit_type (next_hir_id ());
+  auto *unit_type = TyTy::TupleType::get_unit_type ();
   ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
 }
 
diff --git a/gcc/rust/resolve/rust-name-resolver.cc 
b/gcc/rust/resolve/rust-name-resolver.cc
index 21147bd86fa..3b4e3111d93 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -435,8 +435,7 @@ Resolver::generate_builtins ()
   set_never_type_node_id (never_node_id);
 
   // unit type ()
-  TyTy::TupleType *unit_tyty
-= TyTy::TupleType::get_unit_type (mappings.get_next_hir_id ());
+  TyTy::TupleType *unit_tyty = TyTy::TupleType::get_unit_type ();
   std::vector > elems;
   AST::TupleType *unit_type
 = new AST::TupleType (std::move (elems), BUILTINS_LOCATION);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 5b64daf33b7..225d83624e0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -131,12 +131,7 @@ TypeCheckExpr::visit (HIR::TupleExpr &expr)
 {
   if (expr.is_unit ())
 {
-  auto unit_node_id = resolver->get_unit_type_node_id ();
-  if (!context->lookup_builtin (unit_node_id, &infered))
-   {
- rust_error_at (expr.get_locus (),
-"failed to lookup builtin unit type");
-   }
+  infered = TyTy::TupleType::get_unit_type ();
   return;
 }
 
@@ -165,10 +160,9 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr)
   location_t expr_locus = expr.has_return_expr ()
? expr.get_expr ()->get_locus ()
: expr.get_locus ();
-  TyTy::BaseType *expr_ty
-= expr.has_return_expr ()
-   ? TypeCheckExpr::Resolve (expr.get_expr ().get ())
-   : TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+  TyTy::BaseType *expr_ty = expr.has_return_expr ()
+ ? TypeCheckExpr::Resolve (expr.get_expr ().get ())
+ : TyTy::TupleType::get_unit_type ();
 
   coercion_site (expr.get_mappings ().get_hirid (),
 TyTy::TyWithLocation (fn_return_tyty),
@@ -242,7 +236,7 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
 void
 TypeCheckExpr::visit (HIR::AssignmentExpr &expr)
 {
-  infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+  infered = TyTy::TupleType::get_unit_type ();
 
   auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ().get ());
   auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ().get ());
@@ -256,7 +250,7 @@ TypeCheckExpr::visit (HIR::AssignmentExpr &expr)
 void
 TypeCheckExpr::visit (HIR::CompoundAssignmentExpr &expr)
 {
-  infered = TyTy::TupleType::get_unit_type (

[COMMITTED 025/146] gccrs: add test case to show issue is fixed

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

The original test case 1773 has been moved to a new issue 3242 which
is still open and test-case is skipped. The original issue in 1773 is
fixed so this will close out that issue

Fixes Rust-Gcc#1773

gcc/testsuite/ChangeLog:

* rust/compile/issue-1773.rs: new test case
* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3242.rs: old test ranamed to match issue.

Signed-off-by: Philip Herron 
---
 gcc/testsuite/rust/compile/issue-1773.rs | 23 +++
 gcc/testsuite/rust/compile/issue-3242.rs | 24 
 gcc/testsuite/rust/compile/nr2/exclude   |  1 +
 3 files changed, 40 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3242.rs

diff --git a/gcc/testsuite/rust/compile/issue-1773.rs 
b/gcc/testsuite/rust/compile/issue-1773.rs
index 468497a4792..41c82f01b6d 100644
--- a/gcc/testsuite/rust/compile/issue-1773.rs
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -1,8 +1,4 @@
-#[lang = "sized"]
-// { dg-skip-if "" { *-*-* } }
-pub trait Sized {}
-
-trait Foo {
+trait Foo {
 type A;
 
 fn test(a: Self::A) -> Self::A {
@@ -10,9 +6,14 @@ trait Foo {
 }
 }
 
-struct Bar(T);
-impl Foo for Bar {
-type A = T;
+struct Bar(i32);
+impl Foo for Bar {
+type A = i32;
+}
+
+struct Baz(f32);
+impl Foo for Baz {
+type A = f32;
 }
 
 fn main() {
@@ -21,4 +22,10 @@ fn main() {
 
 let b;
 b = Bar::test(a.0);
+
+let c;
+c = Baz(123f32);
+
+let d;
+d = Baz::test(c.0);
 }
diff --git a/gcc/testsuite/rust/compile/issue-3242.rs 
b/gcc/testsuite/rust/compile/issue-3242.rs
new file mode 100644
index 000..468497a4792
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3242.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+// { dg-skip-if "" { *-*-* } }
+pub trait Sized {}
+
+trait Foo {
+type A;
+
+fn test(a: Self::A) -> Self::A {
+a
+}
+}
+
+struct Bar(T);
+impl Foo for Bar {
+type A = T;
+}
+
+fn main() {
+let a;
+a = Bar(123);
+
+let b;
+b = Bar::test(a.0);
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6f8187264aa..efee0fd1e2d 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -216,4 +216,5 @@ issue-3009.rs
 issue-2323.rs
 issue-2953-1.rs
 issue-2953-2.rs
+issue-1773.rs
 # please don't delete the trailing newline
-- 
2.45.2



Re: [PATCH] aarch64: Add support for -mcpu=olympus

2025-03-21 Thread Kyrylo Tkachov
Hi Dhruv,

> On 21 Mar 2025, at 11:11, Dhruv Chawla  wrote:
> 
> This adds support for the NVIDIA Olympus core to the AArch64 backend. The
> initial patch does not add any special tuning decisions, and those may come
> later.
> 
> Bootstrapped and tested on aarch64-none-linux-gnu.
> 

Thanks, given the time it takes for GCC releases to propagate through the Linux 
distro releases it makes sense
to have -mcpu support early on to set the baseline support, especially since 
the patch is not very invasive.

I’ve pushed this to trunk as 1aa49fe0b18 after doing a quick bootstrap and 
smoke test on aarch64-none-linux-gnu.

Kyrill


> gcc/ChangeLog:
> 
> * config/aarch64/aarch64-cores.def (olympus): New entry.
> * config/aarch64/aarch64-tune.md: Regenerate.
> * doc/invoke.texi (AArch64 Options): Document the above.
> 
> Signed-off-by: Dhruv Chawla 
> ---
> gcc/config/aarch64/aarch64-cores.def | 3 +++
> gcc/config/aarch64/aarch64-tune.md   | 2 +-
> gcc/doc/invoke.texi  | 2 +-
> 3 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/config/aarch64/aarch64-cores.def 
> b/gcc/config/aarch64/aarch64-cores.def
> index 5ac81332b67..0e22d72976e 100644
> --- a/gcc/config/aarch64/aarch64-cores.def
> +++ b/gcc/config/aarch64/aarch64-cores.def
> @@ -207,6 +207,9 @@ AARCH64_CORE("neoverse-v3ae", neoversev3ae, cortexa57, 
> V9_2A, (SVE2_BITPERM, RNG
>  AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, 
> RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
> +/* NVIDIA ('N') cores. */
> +AARCH64_CORE("olympus", olympus, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, 
> MEMTAG, PROFILE, FAMINMAX, FP8DOT2, LUT, SVE2_AES, SVE2_SHA3, SVE2_SM4), 
> neoversev3, 0x4e, 0x10, -1)
> +
> /* Generic Architecture Processors.  */
> AARCH64_CORE("generic",  generic, cortexa53, V8A,  (), generic, 0x0, 0x0, -1)
> AARCH64_CORE("generic-armv8-a",  generic_armv8_a, cortexa53, V8A, (), 
> generic_armv8_a, 0x0, 0x0, -1)
> diff --git a/gcc/config/aarch64/aarch64-tune.md 
> b/gcc/config/aarch64/aarch64-tune.md
> index 54c65cbf68d..56a914f12b9 100644
> --- a/gcc/config/aarch64/aarch64-tune.md
> +++ b/gcc/config/aarch64/aarch64-tune.md
> @@ -1,5 +1,5 @@
> ;; -*- buffer-read-only: t -*-
> ;; Generated automatically by gentune.sh from aarch64-cores.def
> (define_attr "tune"
> - 
> "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,generic,generic_armv8_a,generic_armv9_a"
> + 
> "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,generic,generic_armv8_a,generic_armv9_a"
> (const (symbol_ref "((enum attr_tune) aarch64_tune)")))
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 1819bcdcdfb..ca320db6f80 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -21745,7 +21745,7 @@ performance of the code.  Permissible values for this 
> option are:
> @samp{oryon-1},
> @samp{neoverse-512tvb}, @samp{neoverse-e1}, @samp{neoverse-n1},
> @samp{neoverse-n2}, @samp{neoverse-v1}, @samp{neoverse-v2}, @samp{grace},
> -@samp{neoverse-v3}, @samp{neoverse-v3ae}, @samp{neoverse-n3},
> +@samp{neoverse-v3}, @samp{neoverse-v3ae}, @samp{neoverse-n3}, @samp{olympus},
> @samp{cortex-a725}, @samp{cortex-x925},
> @samp{qdf24xx}, @samp{saphira}, @samp{phecda}, @

[COMMITTED 050/146] gccrs: Prepend crate name to functions with nr2

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

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Prepend crate name to function's ir
name.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove passing tests from exclude list.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-base.cc  | 11 ++-
 gcc/testsuite/rust/compile/nr2/exclude |  6 --
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 80ea7a4ec95..fb4aace9555 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -25,7 +25,8 @@
 #include "rust-compile-type.h"
 #include "rust-constexpr.h"
 #include "rust-diagnostics.h"
-#include "rust-expr.h" // for AST::AttrInputLiteral
+#include "rust-expr.h" // for AST::AttrInputLiteral
+#include "rust-hir-map.h"
 #include "rust-macro.h" // for AST::MetaNameValueStr
 #include "rust-hir-path-probe.h"
 #include "rust-type-util.h"
@@ -39,6 +40,9 @@
 #include "tree.h"
 #include "print-tree.h"
 
+// rust-name-resolution-2.0
+#include "options.h"
+
 namespace Rust {
 namespace Compile {
 
@@ -667,6 +671,11 @@ HIRCompileBase::compile_function (
 }
   std::string asm_name = fn_name;
 
+  auto &mappings = Analysis::Mappings::get ();
+
+  if (flag_name_resolution_2_0)
+ir_symbol_name = mappings.get_current_crate_name () + "::" + 
ir_symbol_name;
+
   unsigned int flags = 0;
   tree fndecl = Backend::function (compiled_fn_type, ir_symbol_name,
   "" /* asm_name */, flags, locus);
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6c589e4ab4e..b282f05637d 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,7 +1,3 @@
-attr-mismatch-crate-name.rs
-attr_deprecated.rs
-attr_deprecated_2.rs
-bad=file-name.rs
 bounds1.rs
 break-rust2.rs
 break-rust3.rs
@@ -45,7 +41,6 @@ generics6.rs
 generics8.rs
 generics9.rs
 if_let_expr.rs
-infer-crate-name.rs
 issue-1019.rs
 issue-1031.rs
 issue-1034.rs
@@ -156,7 +151,6 @@ redef_error6.rs
 self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
-specify-crate-name.rs
 stmt_with_block_dot.rs
 struct-expr-parse.rs
 traits1.rs
-- 
2.45.2



[COMMITTED 052/146] gccrs: improve handling of Self Type paths

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

TypePaths have special handling for Self where we can look at the current ctx
for more acurate TypeAlias information if required. We cant do this for Impl
contexts but not for Traits as we might as well fall back to the TypePathProbe.

The other issue was the dyn type comming in because Foo::foo and Foo is a trait
reference we represent this as a dyn type as the root resolved path but then 
find
the associated impl block for this but we cannot do this when we have resolved 
to
a Dyn because this is just a representation that we know we are talking about a
trait not because we are actually working with a real Dyn type.

Fixes Rust-GCC#2907

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): 
track trait
* typecheck/rust-hir-type-check-implitem.cc: trait block
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_segments): dont when dyn
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): look at 
Self contenxt
(TypeCheckType::resolve_root_path): track if Self
(TypeCheckType::resolve_associated_type): look at current context for 
associated types
* typecheck/rust-hir-type-check-type.h: change prototype
* typecheck/rust-hir-type-check.h (class TypeCheckBlockContextItem):
new context system to track current state
* typecheck/rust-typecheck-context.cc 
(TypeCheckContext::have_block_context): likewise
(TypeCheckContext::peek_block_context): likewise
(TypeCheckContext::push_block_context): likewise
(TypeCheckContext::pop_block_context): likewise
(TypeCheckBlockContextItem::Item::Item): likewise
(TypeCheckBlockContextItem::TypeCheckBlockContextItem): likewise
(TypeCheckBlockContextItem::is_impl_block): likewise
(TypeCheckBlockContextItem::is_trait_block): likewise
(TypeCheckBlockContextItem::get_impl_block): likewise
(TypeCheckBlockContextItem::get_trait): likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |   2 +
 .../typecheck/rust-hir-type-check-implitem.cc |   3 +
 .../typecheck/rust-hir-type-check-path.cc |   3 +-
 .../typecheck/rust-hir-type-check-type.cc | 195 --
 gcc/rust/typecheck/rust-hir-type-check-type.h |   9 +-
 gcc/rust/typecheck/rust-hir-type-check.h  |  38 
 gcc/rust/typecheck/rust-typecheck-context.cc  |  64 ++
 gcc/testsuite/rust/compile/issue-2907.rs  |  33 +++
 gcc/testsuite/rust/compile/nr2/exclude|   1 +
 9 files changed, 287 insertions(+), 61 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2907.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 6f2589a0d2b..2fbf123aa77 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -278,6 +278,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 }
   self->inherit_bounds (specified_bounds);
 
+  context->push_block_context (TypeCheckBlockContextItem (trait_reference));
   std::vector item_refs;
   for (auto &item : trait_reference->get_trait_items ())
 {
@@ -307,6 +308,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
   // resolve the blocks of functions etc because it can end up in a recursive
   // loop of trying to resolve traits as required by the types
   tref->on_resolved ();
+  context->pop_block_context ();
 
   return tref;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 602076811c3..5da88b890f3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -335,7 +335,10 @@ TypeCheckImplItem::Resolve (
 
   // resolve
   TypeCheckImplItem resolver (parent, self, substitutions);
+  resolver.context->push_block_context (TypeCheckBlockContextItem (&parent));
   item.accept_vis (resolver);
+  resolver.context->pop_block_context ();
+
   return resolver.result;
 }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cd0e941edd6..4746e7d730d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -355,6 +355,7 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_node_id,
   NodeId resolved_node_id = root_resolved_node_id;
   TyTy::BaseType *prev_segment = tyseg;
   bool reciever_is_generic = prev_segment->get_kind () == 
TyTy::TypeKind::PARAM;
+  bool reciever_is_dyn = prev_segment->get_kind () == TyTy::TypeKind::DYNAMIC;
 
   for (size_t i = offset; i < segments.size (); i++)
 {
@@ -434,7 +435,7 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_nod

[COMMITTED 046/146] gccrs: Clean up some system includes

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

System includes shall use rust-system header instead.

gcc/rust/ChangeLog:

* ast/rust-stmt.h: Remove stdlib include and use rust-system instead.
* backend/rust-compile-expr.cc: Likewise.
* backend/rust-mangle-legacy.cc: Likewise.
* backend/rust-mangle-v0.cc: Likewise.
* hir/rust-hir-dump.cc: Likewise.
* typecheck/rust-hir-type-check-type.cc: Likewise.
* typecheck/rust-tyty.cc: Likewise.
* typecheck/rust-tyty.h: Likewise.
* util/rust-common.h: Likewise.
* util/rust-token-converter.cc: Likewise.
* util/rust-token-converter.h: Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-stmt.h   | 2 +-
 gcc/rust/backend/rust-compile-expr.cc  | 1 -
 gcc/rust/backend/rust-mangle-legacy.cc | 1 -
 gcc/rust/backend/rust-mangle-v0.cc | 1 -
 gcc/rust/hir/rust-hir-dump.cc  | 2 +-
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 2 +-
 gcc/rust/typecheck/rust-tyty.cc| 2 +-
 gcc/rust/typecheck/rust-tyty.h | 2 --
 gcc/rust/util/rust-common.h| 1 -
 gcc/rust/util/rust-token-converter.cc  | 3 +--
 gcc/rust/util/rust-token-converter.h   | 2 +-
 11 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index e8aec34d47e..6cbecaffd03 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -22,7 +22,7 @@
 #include "rust-ast.h"
 #include "rust-path.h"
 #include "rust-expr.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace AST {
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 05c52261cf7..7ea2a675522 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -31,7 +31,6 @@
 #include "convert.h"
 #include "print-tree.h"
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-mangle-legacy.cc 
b/gcc/rust/backend/rust-mangle-legacy.cc
index 2c0ddd92df0..7671982da3f 100644
--- a/gcc/rust/backend/rust-mangle-legacy.cc
+++ b/gcc/rust/backend/rust-mangle-legacy.cc
@@ -21,7 +21,6 @@
 #include "rust-unicode.h"
 #include "rust-diagnostics.h"
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-mangle-v0.cc 
b/gcc/rust/backend/rust-mangle-v0.cc
index 67d7e4d1885..d0df4aba27c 100644
--- a/gcc/rust/backend/rust-mangle-v0.cc
+++ b/gcc/rust/backend/rust-mangle-v0.cc
@@ -25,7 +25,6 @@
 #include "rust-unicode.h"
 #include "rust-punycode.h"
 #include "rust-compile-type.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 5d2a09db348..81cb881268f 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -22,9 +22,9 @@
 #include "rust-hir-path.h"
 #include "rust-hir-type.h"
 #include "rust-hir.h"
-#include 
 #include "rust-attribute-values.h"
 #include "tree/rust-hir-expr.h"
+#include "rust-system.h"
 
 namespace Rust {
 namespace HIR {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 4ebbaf6d836..0360c5504b7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -27,7 +27,7 @@
 #include "rust-mapping-common.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace Resolver {
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 1073dfa6adc..f0c967e0949 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -32,7 +32,7 @@
 #include "rust-hir-type-bounds.h"
 
 #include "options.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace TyTy {
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 49cd00c9174..a41837e35af 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -30,8 +30,6 @@
 #include "rust-system.h"
 #include "rust-hir.h"
 
-#include 
-
 namespace Rust {
 
 namespace Resolver {
diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h
index 2033694156e..71637cee68e 100644
--- a/gcc/rust/util/rust-common.h
+++ b/gcc/rust/util/rust-common.h
@@ -21,7 +21,6 @@
 #ifndef RUST_COMMON
 #define RUST_COMMON
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 
diff --git a/gcc/rust/util/rust-token-converter.cc 
b/gcc/rust/util/rust-token-converter.cc
index 220e891247f..fc34adb9b19 100644
--- a/gcc/rust/util/rust-token-converter.cc
+++ b/gcc/rust/util/rust-token-converter.cc
@@ -18,8 +18,7 @@
 #include "rust-token-converter.h"
 #include "bi-map.h"
 #include "line-map.h"
-
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 
diff -

[COMMITTED 069/146] gccrs: Fix ForeverStack::find_starting_point output parameter

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

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::find_starting_point): Use type
'std::reference_wrapper &' instead of 'Node &' for
parameter starting_point.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Likewise.
(ForeverStack::resolve_path): Handle change to
ForeverStack::find_starting_point.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h   |  3 ++-
 gcc/rust/resolve/rust-forever-stack.hxx | 13 +++--
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index c548eeae087..064d1ab2bb3 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -614,7 +614,8 @@ private:
 
   template 
   tl::optional>
-  find_starting_point (const std::vector &segments, Node &starting_point);
+  find_starting_point (const std::vector &segments,
+  std::reference_wrapper &starting_point);
 
   template 
   tl::optional resolve_segments (Node &starting_point,
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 58164a4d328..d3d78894671 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -374,8 +374,8 @@ check_leading_kw_at_start (const S &segment, bool condition)
 template 
 template 
 tl::optional::const_iterator>
-ForeverStack::find_starting_point (const std::vector &segments,
- Node &starting_point)
+ForeverStack::find_starting_point (
+  const std::vector &segments, std::reference_wrapper &starting_point)
 {
   auto iterator = segments.begin ();
 
@@ -412,14 +412,15 @@ ForeverStack::find_starting_point (const 
std::vector &segments,
}
   if (seg.is_super_path_seg ())
{
- if (starting_point.is_root ())
+ if (starting_point.get ().is_root ())
{
  rust_error_at (seg.get_locus (), ErrorCode::E0433,
 "too many leading % keywords");
  return tl::nullopt;
}
 
- starting_point = find_closest_module (starting_point.parent.value ());
+ starting_point
+   = find_closest_module (starting_point.get ().parent.value ());
  continue;
}
 
@@ -494,12 +495,12 @@ ForeverStack::resolve_path (const std::vector 
&segments)
   if (segments.size () == 1)
 return get (segments.back ().as_string ());
 
-  auto starting_point = cursor ();
+  std::reference_wrapper starting_point = cursor ();
 
   return find_starting_point (segments, starting_point)
 .and_then ([this, &segments, &starting_point] (
 typename std::vector::const_iterator iterator) {
-  return resolve_segments (starting_point, segments, iterator);
+  return resolve_segments (starting_point.get (), segments, iterator);
 })
 .and_then ([&segments] (Node final_node) {
   return final_node.rib.get (segments.back ().as_string ());
-- 
2.45.2



[COMMITTED 054/146] gccrs: ensure packed and aligned is applied properly

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

We cannot apply aligned or packed after layout_type is called you need
to set this up first then call it.

Fixes Rust-GCC#3260

gcc/rust/ChangeLog:

* backend/rust-compile-type.cc (TyTyResolveCompile::visit): call lauout 
type directly
* rust-backend.h (struct_type): add optional layout parameter
(union_type): likewise
(fill_in_fields): likewise
* rust-gcc.cc (struct_type): likewise
(union_type): likewise
(fill_in_fields): only layout if we required

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-type.cc |  8 +---
 gcc/rust/rust-backend.h   |  6 +++---
 gcc/rust/rust-gcc.cc  | 15 +--
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 56d64e1405b..50b52fbd37f 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -22,6 +22,7 @@
 #include "rust-gcc.h"
 
 #include "tree.h"
+#include "stor-layout.h"
 
 namespace Rust {
 namespace Compile {
@@ -268,8 +269,8 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
  fields.push_back (std::move (f));
}
 
-  type_record = type.is_union () ? Backend::union_type (fields)
-: Backend::struct_type (fields);
+  type_record = type.is_union () ? Backend::union_type (fields, false)
+: Backend::struct_type (fields, false);
 }
   else
 {
@@ -359,7 +360,7 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
}
 
   // finally make the union or the enum
-  type_record = Backend::union_type (enum_fields);
+  type_record = Backend::union_type (enum_fields, false);
 }
 
   // Handle repr options
@@ -381,6 +382,7 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
   SET_TYPE_ALIGN (type_record, repr.align * 8);
   TYPE_USER_ALIGN (type_record) = 1;
 }
+  layout_type (type_record);
 
   std::string named_struct_str
 = type.get_ident ().path.get () + type.subst_as_string ();
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 9d28cf6d393..414799edefe 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -133,11 +133,11 @@ function_ptr_type (tree result, const std::vector 
&praameters,
 
 // Get a struct type.
 tree
-struct_type (const std::vector &fields);
+struct_type (const std::vector &fields, bool layout = true);
 
 // Get a union type.
 tree
-union_type (const std::vector &fields);
+union_type (const std::vector &fields, bool layout = true);
 
 // Get an array type.
 tree
@@ -496,7 +496,7 @@ write_global_definitions (const std::vector 
&type_decls,
 // TODO: make static
 
 tree
-fill_in_fields (tree, const std::vector &);
+fill_in_fields (tree, const std::vector &, bool);
 
 tree fill_in_array (tree, tree, tree);
 
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab7889b0..59983ede97d 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -592,23 +592,24 @@ function_ptr_type (tree result_type, const 
std::vector ¶meters,
 // Make a struct type.
 
 tree
-struct_type (const std::vector &fields)
+struct_type (const std::vector &fields, bool layout)
 {
-  return fill_in_fields (make_node (RECORD_TYPE), fields);
+  return fill_in_fields (make_node (RECORD_TYPE), fields, layout);
 }
 
 // Make a union type.
 
 tree
-union_type (const std::vector &fields)
+union_type (const std::vector &fields, bool layout)
 {
-  return fill_in_fields (make_node (UNION_TYPE), fields);
+  return fill_in_fields (make_node (UNION_TYPE), fields, layout);
 }
 
 // Fill in the fields of a struct or union type.
 
 tree
-fill_in_fields (tree fill, const std::vector &fields)
+fill_in_fields (tree fill, const std::vector &fields,
+   bool layout)
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
@@ -625,7 +626,9 @@ fill_in_fields (tree fill, const 
std::vector &fields)
   pp = &DECL_CHAIN (field);
 }
   TYPE_FIELDS (fill) = field_trees;
-  layout_type (fill);
+
+  if (layout)
+layout_type (fill);
 
   // Because Rust permits converting between named struct types and
   // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
-- 
2.45.2



Re: [PATCH 3/3] libstdc++: Fix localized %c formatting for non-UTC times [PR117214]

2025-03-21 Thread Jonathan Wakely
On Fri, 21 Mar 2025 at 12:24, Tomasz Kaminski  wrote:
>
>
>
> On Thu, Mar 20, 2025 at 10:39 AM Jonathan Wakely  wrote:
>>
>> The previous commit fixed most cases of %c formatting, but it
>> incorrectly prints times using the system's local time zone. This only
>> matters if the locale's %c format includes %Z, but some do.
>>
>> To print a correct value for %Z we can set tm.tm_zone to either "UTC" or
>> the abbreviation passed to the formatter in the local-time-format-t
>> structure.
>>
>> For local times with no info and for systems that don't support tm_zone
>> (which is new in POSIX.1-2024) we just set tm_isdst = -1 so that no zone
>> name is printed.
>>
>> In theory, a locale's %c format could use %z which should print a +hhmm
>> offset from UTC. I'm unsure how to control that though. The new
>> tm_gmtoff field in combination with tm_isdst != -1 seems like it should
>> work, but using that without also setting tm_zone causes the system zone
>> to be used for %Z again. That means local_time_format(lt, nullptr, &off)
>> might work for a locale that uses %z but prints the wrong thing for %Z.
>> This commit doesn't set tm_gmtoff even if _M_offset_sec is provided for
>> a local-time-format-t value.
>>
>> libstdc++-v3/ChangeLog:
>>
>> PR libstdc++/117214
>> * configure.ac: Use AC_STRUCT_TIMEZONE.
>> * config.h.in: Regenerate.
>> * configure: Regenerate.
>> * include/bits/chrono_io.h (__formatter_chrono::_M_c): Set
>> tm_isdst and tm_zone.
>> * testsuite/std/time/format/pr117214.cc: Check %c formatting of
>> zoned_time and local time.
>> ---
>>
>> Tested x86_64-linux.
>
> The c++ code parts LGTM, however the changes in config.h.in and
> configure went over my head: they seem to check for new members,
> but I cannot confirm if they are correct and according to best practices.

It's all generated by autoconf. The only change is adding
AC_STRUCT_TIMEZONE to configure.ac which is documented at
https://www.gnu.org/software/autoconf/manual/autoconf-2.64/html_node/Particular-Structures.html#Particular-Structures
The rest is just what autoconf generates from that, and so doesn't
need to be reviewed.


>> diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
>> index a3b257fe652..fe0cdde1f7a 100644
>> --- a/libstdc++-v3/configure.ac
>> +++ b/libstdc++-v3/configure.ac
>> @@ -584,6 +584,8 @@ GLIBCXX_CHECK_FILEBUF_NATIVE_HANDLES
>>  # For std::text_encoding
>>  GLIBCXX_CHECK_TEXT_ENCODING
>>
>> +AC_STRUCT_TIMEZONE
>> +
>>  # Define documentation rules conditionally.
>>
>>  # See if makeinfo has been installed and is modern enough
>> diff --git a/libstdc++-v3/include/bits/chrono_io.h 
>> b/libstdc++-v3/include/bits/chrono_io.h
>> index 86338d48d18..08969166d2f 100644
>> --- a/libstdc++-v3/include/bits/chrono_io.h
>> +++ b/libstdc++-v3/include/bits/chrono_io.h
>> @@ -894,13 +894,42 @@ namespace __format
>>   // %Ec Locale's alternate date and time representation.
>>
>>   using namespace chrono;
>> + using ::std::chrono::__detail::__utc_leap_second;
>> + using ::std::chrono::__detail::__local_time_fmt;
>> +
>> + struct tm __tm{};
>> +
>> + // Some locales use %Z in their %c format but we don't want 
>> strftime
>> + // to use the system's local time zone (from /etc/localtime or $TZ)
>> + // as the output for %Z. Setting tm_isdst to -1 says there is no
>> + // time zone info available for the time in __tm.
>> + __tm.tm_isdst = -1;
>> +
>> +#ifdef _GLIBCXX_HAVE_STRUCT_TM_TM_ZONE
>> + // POSIX.1-2024 adds tm.tm_zone which will be used for %Z.
>> + if constexpr (__is_time_point_v<_Tp>)
>> +   {
>> + // One of sys_time, utc_time, or local_time.
>> + if constexpr (!is_same_v)
>> +   __tm.tm_zone = "UTC";
>
> I have checked that other clocks, like TAI and GPS that user different zone 
> name,
> are formatted using __local_time_fmt.

Thanks!

>>
>> +   }
>> + else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>)
>> +   {
>> + // local-time-format-t is used to provide time zone info for
>> + // one of zoned_time, tai_time, gps_time, or local_time.
>> + if (__t._M_abbrev)
>> +   __tm.tm_zone = __t._M_abbrev->c_str();
>> +   }
>> + else
>> +   __tm.tm_zone = "UTC";
>> +#endif
>> +
>>   auto __d = _S_days(__t); // Either sys_days or local_days.
>>   using _TDays = decltype(__d);
>>   const year_month_day __ymd(__d);
>>   const auto __y = __ymd.year();
>>   const auto __hms = _S_hms(__t);
>>
>> - struct tm __tm{};
>>   __tm.tm_year = (int)__y - 1900;
>>   __tm.tm_yday = (__d - _TDays(__y/January/1)).count();
>>   __tm.tm_mon = (unsigned)__ymd.month() - 1;
>> @@ -909,6 +938,7 @@ namespace __format
>>   __tm.tm_hour = __hms.hours().count();
>

[COMMITTED 064/146] gccrs: fix crash in hir dump

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

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): add missing check for no return 
value

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index be785b9ebec..2590eed19ae 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1365,7 +1365,8 @@ Dump::visit (ReturnExpr &e)
   begin ("ReturnExpr");
   do_mappings (e.get_mappings ());
 
-  visit_field ("return_expr", e.get_expr ());
+  if (e.has_return_expr ())
+visit_field ("return_expr", e.get_expr ());
 
   end ("ReturnExpr");
 }
-- 
2.45.2



[COMMITTED 063/146] gccrs: add test case to show issue is fixed

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

Fixes Rust-GCC#266

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/testsuite/rust/compile/issue-266.rs | 3 +++
 gcc/testsuite/rust/compile/nr2/exclude  | 1 +
 2 files changed, 4 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-266.rs

diff --git a/gcc/testsuite/rust/compile/issue-266.rs 
b/gcc/testsuite/rust/compile/issue-266.rs
new file mode 100644
index 000..11196cb7d73
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-266.rs
@@ -0,0 +1,3 @@
+fn main() {
+'label: while break 'label {}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index bf4506f25d2..797e59a5c58 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -207,4 +207,5 @@ issue-2905-1.rs
 issue-2905-2.rs
 issue-2907.rs
 issue-2423.rs
+issue-266.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 048/146] gccrs: empty match expressions should resolve to !

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

This is a special case in Rust and the ! type can unify with pretty much
anything its almost a inference variable and a unit-type for special cases.

Fixes Rust-GCC/gccrs#3231
Fixes Rust-GCC/gccrs#2567

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (check_match_scrutinee): check for empty 
match
(CompileExpr::visit): fix assertion
* checks/errors/rust-hir-pattern-analysis.cc (check_match_usefulness): 
check for empty
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): resolve 
to !

gcc/testsuite/ChangeLog:

* rust/compile/exhaustiveness1.rs: remove bad check
* rust/compile/issue-2567-1.rs: New test.
* rust/compile/issue-2567-2.rs: New test.
* rust/compile/issue-2567-3.rs: New test.
* rust/compile/issue-3231.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc | 21 +--
 .../errors/rust-hir-pattern-analysis.cc   |  3 +++
 .../typecheck/rust-hir-type-check-expr.cc | 12 +++
 gcc/testsuite/rust/compile/exhaustiveness1.rs |  4 +---
 gcc/testsuite/rust/compile/issue-2567-1.rs|  8 +++
 gcc/testsuite/rust/compile/issue-2567-2.rs|  8 +++
 gcc/testsuite/rust/compile/issue-2567-3.rs|  8 +++
 gcc/testsuite/rust/compile/issue-3231.rs  |  8 +++
 8 files changed, 58 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2567-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2567-2.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2567-3.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3231.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 7ea2a675522..e0fb1da3feb 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1013,17 +1013,7 @@ check_match_scrutinee (HIR::MatchExpr &expr, Context 
*ctx)
   || scrutinee_kind == TyTy::TypeKind::TUPLE
   || scrutinee_kind == TyTy::TypeKind::REF);
 
-  if (scrutinee_kind == TyTy::TypeKind::ADT)
-{
-  // this will need to change but for now the first pass implementation,
-  // lets assert this is the case
-  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)
+  if (scrutinee_kind == TyTy::TypeKind::FLOAT)
 {
   // FIXME: CASE_LABEL_EXPR does not support floating point types.
   // Find another way to compile these.
@@ -1064,6 +1054,15 @@ CompileExpr::visit (HIR::MatchExpr &expr)
   return;
 }
 
+  // if the result of this expression is meant to be never type then we can
+  // optimise this away but there is the case where match arms resolve to !
+  // because of return statements we need to special case this
+  if (!expr.has_match_arms () && expr_tyty->is ())
+{
+  translated = unit_expression (expr.get_locus ());
+  return;
+}
+
   fncontext fnctx = ctx->peek_fn ();
   Bvariable *tmp = NULL;
   tree enclosing_scope = ctx->peek_enclosing_scope ();
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 617d754c181..db1e7272556 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -1530,6 +1530,9 @@ void
 check_match_usefulness (Resolver::TypeCheckContext *ctx,
TyTy::BaseType *scrutinee_ty, HIR::MatchExpr &expr)
 {
+  if (!expr.has_match_arms ())
+return;
+
   // Lower the arms to a more convenient representation.
   std::vector rows;
   for (auto &arm : expr.get_match_cases ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 03922bb554c..5a96c359d7c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1456,6 +1456,18 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
   TyTy::BaseType *scrutinee_tyty
 = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ());
 
+  // https://github.com/Rust-GCC/gccrs/issues/3231#issuecomment-2462660048
+  // 
https://github.com/rust-lang/rust/blob/3d1dba830a564d1118361345d7ada47a05241f45/compiler/rustc_hir_typeck/src/_match.rs#L32-L36
+  if (!expr.has_match_arms ())
+{
+  // this is a special case where rustc returns !
+  TyTy::BaseType *lookup = nullptr;
+  bool ok = context->lookup_builtin ("!", &lookup);
+  rust_assert (ok);
+  infered = lookup->clone ();
+  return;
+}
+
   bool saw_error = false;
   std::vector kase_block_tys;
   for (auto &kase : expr.get_match_cases ())
diff --git a/gcc/testsuite/rust/compile/exhaustiveness1.rs 
b/gcc/testsuite/rust/compile/exhaustiveness1.rs
ind

[COMMITTED 094/146] gccrs: lower: Correctly lower parenthesized types

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

This is useful for handling multiple trait bounds, and required for better 
handling of auto traits.

gcc/rust/ChangeLog:

* hir/rust-ast-lower-type.cc (ASTLoweringType::visit): Add 
implementation for
ParenthesizedType.
* hir/rust-ast-lower-type.h: Declare that new visitor.

gcc/testsuite/ChangeLog:

* rust/compile/auto_traits1.rs: New test.
---
 gcc/rust/hir/rust-ast-lower-type.cc| 19 +++
 gcc/rust/hir/rust-ast-lower-type.h |  2 ++
 gcc/testsuite/rust/compile/auto_traits1.rs | 27 ++
 3 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/auto_traits1.rs

diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index df06e48b801..d1f95edc345 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -19,6 +19,7 @@
 #include "rust-ast-lower-type.h"
 #include "rust-hir-map.h"
 #include "rust-hir-path.h"
+#include "rust-hir-type.h"
 #include "rust-path.h"
 #include "rust-pattern.h"
 
@@ -471,6 +472,24 @@ ASTLoweringType::visit (AST::TraitObjectType &type)
 type.get_locus (), type.is_dyn ());
 }
 
+void
+ASTLoweringType::visit (AST::ParenthesisedType &type)
+{
+  auto *inner = ASTLoweringType::translate (*type.get_type_in_parens (),
+   default_to_static_lifetime);
+
+  auto crate_num = mappings.get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+mappings.get_next_hir_id (crate_num),
+mappings.get_next_localdef_id (crate_num));
+
+  // FIXME: Do we actually need to know if a type is parenthesized in the HIR?
+  // or can we just use the type in parens?
+  translated
+= new HIR::ParenthesisedType (mapping, std::unique_ptr (inner),
+ type.get_locus ());
+}
+
 HIR::GenericParam *
 ASTLowerGenericParam::translate (AST::GenericParam ¶m)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-type.h 
b/gcc/rust/hir/rust-ast-lower-type.h
index 0429e3fcf98..26ca8684083 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -22,6 +22,7 @@
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-expr.h"
 #include "rust-hir-path.h"
+#include "rust-type.h"
 
 namespace Rust {
 namespace HIR {
@@ -83,6 +84,7 @@ public:
   void visit (AST::NeverType &type) override;
   void visit (AST::TraitObjectTypeOneBound &type) override;
   void visit (AST::TraitObjectType &type) override;
+  void visit (AST::ParenthesisedType &type) override;
 
 private:
   ASTLoweringType (bool default_to_static_lifetime)
diff --git a/gcc/testsuite/rust/compile/auto_traits1.rs 
b/gcc/testsuite/rust/compile/auto_traits1.rs
new file mode 100644
index 000..192052d4815
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits1.rs
@@ -0,0 +1,27 @@
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+a.a_method();
+}
+
+struct S;
+
+impl A for S {
+fn a_method(&self) {}
+}
+
+fn main() {
+let s = S;
+
+foo(&s);
+}
-- 
2.45.2



[COMMITTED 091/146] gccrs: nr2.0: Handle "Self" properly in trait definitions

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

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Visit implicit Self parameters of
traits.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Resolve implicit Self parameters of traits.
* resolve/rust-late-name-resolver-2.0.h:
(Late::visit): Add trait visitor.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Insert resolutions for Self type parameters
as well.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index a390aa20bcb..32e8025e9b2 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -997,6 +997,8 @@ DefaultASTVisitor::visit (AST::Trait &trait)
 
   visit_inner_attrs (trait);
 
+  visit (trait.get_implicit_self ());
+
   for (auto &generic : trait.get_generic_params ())
 visit (generic);
 
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 38515cdc0fd..86fd5f12173 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -288,6 +288,19 @@ Late::visit (AST::TypePath &type)
   DefaultResolver::visit (type);
 }
 
+void
+Late::visit (AST::Trait &trait)
+{
+  // kind of weird how this is done
+  // names are resolved to the node id of trait.get_implicit_self ()
+  // which is then resolved to the node id of trait
+  // we set up the latter mapping here
+  ctx.map_usage (Usage (trait.get_implicit_self ().get_node_id ()),
+Definition (trait.get_node_id ()));
+
+  DefaultResolver::visit (trait);
+}
+
 void
 Late::visit (AST::StructStruct &s)
 {
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 1dbca3648da..803a5ec1c00 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -48,6 +48,7 @@ public:
   void visit (AST::PathInExpression &) override;
   void visit (AST::LangItemPath &) override;
   void visit (AST::TypePath &) override;
+  void visit (AST::Trait &) override;
   void visit (AST::StructExprStruct &) override;
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index a76c098f2df..6d52fcaaac8 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -280,11 +280,8 @@ TopLevel::visit (AST::StructStruct &struct_item)
 void
 TopLevel::visit (AST::TypeParam &type_param)
 {
-  // Hacky and weird, find a better solution
-  // We should probably not even insert self in the first place ?
-  if (type_param.get_type_representation ().as_string () != "Self")
-insert_or_error_out (type_param.get_type_representation (), type_param,
-Namespace::Types);
+  insert_or_error_out (type_param.get_type_representation (), type_param,
+  Namespace::Types);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 8bdcc8ac338..2a5bc94b646 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -79,7 +79,6 @@ issue-2190-2.rs
 issue-2238.rs
 issue-2304.rs
 issue-2330.rs
-issue-2375.rs
 issue-2478.rs
 issue-2479.rs
 issue-2723-1.rs
@@ -182,7 +181,6 @@ issue-2987.rs
 issue-3045-1.rs
 issue-3045-2.rs
 issue-3046.rs
-unknown-associated-item.rs
 issue-3030.rs
 issue-3035.rs
 issue-3139-1.rs
-- 
2.45.2



[COMMITTED 106/146] gccrs: Allow float type to be casted as integer type

2025-03-21 Thread arthur . cohen
From: Nobel 

gccrs now should be able to cast float types as numeric.

gcc/rust/ChangeLog:

* typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Nobel Singh 
---
 gcc/rust/typecheck/rust-casts.cc|  6 ++
 gcc/testsuite/rust/compile/cast_float_as_integer.rs | 10 ++
 2 files changed, 16 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/cast_float_as_integer.rs

diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index 694cbaa5db6..90bdef1fd3c 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -235,6 +235,12 @@ TypeCastRules::cast_rules ()
 case TyTy::TypeKind::FLOAT:
   switch (to.get_ty ()->get_kind ())
{
+   case TyTy::TypeKind::USIZE:
+   case TyTy::TypeKind::ISIZE:
+   case TyTy::TypeKind::UINT:
+   case TyTy::TypeKind::INT:
+ return TypeCoercionRules::CoercionResult{{}, to.get_ty ()->clone ()};
+
case TyTy::TypeKind::FLOAT:
  return TypeCoercionRules::CoercionResult{{}, to.get_ty ()->clone ()};
 
diff --git a/gcc/testsuite/rust/compile/cast_float_as_integer.rs 
b/gcc/testsuite/rust/compile/cast_float_as_integer.rs
new file mode 100644
index 000..e6b86db8a66
--- /dev/null
+++ b/gcc/testsuite/rust/compile/cast_float_as_integer.rs
@@ -0,0 +1,10 @@
+// { dg-options "-w" }
+fn main(){
+let foo:f64 = 13.37;
+let _ = foo as i64;
+let _ = foo as u64;
+let _ = foo as isize;
+let _ = foo as usize;
+let _ = foo as i8;
+let _ = foo as u8;
+}
-- 
2.45.2



[COMMITTED 062/146] gccrs: add checks for division by zero and left shift overflow

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

These are ported from the c-family code c-warn.cc and c/c-typchk.cc

Fixes Rust-GCC#2394

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_store_expression): check for null
(eval_call_expression): remove bad warning
* rust-gcc.cc (arithmetic_or_logical_expression): add warnings

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-constexpr.cc   |  8 +---
 gcc/rust/rust-gcc.cc | 11 +++
 gcc/testsuite/rust/compile/issue-2394.rs | 14 ++
 3 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2394.rs

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index bfd7d959aa8..2f2bbbd921d 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2929,8 +2929,13 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
}
 }
 
+  if (*non_constant_p)
+return t;
+
   /* Don't share a CONSTRUCTOR that might be changed later.  */
   init = unshare_constructor (init);
+  if (init == NULL_TREE)
+return t;
 
   if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
   && TREE_CODE (init) == CONSTRUCTOR)
@@ -3585,9 +3590,6 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
  result = *ctx->global->values.get (res);
  if (result == NULL_TREE && !*non_constant_p)
{
- if (!ctx->quiet)
-   error ("% call flows off the end "
-  "of the function");
  *non_constant_p = true;
}
}
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 59983ede97d..7da5e2c5637 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1106,6 +1106,17 @@ arithmetic_or_logical_expression 
(ArithmeticOrLogicalOperator op, tree left,
   if (floating_point && extended_type != NULL_TREE)
 ret = convert (original_type, ret);
 
+  if (op == ArithmeticOrLogicalOperator::DIVIDE
+  && (integer_zerop (right) || fixed_zerop (right)))
+{
+  rust_error_at (location, "division by zero");
+}
+  else if (op == ArithmeticOrLogicalOperator::LEFT_SHIFT
+  && (compare_tree_int (right, TYPE_PRECISION (TREE_TYPE (ret))) >= 0))
+{
+  rust_error_at (location, "left shift count >= width of type");
+}
+
   return ret;
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-2394.rs 
b/gcc/testsuite/rust/compile/issue-2394.rs
new file mode 100644
index 000..92f7afc6507
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2394.rs
@@ -0,0 +1,14 @@
+const A: i32 = (1 / 0);
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+fn main() {
+let a = 1 / 0;
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+let b = 3;
+let c = b / 0;
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+let a = 1 << 500;
+// { dg-error "left shift count >= width of type" "" { target *-*-* } .-1 }
+}
-- 
2.45.2



[COMMITTED 124/146] gccrs: ast: Refactor how lang item paths are handled.

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

Lang item typepaths were not handled properly, and required a complete overhaul.
All old classes that concerned lang item paths are now modified to use a simpler
version of `AST::LangItemPath`, which has been removed. TypePath segments can 
now
be lang items, as this is requied for having generic lang item paths such as
PhantomData.

gcc/rust/ChangeLog:

* ast/rust-path.h: Rework how lang item paths are represented.
* ast/rust-path.cc: Likewise.
* ast/rust-item.h: Likewise.
* ast/rust-ast.cc: Likewise.
* ast/rust-ast-collector.cc: Adapt to new lang item path system.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h: Likewise.
* expand/rust-derive-copy.cc: Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Likewise.
(ASTLowerTypePath::visit): Likewise.
* hir/rust-ast-lower-type.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise.
* resolve/rust-ast-resolve-type.h: Likewise.
* resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): 
Likewise.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
* resolve/rust-late-name-resolver-2.0.h: Likewise.
* hir/tree/rust-hir-path.cc (TypePathSegment::TypePathSegment): 
Likewise.
(TypePathSegmentGeneric::TypePathSegmentGeneric): Likewise.
* hir/tree/rust-hir-path.h: Likewise.
* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path): Likewise.
* ast/rust-ast-builder.cc: Likewise.
* ast/rust-ast-builder.h: Likewise.
---
 gcc/rust/ast/rust-ast-builder.cc  |  20 +-
 gcc/rust/ast/rust-ast-builder.h   |   4 -
 gcc/rust/ast/rust-ast-collector.cc|  13 -
 gcc/rust/ast/rust-ast-collector.h |   2 -
 gcc/rust/ast/rust-ast-visitor.cc  |  11 -
 gcc/rust/ast/rust-ast-visitor.h   |   4 -
 gcc/rust/ast/rust-ast.cc  |   4 +-
 gcc/rust/ast/rust-item.h  |  40 +-
 gcc/rust/ast/rust-path.cc |  31 +-
 gcc/rust/ast/rust-path.h  | 405 +++---
 gcc/rust/expand/rust-derive-copy.cc   |   4 +-
 gcc/rust/expand/rust-derive.h |   2 -
 gcc/rust/hir/rust-ast-lower-base.cc   |   6 -
 gcc/rust/hir/rust-ast-lower-base.h|   2 -
 gcc/rust/hir/rust-ast-lower-type.cc   |  75 ++--
 gcc/rust/hir/rust-ast-lower-type.h|   6 +-
 gcc/rust/hir/tree/rust-hir-path.cc|  21 +-
 gcc/rust/hir/tree/rust-hir-path.h |  38 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc |   8 -
 gcc/rust/resolve/rust-ast-resolve-base.h  |   2 -
 gcc/rust/resolve/rust-ast-resolve-item.cc |  27 +-
 gcc/rust/resolve/rust-ast-resolve-type.cc |  79 ++--
 gcc/rust/resolve/rust-ast-resolve-type.h  |  31 --
 .../resolve/rust-late-name-resolver-2.0.cc|  19 -
 .../resolve/rust-late-name-resolver-2.0.h |   1 -
 .../typecheck/rust-hir-type-check-type.cc |   2 +-
 26 files changed, 311 insertions(+), 546 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 22fb0d83f97..f6d0f0dc4ae 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -42,15 +42,6 @@ Builder::call (std::unique_ptr &&path,
 new CallExpr (std::move (path), std::move (args), {}, loc));
 }
 
-std::unique_ptr
-Builder::call (std::unique_ptr &&path,
-  std::vector> &&args) const
-{
-  return call (std::unique_ptr (
-new PathInExpression (std::move (path), {}, loc)),
-  std::move (args));
-}
-
 std::unique_ptr
 Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
 {
@@ -60,15 +51,6 @@ Builder::call (std::unique_ptr &&path, 
std::unique_ptr &&arg) const
   return call (std::move (path), std::move (args));
 }
 
-std::unique_ptr
-Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
-{
-  auto args = std::vector> ();
-  args.emplace_back (std::move (arg));
-
-  return call (std::move (path), std::move (args));
-}
-
 std::unique_ptr
 Builder::array (std::vector> &&members) const
 {
@@ -242,7 +224,7 @@ Builder::wildcard () const
 std::unique_ptr
 Builder::lang_item_path (LangItem::Kind kind) const
 {
-  return std::unique_ptr (new LangItemPath (kind, loc));
+  return std::unique_ptr (new PathInExpression (kind, {}, loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 

Re: [Fortran, Patch, PR119380, v1] Fix freeing procedure pointers in components

2025-03-21 Thread Andre Vehreschild
Hi Paul,

well, I had those might complicated patches bit my mightily. So let's hope for
the best :-)

Thanks for the review. Committed with your proposed change in the testcase as
gcc-15-8642-ga5c69abf138

Thanks again,
Andre

On Fri, 21 Mar 2025 10:40:11 +
Paul Richard Thomas  wrote:

> Hi Andre,
>
> Gosh, that's a mighty complicated patch :-) I suggest changing the comment
> in the test case:
>
> s/Check that components of procedure pointer aren't freeed./Do not free
> procedure pointer components/ or some such.
>
> OK for mainline and, I propose, 14-branch.
>
> Regards and thanks
>
> Paul
>
>
> On Fri, 21 Mar 2025 at 09:38, Andre Vehreschild  wrote:
>
> > Hi all,
> >
> > attached patch fixes freeing of procedure pointers that are stored in a
> > derived
> > type's component. GFortran did that already for polymorphic types but
> > missed
> > out on the others.
> >
> > Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
> >
> > Regards,
> > Andre
> > --
> > Andre Vehreschild * Email: vehre ad gmx dot de
> >


--
Andre Vehreschild * Email: vehre ad gmx dot de


[COMMITTED 097/146] gccrs: ast: Add new Kind enums for more precise downcasting

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

This commit adds things like Item::Kind, Expr::Kind, etc, and implements the 
associated `get_*_kind` functions.
It also removes the more generic AST::Kind enum we were using, which was 
incomplete and painful to use.

gcc/rust/ChangeLog:

* ast/rust-ast.h: Add new Kind enums, remove Node class.
* ast/rust-builtin-ast-nodes.h: Use new Kind enums.
* ast/rust-expr.h (class LoopLabel): Likewise.
* ast/rust-item.h: Likewise.
* ast/rust-macro.h: Likewise.
* ast/rust-path.h: Likewise.
* expand/rust-macro-builtins-helpers.cc: Likewise.
* expand/rust-macro-builtins-utility.cc (MacroBuiltin::concat_handler): 
Likewise.
(MacroBuiltin::stringify_handler): Likewise.
* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
* resolve/rust-early-name-resolver.cc: Likewise.
* hir/rust-ast-lower.cc (ASTLoweringBlock::visit): Likewise.
---
 gcc/rust/ast/rust-ast.h   | 94 +--
 gcc/rust/ast/rust-builtin-ast-nodes.h |  2 +
 gcc/rust/ast/rust-expr.h  | 84 -
 gcc/rust/ast/rust-item.h  | 36 ++-
 gcc/rust/ast/rust-macro.h | 34 ---
 gcc/rust/ast/rust-path.h  | 10 ++
 .../expand/rust-macro-builtins-helpers.cc |  2 +-
 .../expand/rust-macro-builtins-utility.cc |  4 +-
 gcc/rust/hir/rust-ast-lower.cc|  6 +-
 gcc/rust/resolve/rust-ast-resolve-expr.cc |  2 +-
 gcc/rust/resolve/rust-early-name-resolver.cc  | 10 +-
 11 files changed, 229 insertions(+), 55 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 42ad0119231..5e724d184de 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -70,16 +70,6 @@ namespace AST {
 class ASTVisitor;
 using AttrVec = std::vector;
 
-// The available kinds of AST Nodes
-enum class Kind
-{
-  UNKNOWN,
-  MODULE,
-  MACRO_RULES_DEFINITION,
-  MACRO_INVOCATION,
-  IDENTIFIER,
-};
-
 class Visitable
 {
 public:
@@ -87,20 +77,6 @@ public:
   virtual void accept_vis (ASTVisitor &vis) = 0;
 };
 
-// Abstract base class for all AST elements
-class Node : public Visitable
-{
-public:
-  /**
-   * Get the kind of Node this is. This is used to differentiate various AST
-   * elements with very little overhead when extracting the derived type
-   * through static casting is not necessary.
-   */
-  // FIXME: Mark this as `= 0` in the future to make sure every node
-  // implements it
-  virtual Kind get_ast_kind () const { return Kind::UNKNOWN; }
-};
-
 // Delimiter types - used in macros and whatever.
 enum DelimType
 {
@@ -1092,7 +1068,7 @@ class MetaListNameValueStr;
 /* Base statement abstract class. Note that most "statements" are not allowed
  * in top-level module scope - only a subclass of statements called "items"
  * are. */
-class Stmt : public Node
+class Stmt : public Visitable
 {
 public:
   enum class Kind
@@ -1141,6 +1117,28 @@ protected:
 class Item : public Stmt
 {
 public:
+  enum class Kind
+  {
+MacroRulesDefinition,
+MacroInvocation,
+Module,
+ExternCrate,
+UseDeclaration,
+Function,
+TypeAlias,
+Struct,
+EnumItem,
+Enum,
+Union,
+ConstantItem,
+StaticItem,
+Trait,
+Impl,
+ExternBlock,
+  };
+
+  virtual Kind get_item_kind () const = 0;
+
   // Unique pointer custom clone function
   std::unique_ptr clone_item () const
   {
@@ -1221,14 +1219,54 @@ public:
   {
 return outer_attrs;
   }
+
+  virtual Item::Kind get_item_kind () const override = 0;
 };
+
 // forward decl of ExprWithoutBlock
 class ExprWithoutBlock;
 
 // Base expression AST node - abstract
-class Expr : public Node
+class Expr : public Visitable
 {
 public:
+  enum class Kind
+  {
+PathInExpression,
+QualifiedPathInExpression,
+Literal,
+Operator,
+Grouped,
+Array,
+ArrayIndex,
+Tuple,
+TupleIndex,
+Struct,
+Call,
+MethodCall,
+FieldAccess,
+Closure,
+Block,
+Continue,
+Break,
+Range,
+Box,
+Return,
+UnsafeBlock,
+Loop,
+If,
+IfLet,
+Match,
+Await,
+AsyncBlock,
+InlineAsm,
+Identifier,
+FormatArgs,
+MacroInvocation,
+  };
+
+  virtual Kind get_expr_kind () const = 0;
+
   // Unique pointer custom clone function
   std::unique_ptr clone_expr () const
   {
@@ -1343,7 +1381,7 @@ public:
 outer_attrs = std::move (new_attrs);
   }
 
-  Kind get_ast_kind () const override { return Kind::IDENTIFIER; }
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
 
 protected:
   // Clone method implementation
@@ -1410,7 +1448,7 @@ protected:
 class TraitBound;
 
 // Base class for types as represented in AST - abstract
-class Type : public Node
+class Type : public Visitable
 {
 public:
   // Unique pointer custom clone function
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc

[COMMITTED 068/146] gccrs: type-check: Remove unused capture in nr2.0

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

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path):
Remove unused capture in lambda.
---
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 89ede4e3013..e9859a71f83 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -19,6 +19,7 @@
 #include "rust-hir-type-check-type.h"
 #include "options.h"
 #include "optional.h"
+#include "rust-hir-map.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-path-probe.h"
@@ -394,11 +395,10 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, 
size_t *offset,
{
  auto nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
  // assign the ref_node_id if we've found something
  nr_ctx.lookup (path.get_mappings ().get_nodeid ())
-   .map ([&ref_node_id, &path] (NodeId resolved) {
- ref_node_id = resolved;
-   });
+   .map ([&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
}
   else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
-- 
2.45.2



[COMMITTED 075/146] gccrs: nr2.0: Resolve lang item paths properly.

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): New.
* resolve/rust-late-name-resolver-2.0.h: New.
---
 .../resolve/rust-late-name-resolver-2.0.cc| 20 +++
 .../resolve/rust-late-name-resolver-2.0.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 3af8496288d..ac5f1c57546 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -18,6 +18,7 @@
 
 #include "optional.h"
 #include "rust-ast-full.h"
+#include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-late-name-resolver-2.0.h"
 #include "rust-default-resolver.h"
@@ -247,6 +248,25 @@ Late::visit (AST::PathInExpression &expr)
 Definition (resolved->get_node_id ()));
 }
 
+void
+Late::visit (AST::LangItemPath &type)
+{
+  auto &mappings = Rust::Analysis::Mappings::get ();
+  auto lang_item = mappings.lookup_lang_item_node (type.get_lang_item_kind ());
+
+  if (!lang_item)
+{
+  rust_fatal_error (
+   type.get_locus (), "use of undeclared lang item %qs",
+   LangItem::ToString (type.get_lang_item_kind ()).c_str ());
+  return;
+}
+
+  ctx.map_usage (Usage (type.get_node_id ()), Definition (lang_item.value ()));
+
+  DefaultResolver::visit (type);
+}
+
 void
 Late::visit (AST::TypePath &type)
 {
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 79572fbc4fa..6f1191662cc 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -46,6 +46,7 @@ public:
   // resolutions
   void visit (AST::IdentifierExpr &) override;
   void visit (AST::PathInExpression &) override;
+  void visit (AST::LangItemPath &) override;
   void visit (AST::TypePath &) override;
   void visit (AST::StructExprStruct &) override;
   void visit (AST::StructExprStructBase &) override;
-- 
2.45.2



Re: [PATCH] opcodes: fix wrong code in expand_binop_directly [PR117811]

2025-03-21 Thread Richard Biener
On Fri, 21 Mar 2025, Richard Earnshaw wrote:

> If expand_binop_directly fails to add a REG_EQUAL note it tries to
> unwind and restart.  But it can unwind too far if expand_binop changed
> some of the operands before calling it.  We don't need to unwind that
> far anyway since we should end up taking exactly the same route next
> time, just without a target rtx.
> 
> To fix this we remove LAST from the argument list and let the callers
> (all in expand_binop) do their own unwinding if the call fails.
> Instead we unwind just as far as the entry to expand_binop_directly
> and recurse within this function instead of all the way back up.

This looks good and like a nice cleanup as well.  But please give
others more familiar with this code the chance to chime in.

Thanks,
Richard.

> gcc/ChangeLog:
> 
>   PR middle-end/117811
>   * optabs.cc (expand_binop_directly): Remove LAST as an argument,
>   instead record the last insn on entry.  Only delete insns if
>   we need to restart and restart by calling ourself, not expand_binop.
>   (expand_binop): Update callers to expand_binop_directly.  If it
>   fails to expand the operation, delete back to LAST.
> 
> gcc/testsuite:
> 
>   PR middle-end/117811
>   * gcc.dg/torture/pr117811.c: New test.
> ---
>  gcc/optabs.cc   | 24 +++---
>  gcc/testsuite/gcc.dg/torture/pr117811.c | 27 +
>  2 files changed, 39 insertions(+), 12 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/torture/pr117811.c
> 
> diff --git a/gcc/optabs.cc b/gcc/optabs.cc
> index 36f2e6af8b5..0a14b1eef8a 100644
> --- a/gcc/optabs.cc
> +++ b/gcc/optabs.cc
> @@ -1369,8 +1369,7 @@ avoid_expensive_constant (machine_mode mode, optab 
> binoptab,
>  static rtx
>  expand_binop_directly (enum insn_code icode, machine_mode mode, optab 
> binoptab,
>  rtx op0, rtx op1,
> -rtx target, int unsignedp, enum optab_methods methods,
> -rtx_insn *last)
> +rtx target, int unsignedp, enum optab_methods methods)
>  {
>machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
>machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
> @@ -1380,6 +1379,7 @@ expand_binop_directly (enum insn_code icode, 
> machine_mode mode, optab binoptab,
>rtx_insn *pat;
>rtx xop0 = op0, xop1 = op1;
>bool canonicalize_op1 = false;
> +  rtx_insn *last = get_last_insn ();
>  
>/* If it is a commutative operator and the modes would match
>   if we would swap the operands, we can save the conversions.  */
> @@ -1444,10 +1444,7 @@ expand_binop_directly (enum insn_code icode, 
> machine_mode mode, optab binoptab,
>tmp_mode = insn_data[(int) icode].operand[0].mode;
>if (VECTOR_MODE_P (mode)
> && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
> - {
> -   delete_insns_since (last);
> -   return NULL_RTX;
> - }
> + return NULL_RTX;
>  }
>else
>  tmp_mode = mode;
> @@ -1467,14 +1464,14 @@ expand_binop_directly (enum insn_code icode, 
> machine_mode mode, optab binoptab,
>  ops[1].value, ops[2].value, mode0))
>   {
> delete_insns_since (last);
> -   return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
> -unsignedp, methods);
> +   return expand_binop_directly (icode, mode, binoptab, op0, op1,
> + NULL_RTX, unsignedp, methods);
>   }
>  
>emit_insn (pat);
>return ops[0].value;
>  }
> -  delete_insns_since (last);
> +
>return NULL_RTX;
>  }
>  
> @@ -1543,9 +1540,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
> op0, rtx op1,
>if (icode != CODE_FOR_nothing)
>   {
> temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
> - target, unsignedp, methods, last);
> + target, unsignedp, methods);
> if (temp)
>   return temp;
> +   delete_insns_since (last);
>   }
>  }
>  
> @@ -1571,9 +1569,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
> op0, rtx op1,
>  NULL_RTX, unsignedp, OPTAB_DIRECT);
>  
>temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
> - target, unsignedp, methods, last);
> + target, unsignedp, methods);
>if (temp)
>   return temp;
> +  delete_insns_since (last);
>  }
>  
>/* If this is a multiply, see if we can do a widening operation that
> @@ -1637,9 +1636,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
> op0, rtx op1,
> if (vop1)
>   {
> temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
> - target, unsignedp, methods, last);
> +

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

2025-03-21 Thread Richard Biener
On Fri, 21 Mar 2025, Simon Sobisch wrote:

> > Now a question on COBOL:
> >
> > 77 var8 PIC 999V9(8) COMP-5
> >
> > what precision/digits does this specify?  When then doing
> >
> >  add 0.0001 TO var555 giving var8 rounded
> >
> > what's the precision/digit specification for the literal floating
> > point values and how does that or that of var555 or var8
> > "promote" or "demote" to a common specification for the arithmetic
> > operation?
> >
> > Does the COBOL standard expect a literal floating point value to
> > be represented exactly?  Maybe rounding then only applies at the
> > "giving var8 rounded" point, forcing the exact value to the
> > specification of var8?
> >
> > Richard.
> 
> That's NOT a floating-point in COBOL, but a fixed-point numeric literal.
> It is best understood with the following explanation from the standard:
> 
> > An integer literal is a fixed-point numeric literal that contains no 
> decimal point.
> 
> --> it is to be used as integer with an implied decimal point after the 
> first position, as if it would be defined with a PIC 9v
> 
> 
> floating-point literals in COBOL would have the following most important
> difference:
> 
> > A floating-point numeric literal is formed from two fixed-point 
> numeric literals separated by the letter 'E' without intervening spaces.
> 
> 
> The requested *minimal* precision - "stored exactly" is:
> * 31 digits for fixed-point numeric literals (and effectively all
>   calculations with those, before rounding/truncation applies)
> * up to 36 digits of significand with up to 4 digits in exponent for
>   floating-point literals

OK, and "digits" are for a base-10 representation?

> Back to your arithmetic question: COBOL standard expects that to be exact for
> an intermediate value up to these sizes.
> If the sizes get bigger and cannot be stored (the maximum is
> implementor-defined = "should be documented in the user-documentation") then
> there's the option to specify which INTERMEDIATE ROUNDING should apply (= per
> program), which includes ROUNDING/TRUNCATION/PROHIBITED (=an exception
> raised).
> 
> The default for INTERMEDIATE ROUNDING dependens on which arithmetic is in
> effect (also per program defined, NATIVE is default where rounding is
> implementor-defined, STANDARD-BINARY and STANDARD-DECIMAL can be chosen).

Where STANDARD-BINARY and STANDARD-DECIMAL roughly correspond to
binary vs decimal floating-point?

> > If the NATIVE phrase is specified [or implied], the techniques used 
> in handling arithmetic expressions and intrinsic functions shall be those
> specified by the implementor, [as well as] the techniques used in handling
> arithmetic statements [mostly for rounding/truncation].

And NATIVE for whatever a CPU implements when using its native
floating-point facilities?

> --> note that STANDARD-DECIMAL arithmetic is no optional feature, so for 
> full compliance that has to be considered - but can also be "ignored in
> detail" for now; note that the OPTIONS paragraph (support for the paragraph is
> required since COBOL2002) is only supported by GnuCOBOL (neither IBM nor Micro
> Focus nor Fujitsu support it and all go with "native arithmetic" only).
> 
> also mind that COBOL2014 has a note:
> > Implementors are strongly encouraged to provide support for the 
> STANDARD-DECIMAL phrase of the ARITHMETIC clause
> 
> 
> ... sorry for another "background-drift", getting to your question again:
> 
> * intermediate values need to cover at least the sizes outlined above
> * for bigger sizes truncation/rounding may apply - the rules that IBM,
>   MF and GnuCOBOL applies are different (with GnuCOBOL being nearly
>   infinite using GMP with an internal scale as intermediate
>   representation)
> * the truncation/rounding that applies for a statement can be specified
>   at the statement (as in your example where "rounded" only applies to
>   this final "store to the receiving item") with the default being able
>   to be configured in the OPTIONS paragraph "DEFAULT ROUNDED MODE"

OK, so I guess I have to look into gcobol.1 to see what's documented
there for the implementation-defined bits.

It seems to me that with all this "digit" stuff using decimal
floating point internally would be more natural here?  From saying
that GnuCOBOL uses GMP I suppose you're representing fixed-point
arithmetic with integers?  As maybe obvious from the thread I'm
trying to deal with the choice of using _Float128 as internal
representation for COBOL "numbers".

> Hope this helps with some background and answers your questions,

Yes - thanks a lot.
Richard.

> Simon
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


Re: [Fortran, Patch, PR119380, v1] Fix freeing procedure pointers in components

2025-03-21 Thread Paul Richard Thomas
Hi Andre,

Gosh, that's a mighty complicated patch :-) I suggest changing the comment
in the test case:

s/Check that components of procedure pointer aren't freeed./Do not free
procedure pointer components/ or some such.

OK for mainline and, I propose, 14-branch.

Regards and thanks

Paul


On Fri, 21 Mar 2025 at 09:38, Andre Vehreschild  wrote:

> Hi all,
>
> attached patch fixes freeing of procedure pointers that are stored in a
> derived
> type's component. GFortran did that already for polymorphic types but
> missed
> out on the others.
>
> Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
>
> Regards,
> Andre
> --
> Andre Vehreschild * Email: vehre ad gmx dot de
>


New French PO file for 'gcc' (version 15.1-b20250316)

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

This is a message from the Translation Project robot.

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

https://translationproject.org/latest/gcc/fr.po

(This file, 'gcc-15.1-b20250316.fr.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/gcc/

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/gcc.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.




[PATCH v2 0/1] Cherry pick of patch for gcc-13 fixing PR119372

2025-03-21 Thread Alfie Richards
Minor update to add the PR label from Alex's feedback (thank you!).

Regtested and bookstrapped for gcc-12 and gcc-13 (after applying
r13-100-g3771486daa1e904ceae6f3e135b28e58af33849 to gcc-12).

Alfie

Andrew Carlotti (1):
  aarch64: Use PAUTH instead of V8_3A in some places

 gcc/config/aarch64/aarch64.cc | 6 +++---
 gcc/config/aarch64/aarch64.md | 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

-- 
2.34.1



[PATCH] inliner: Silently drop musttail flag on calls during inlining unless the inlined routine was musttail called [PR119376]

2025-03-21 Thread Jakub Jelinek
Hi!

As discussed in the PR, some packages fail to build because they use
musttail attribute on calls in functions which we inline, and if they
are inlined into a middle of the function, that results in an error
because we have a musttail call in the middle of a function and so it
can't be tail called there.

Now, guess the primary intent of the musttail attribute is ensuring
we don't get an extra stack frame in the backtrace.  Inlining itself
removes one extra stack frame from the backtrace as well (sure, not
counting virtual backtraces in gdb), so I think erroring out on that
is unnecessary.

Except when we are inlining a musttail call which has musttail calls
in it, in that case we are being asked to remove 2 stack frames from
the backtrace, inlining removes one, so we need to keep musttail
on the calls so that another stack frame is removed through a tail call.

The following patch implements that, keeping previous behavior when
id->call_stmt is NULL (i.e. when versioning/cloning etc.).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-03-20  Jakub Jelinek  

PR ipa/119376
* tree-inline.cc (remap_gimple_stmt): Silently clear
gimple_call_must_tail_p on inlined call stmts if id->call_stmt
is a call without that flag set.

* c-c++-common/musttail26.c: New test.

--- gcc/tree-inline.cc.jj   2025-01-20 17:58:39.244480277 +0100
+++ gcc/tree-inline.cc  2025-03-20 12:08:42.957453514 +0100
@@ -1892,6 +1892,15 @@ remap_gimple_stmt (gimple *stmt, copy_bo
gimple_call_set_tail (call_stmt, false);
  if (gimple_call_from_thunk_p (call_stmt))
gimple_call_set_from_thunk (call_stmt, false);
+ /* Silently clear musttail flag when inlining a function
+with must tail call from a non-musttail call.  The inlining
+removes one frame so acts like musttail's intent, and we
+can be inlining a function with musttail calls in the middle
+of caller where musttail will always error.  */
+ if (gimple_call_must_tail_p (call_stmt)
+ && id->call_stmt
+ && !gimple_call_must_tail_p (id->call_stmt))
+   gimple_call_set_must_tail (call_stmt, false);
  if (gimple_call_internal_p (call_stmt))
switch (gimple_call_internal_fn (call_stmt))
  {
--- gcc/testsuite/c-c++-common/musttail26.c.jj  2025-03-20 12:47:53.443730606 
+0100
+++ gcc/testsuite/c-c++-common/musttail26.c 2025-03-20 12:53:26.110082182 
+0100
@@ -0,0 +1,33 @@
+/* PR ipa/119376 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(3, \[^\n\r]*\\\); 
\\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(4, \[^\n\r]*\\\); 
\\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "  foo \\\(\[12], \[^\n\r]*\\\); \\\[tail 
call\\\]" "optimized" } } */
+
+int foo (int, int);
+int v, w[10];
+
+static inline __attribute__((always_inline)) int
+bar (int x, int y)
+{
+  [[gnu::musttail]] return foo (x, y);
+}
+
+static int
+baz (int x, int y)
+{
+  [[gnu::musttail]] return foo (x, x + y + (v | y) * (v & y));
+}
+
+int
+qux (int x, int y)
+{
+  w[0] = bar (1, x + y);
+  w[1] = baz (2, x + y);
+  if (x == 42)
+[[gnu::musttail]] return bar (3, x + y);
+  if (x == -42)
+[[gnu::musttail]] return baz (4, x + y);
+  return 0;
+}

Jakub



[PATCH] icf: Punt for musttail call flag differences in ICF [PR119376]

2025-03-21 Thread Jakub Jelinek
Hi!

The following testcase shows we were ignoring musttail flags on calls
when deciding if two functions are the same.
That can result in problems in both directions, either we silently
lose musttail attribute because there is a similar function without it
earlier and then we e.g. don't diagnose if it can't be tail called
or don't try harder to do a tail call, or we get it even in functions
which didn't have it before.

The following patch for now just punts if it differs.  Perhaps we could
just merge it and get musttail flag if any of the merged functions had
one in such position, but it feels to me that it is now too late in GCC 15
cycle to play with this.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-03-20  Jakub Jelinek  

PR ipa/119376
* ipa-icf-gimple.cc (func_checker::compare_gimple_call): Return false
for gimple_call_must_tail_p mismatches.

* c-c++-common/musttail27.c: New test.

--- gcc/ipa-icf-gimple.cc.jj2025-02-27 22:04:06.082435026 +0100
+++ gcc/ipa-icf-gimple.cc   2025-03-20 15:33:38.996614656 +0100
@@ -708,7 +708,8 @@ func_checker::compare_gimple_call (gcall
   || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
   || gimple_call_from_new_or_delete (s1) != gimple_call_from_new_or_delete 
(s2)
   || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
-  || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p 
(s2))
+  || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
+  || gimple_call_must_tail_p (s1) != gimple_call_must_tail_p (s2))
 return false;
 
   unsigned check_arg_types_from = 0;
--- gcc/testsuite/c-c++-common/musttail27.c.jj  2025-03-20 15:42:30.200261715 
+0100
+++ gcc/testsuite/c-c++-common/musttail27.c 2025-03-20 15:44:24.990674296 
+0100
@@ -0,0 +1,31 @@
+/* PR ipa/119376 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(\[^\n\r]*\\\); 
\\\[tail call\\\] \\\[must tail call\\\]" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(\[^\n\r]*\\\); 
\\\[tail call\\\]" 4 "optimized" } } */
+
+int foo (int);
+
+int
+bar (int x)
+{
+  [[gnu::musttail]] return foo (x + 1);
+}
+
+int
+baz (int x)
+{
+  return foo (x + 1);
+}
+
+int
+qux (int x)
+{
+  return foo (x + 2);
+}
+
+int
+corge (int x)
+{
+  [[gnu::musttail]] return foo (x + 2);
+}

Jakub



Re: [PATCH v2 1/3] libstdc++: Use formatting locale for std::time_put formats

2025-03-21 Thread Tomasz Kaminski
On Thu, Mar 20, 2025 at 5:29 PM Jonathan Wakely  wrote:

> On Thu, 20 Mar 2025 at 16:16, Jonathan Wakely  wrote:
> >
> > When using std::time_put to format a chrono value, we should imbue the
> > formatting locale into the stream. This ensures that when
> > std::time_put::do_put uses a ctype or __timepunct facet from the locale,
> > it gets the correct facets.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/bits/chrono_io.h (__formatter_chrono::_M_locale_fmt):
> > Imbue locale into ostringstream.
> > * testsuite/std/time/format/localized.cc: Check that correct
> > locale is used for call to time_put::put.
> > ---
> >
> > Now with a test that shows the bug independent of the PR117214 patches
> > to use std::time_put for %c formats.
> >
> > Tested x86_64-linux.
> >
> >  libstdc++-v3/include/bits/chrono_io.h |  1 +
> >  .../testsuite/std/time/format/localized.cc| 30 +++
> >  2 files changed, 31 insertions(+)
> >
> > diff --git a/libstdc++-v3/include/bits/chrono_io.h
> b/libstdc++-v3/include/bits/chrono_io.h
> > index c16b555df29..55ebd4ee061 100644
> > --- a/libstdc++-v3/include/bits/chrono_io.h
> > +++ b/libstdc++-v3/include/bits/chrono_io.h
> > @@ -1697,6 +1697,7 @@ namespace __format
> >   char __fmt, char __mod) const
> > {
> >   basic_ostringstream<_CharT> __os;
> > + __os.imbue(__loc);
> >   const auto& __tp = use_facet>(__loc);
> >   __tp.put(__os, __os, _S_space, &__tm, __fmt, __mod);
> >   if (__os)
> > diff --git a/libstdc++-v3/testsuite/std/time/format/localized.cc
> b/libstdc++-v3/testsuite/std/time/format/localized.cc
> > index 393d0d200e4..437a4a011b2 100644
> > --- a/libstdc++-v3/testsuite/std/time/format/localized.cc
> > +++ b/libstdc++-v3/testsuite/std/time/format/localized.cc
> > @@ -13,6 +13,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >
> > @@ -81,6 +82,35 @@ test_en()
> >  }
> >  }
> >
> > +void
> > +test_locale_imbued()
> > +{
> > +  // Custom time_put facet which returns %b string for %Om
> > +  struct TimePut : std::time_put
> > +  {
> > +iter_type
> > +do_put(iter_type out, std::ios_base& io, char_type fill, const tm*
> t,
> > +  char format, char modifier) const override
> > +{
> > +  if (format == 'm' && modifier == 'O')
> > +   format = 'b';
> > +  return std::time_put::do_put(out, io, fill, t, format, 0);
> > +}
> > +  };
> > +
> > +  auto m = std::chrono::March;
> > +
> > +  std::locale fr(ISO_8859(1,fr_FR));
> > +  std::locale fr2(fr, new TimePut);
> > +  auto s1 = std::format(fr2, "{:L%Om}", m);
> > +  VERIFY( s1 == std::format(fr, "{:L}", m) );
> > +
> > +  std::locale es(ISO_8859(1,es_ES));
> > +  std::locale es2(es, new TimePut);
> > +  auto s2 = std::format(es2, "{:L%Om}", m);
> > +  VERIFY( s2 == std::format(es, "{:L}", m) );
> > +}
> > +
> >  int main()
> >  {
> >test_ru();
>
> It would help if I added the new test_locale_imbued() function to main
> so that it actually runs.
>
LGTM with that addition.

>
> Luckily it passes when I do that.
>
>


[PATCH] opcodes: fix wrong code in expand_binop_directly [PR117811]

2025-03-21 Thread Richard Earnshaw
If expand_binop_directly fails to add a REG_EQUAL note it tries to
unwind and restart.  But it can unwind too far if expand_binop changed
some of the operands before calling it.  We don't need to unwind that
far anyway since we should end up taking exactly the same route next
time, just without a target rtx.

To fix this we remove LAST from the argument list and let the callers
(all in expand_binop) do their own unwinding if the call fails.
Instead we unwind just as far as the entry to expand_binop_directly
and recurse within this function instead of all the way back up.

gcc/ChangeLog:

PR middle-end/117811
* optabs.cc (expand_binop_directly): Remove LAST as an argument,
instead record the last insn on entry.  Only delete insns if
we need to restart and restart by calling ourself, not expand_binop.
(expand_binop): Update callers to expand_binop_directly.  If it
fails to expand the operation, delete back to LAST.

gcc/testsuite:

PR middle-end/117811
* gcc.dg/torture/pr117811.c: New test.
---
 gcc/optabs.cc   | 24 +++---
 gcc/testsuite/gcc.dg/torture/pr117811.c | 27 +
 2 files changed, 39 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr117811.c

diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 36f2e6af8b5..0a14b1eef8a 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -1369,8 +1369,7 @@ avoid_expensive_constant (machine_mode mode, optab 
binoptab,
 static rtx
 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
   rtx op0, rtx op1,
-  rtx target, int unsignedp, enum optab_methods methods,
-  rtx_insn *last)
+  rtx target, int unsignedp, enum optab_methods methods)
 {
   machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
   machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
@@ -1380,6 +1379,7 @@ expand_binop_directly (enum insn_code icode, machine_mode 
mode, optab binoptab,
   rtx_insn *pat;
   rtx xop0 = op0, xop1 = op1;
   bool canonicalize_op1 = false;
+  rtx_insn *last = get_last_insn ();
 
   /* If it is a commutative operator and the modes would match
  if we would swap the operands, we can save the conversions.  */
@@ -1444,10 +1444,7 @@ expand_binop_directly (enum insn_code icode, 
machine_mode mode, optab binoptab,
   tmp_mode = insn_data[(int) icode].operand[0].mode;
   if (VECTOR_MODE_P (mode)
  && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
-   {
- delete_insns_since (last);
- return NULL_RTX;
-   }
+   return NULL_RTX;
 }
   else
 tmp_mode = mode;
@@ -1467,14 +1464,14 @@ expand_binop_directly (enum insn_code icode, 
machine_mode mode, optab binoptab,
   ops[1].value, ops[2].value, mode0))
{
  delete_insns_since (last);
- return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
-  unsignedp, methods);
+ return expand_binop_directly (icode, mode, binoptab, op0, op1,
+   NULL_RTX, unsignedp, methods);
}
 
   emit_insn (pat);
   return ops[0].value;
 }
-  delete_insns_since (last);
+
   return NULL_RTX;
 }
 
@@ -1543,9 +1540,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
op0, rtx op1,
   if (icode != CODE_FOR_nothing)
{
  temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
-   target, unsignedp, methods, last);
+   target, unsignedp, methods);
  if (temp)
return temp;
+ delete_insns_since (last);
}
 }
 
@@ -1571,9 +1569,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
op0, rtx op1,
   NULL_RTX, unsignedp, OPTAB_DIRECT);
 
   temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
-   target, unsignedp, methods, last);
+   target, unsignedp, methods);
   if (temp)
return temp;
+  delete_insns_since (last);
 }
 
   /* If this is a multiply, see if we can do a widening operation that
@@ -1637,9 +1636,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx 
op0, rtx op1,
  if (vop1)
{
  temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
-   target, unsignedp, methods, last);
+   target, unsignedp, methods);
  if (temp)
return temp;
+ delete_insns_since (last);
}
}
 }
diff --git a/gcc/testsuite/gcc.dg/torture/pr117811.c 
b/gcc/testsuite/gcc.dg/torture/pr117811.c
new file mode 100644
index 000..13d7e134780
-

[COMMITTED 111/146] gccrs: Visit the trait paths of trait implementations

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

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): When visiting a TraitImpl, visit its
trait path.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-visitor.cc   |  1 +
 gcc/testsuite/rust/compile/nr2/exclude | 46 --
 2 files changed, 1 insertion(+), 46 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 32e8025e9b2..d10ca6ca07b 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1039,6 +1039,7 @@ DefaultASTVisitor::visit (AST::TraitImpl &impl)
   if (impl.has_where_clause ())
 visit (impl.get_where_clause ());
   visit (impl.get_type ());
+  visit (impl.get_trait_path ());
   visit_inner_attrs (impl);
   for (auto &item : impl.get_impl_items ())
 visit (item);
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 9b1ee7ceaf9..9b490c18bab 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -13,7 +13,6 @@ cfg4.rs
 cfg5.rs
 closure_no_type_anno.rs
 complex-path1.rs
-complex_qualified_path_in_expr.rs
 const-issue1440.rs
 const_generics_3.rs
 const_generics_4.rs
@@ -21,12 +20,8 @@ const_generics_5.rs
 const_generics_7.rs
 derive_empty.rs
 derive_macro1.rs
-derive_macro3.rs
-derive_macro4.rs
-derive_macro6.rs
 expected_type_args2.rs
 feature_rust_attri0.rs
-for_lifetimes.rs
 format_args_basic_expansion.rs
 generic-default1.rs
 generics1.rs
@@ -38,9 +33,6 @@ generics5.rs
 generics6.rs
 generics9.rs
 if_let_expr.rs
-issue-1019.rs
-issue-1034.rs
-issue-1129-2.rs
 issue-1130.rs
 issue-1173.rs
 issue-1272.rs
@@ -52,24 +44,12 @@ issue-1786.rs
 issue-1893.rs
 issue-1901.rs
 issue-1981.rs
-issue-2019-1.rs
-issue-2019-2.rs
-issue-2019-3.rs
 issue-2036.rs
-issue-2037.rs
 issue-2043.rs
-issue-2070.rs
-issue-2135.rs
-issue-2136-1.rs
 issue-2136-2.rs
-issue-2139.rs
 issue-2142.rs
-issue-2165.rs
-issue-2166.rs
 issue-2238.rs
-issue-2304.rs
 issue-2330.rs
-issue-2478.rs
 issue-2479.rs
 issue-2723-1.rs
 issue-2723-2.rs
@@ -80,10 +60,8 @@ issue-2812.rs
 issue-850.rs
 issue-852.rs
 issue-855.rs
-issue-925.rs
 iterators1.rs
 lookup_err1.rs
-macros/mbe/macro-issue1400.rs
 macros/mbe/macro13.rs
 macros/mbe/macro15.rs
 macros/mbe/macro23.rs
@@ -111,7 +89,6 @@ name_resolution4.rs
 nested_macro_use1.rs
 nested_macro_use2.rs
 nested_macro_use3.rs
-non_member_const.rs
 not_find_value_in_scope.rs
 parse_associated_type_as_generic_arg.rs
 parse_associated_type_as_generic_arg2.rs
@@ -135,17 +112,10 @@ redef_error5.rs
 self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
-stmt_with_block_dot.rs
 struct-expr-parse.rs
-traits1.rs
-traits12.rs
-traits2.rs
 traits3.rs
-traits4.rs
-traits5.rs
 traits6.rs
 traits7.rs
-traits8.rs
 type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
@@ -154,27 +124,13 @@ use_2.rs
 v0-mangle1.rs
 v0-mangle2.rs
 while_break_expr.rs
-negative_impls.rs
 exhaustiveness1.rs
 exhaustiveness2.rs
 exhaustiveness3.rs
-trait13.rs
-trait14.rs
 issue-2324-1.rs
 issue-2324-2.rs
-issue-2987.rs
-issue-3045-1.rs
-issue-3045-2.rs
 issue-3046.rs
-issue-3030.rs
-issue-3035.rs
-issue-3139-1.rs
 issue-3139-2.rs
-issue-3139-3.rs
-issue-3036.rs
-issue-2951.rs
-issue-2203.rs
-issue-2499.rs
 issue-3032-1.rs
 issue-3032-2.rs
 # https://github.com/Rust-GCC/gccrs/issues/3189
@@ -184,13 +140,11 @@ issue-3033.rs
 issue-3009.rs
 issue-2953-2.rs
 issue-1773.rs
-issue-2905-1.rs
 issue-2905-2.rs
 issue-2907.rs
 issue-2423.rs
 issue-266.rs
 additional-trait-bounds2.rs
-auto_traits2.rs
 auto_traits3.rs
 issue-3140.rs
 cmp1.rs
-- 
2.45.2



[COMMITTED 105/146] gccrs: cleanup our enum type layout to be closer to rustc

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

This changes our enum type layout so for example:

  enum Foo {
  A,
  B,
  C(char),
  D { x: i32, y: i32 },
  }

Used to get layed out like this in gccrs:

  union {
struct A { int RUST$ENUM$DISR; };
struct B { int RUST$ENUM$DISR; };
struct C { int RUST$ENUM$DISR; char __0; };
struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
  }

This has some issues notably with the constexpr because this is just a
giant union it means its not simple to constify what enum variant we are
looking at because the discriminant is a mess.

This now gets layed out as:

  struct {
 int RUST$ENUM$DISR;
 union {
 struct A { };
 struct B { };
 struct C { char __0; };
 struct D { i64 x; i64 y; };
 } payload;
  }

This layout is much cleaner and allows for our constexpr to work properly.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): new layout
* backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): 
likewise
(CompilePatternBindings::visit): likewise
* backend/rust-compile-resolve-path.cc: likewise
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): implement 
new layout
* rust-gcc.cc (constructor_expression): get rid of useless assert

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc | 74 +++
 gcc/rust/backend/rust-compile-pattern.cc  | 64 
 gcc/rust/backend/rust-compile-resolve-path.cc |  5 +-
 gcc/rust/backend/rust-compile-type.cc | 62 
 gcc/rust/rust-gcc.cc  |  2 +-
 5 files changed, 128 insertions(+), 79 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 900e080ea0e..b40aa33866e 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -558,24 +558,32 @@ CompileExpr::visit (HIR::StructExprStructFields 
&struct_expr)
}
 }
 
-  // the constructor depends on whether this is actually an enum or not if
-  // its an enum we need to setup the discriminator
-  std::vector ctor_arguments;
-  if (adt->is_enum ())
+  if (!adt->is_enum ())
 {
-  HIR::Expr &discrim_expr = variant->get_discriminant ();
-  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
-  tree folded_discrim_expr = fold_expr (discrim_expr_node);
-  tree qualifier = folded_discrim_expr;
-
-  ctor_arguments.push_back (qualifier);
+  translated
+   = Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
+  arguments, union_disriminator,
+  struct_expr.get_locus ());
+  return;
 }
-  for (auto &arg : arguments)
-ctor_arguments.push_back (arg);
+
+  HIR::Expr &discrim_expr = variant->get_discriminant ();
+  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+  tree folded_discrim_expr = fold_expr (discrim_expr_node);
+  tree qualifier = folded_discrim_expr;
+
+  tree enum_root_files = TYPE_FIELDS (compiled_adt_type);
+  tree payload_root = DECL_CHAIN (enum_root_files);
+
+  tree payload = Backend::constructor_expression (TREE_TYPE (payload_root),
+ adt->is_enum (), arguments,
+ union_disriminator,
+ struct_expr.get_locus ());
+
+  std::vector ctor_arguments = {qualifier, payload};
 
   translated
-= Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
-  ctor_arguments, union_disriminator,
+= Backend::constructor_expression (compiled_adt_type, 0, ctor_arguments, 
-1,
   struct_expr.get_locus ());
 }
 
@@ -1247,26 +1255,34 @@ CompileExpr::visit (HIR::CallExpr &expr)
  arguments.push_back (rvalue);
}
 
-  // the constructor depends on whether this is actually an enum or not if
-  // its an enum we need to setup the discriminator
-  std::vector ctor_arguments;
-  if (adt->is_enum ())
+  if (!adt->is_enum ())
{
- HIR::Expr &discrim_expr = variant->get_discriminant ();
- tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
- tree folded_discrim_expr = fold_expr (discrim_expr_node);
- tree qualifier = folded_discrim_expr;
-
- ctor_arguments.push_back (qualifier);
+ translated
+   = Backend::constructor_expression (compiled_adt_type,
+  adt->is_enum (), arguments,
+  union_disriminator,
+  expr.get_locus ());
+ return;
}
-  for (auto &arg : arguments)
-   ctor_arguments.push_back (arg);
 
-  transla

[COMMITTED 115/146] gccrs: testsuite: Fix missing handling of little endian.

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

Some failures occur in the testsuite because we
did not account for the little-endian case.

gcc/testsuite/ChangeLog:

* rust/compile/issue-1446.rs: Add swap_bytes function.
* rust/compile/iterators1.rs: Remove unused {to, from}_le functions.
---
 gcc/testsuite/rust/compile/issue-1446.rs | 10 +-
 gcc/testsuite/rust/compile/iterators1.rs | 18 --
 2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/gcc/testsuite/rust/compile/issue-1446.rs 
b/gcc/testsuite/rust/compile/issue-1446.rs
index 8bfa42b9dac..969ad380ee6 100644
--- a/gcc/testsuite/rust/compile/issue-1446.rs
+++ b/gcc/testsuite/rust/compile/issue-1446.rs
@@ -1,3 +1,11 @@
+// fake function
+pub fn swap_bytes(this: u32) -> u32 {
+(((this) & 0xff00) >> 24)
+| (((this) & 0x00ff) >> 8)
+| (((this) & 0xff00) << 8)
+| (((this) & 0x00ff) << 24)
+}
+
 pub fn to_le(this: u32) -> u32 {
 #[cfg(target_endian = "little")]
 {
@@ -5,6 +13,6 @@ pub fn to_le(this: u32) -> u32 {
 }
 #[cfg(not(target_endian = "little"))]
 {
-this.swap_bytes()
+swap_bytes(this)
 }
 }
diff --git a/gcc/testsuite/rust/compile/iterators1.rs 
b/gcc/testsuite/rust/compile/iterators1.rs
index 35fea5a0493..1141758b14a 100644
--- a/gcc/testsuite/rust/compile/iterators1.rs
+++ b/gcc/testsuite/rust/compile/iterators1.rs
@@ -232,24 +232,6 @@ macro_rules! impl_uint {
 }
 }
 
-pub fn to_le(self) -> Self {
-#[cfg(target_endian = "little")]
-{
-self
-}
-}
-
-pub const fn from_le_bytes(bytes: [u8; 
mem::size_of::()]) -> Self {
-Self::from_le(Self::from_ne_bytes(bytes))
-}
-
-pub const fn from_le(x: Self) -> Self {
-#[cfg(target_endian = "little")]
-{
-x
-}
-}
-
 pub const fn from_ne_bytes(bytes: [u8; 
mem::size_of::()]) -> Self {
 unsafe { mem::transmute(bytes) }
 }
-- 
2.45.2



[COMMITTED 103/146] gccrs: fix ICE with hir dump on closure

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

Return type and parameter types are optional on closures.

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): add null guard

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 5acf53e9296..798179d172e 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1244,13 +1244,17 @@ Dump::visit (ClosureExpr &e)
  auto oa = param.get_outer_attrs ();
  do_outer_attrs (oa);
  visit_field ("pattern", param.get_pattern ());
- visit_field ("type", param.get_type ());
+
+ if (param.has_type_given ())
+   visit_field ("type", param.get_type ());
+
  end ("ClosureParam");
}
   end_field ("params");
 }
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
 
   visit_field ("expr", e.get_expr ());
   end ("ClosureExpr");
-- 
2.45.2



Re: [PATCH] libstdc++: Add P1206R7 range operations to std::deque [PR111055]

2025-03-21 Thread Tomasz Kaminski
On Fri, Mar 21, 2025 at 11:14 AM Tomasz Kamiński 
wrote:

> This is another piece of P1206R7, adding from_range constructor,
> append_range,
> prepend_range, insert_range, and assign_range members to std::deque.
>
> For insert_range, the handling of insertion in the middle of input-only
> ranges
> that are sized could be optimized, we still insert nodes one-by-one in
> such case.
> For forward and stronger ranges, we reduce them to common_range case,
> by computing the iterator when computing the distance.
> This is slightly suboptimal, as it require range to be iterated for
> non-common
> forward ranges that are sized.
>
> This patch extract a set of  helper functions that accepts (iterator,
> sentinel) pair:
> _M_range_prepend, _M_range_append, _M_range_empl.
> To make them usable in all standard modes, _M_emplace_aux is defined for
> c++98
> as accepting const value_type&, and _M_insert_aux forwards to it.
>
> PR libstdc++/111055
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/deque.tcc (deque::insert_range,
> __detail::__advance_dist):
> Define.
> (deque::_M_range_prepend, deque::_M_range_append):
> Extract from _M_range_insert_aux for _ForwardIterator(s).
> (deque::_M_range_empl): Define.
> (deque::_M_emplace_aux(iterator, const value_type&)): Renamed
> _M_insert_aux
> in c++98.
> * include/bits/stl_deque.h (deque::prepend_range,
> deque::append_range),
> (deque::assing_range):Define.
> deque(from_range_t, _Rg&&, const allocator_type&): Define
> constructor
> and deduction guide.
> * include/debug/deque (prepend_range, append_range, assing_range):
> Define.
> deque(from_range_t, _Rg&&, const allocator_type&): Define
> constructor
> and deduction guide.
> (deque::_M_insert_qux): Define using _M_emplace_aux also for c++98.
> (deque::_M_range_insert(iterator, _InputIterator, _InputIterator,
> std::input_iterator_tag)): Forward to _M_range_empl.
> * testsuite/23_containers/deque/cons/from_range.cc: New test.
> * testsuite/23_containers/deque/modifiers/append_range.cc: New
> test.
> * testsuite/23_containers/deque/modifiers/assign/assign_range.cc:
> New test.
> * testsuite/23_containers/deque/modifiers/prepend_range.cc: New
> test.
> ---
>  Testing on x86_64-linux. Tests in 23_containers passed with each of:
>  -std=c++98, GLIBCXX_DEBUG and no-PCH.
>  OK for trunk?
>
>  In the __advance_dist I branch between __it += __n and
> ranges::advance(__it, ranges::end(__rg)),
>  instead of just calling ranges::advance(__it, __n), as the former will
> handle nearly
>  common ranges, like `int const*` and `int*`.
>
>  libstdc++-v3/include/bits/deque.tcc   | 170 ++
>  libstdc++-v3/include/bits/stl_deque.h | 148 ++-
>  libstdc++-v3/include/debug/deque  |  52 ++
>  .../23_containers/deque/cons/from_range.cc|  99 ++
>  .../deque/modifiers/append_range.cc   |  88 +
>  .../deque/modifiers/assign/assign_range.cc| 109 +++
>  .../deque/modifiers/insert/insert_range.cc| 116 
>  .../deque/modifiers/prepend_range.cc  |  90 ++
>  8 files changed, 829 insertions(+), 43 deletions(-)
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/deque/cons/from_range.cc
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/deque/modifiers/append_range.cc
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/deque/modifiers/assign/assign_range.cc
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/deque/modifiers/insert/insert_range.cc
>  create mode 100644
> libstdc++-v3/testsuite/23_containers/deque/modifiers/prepend_range.cc
>
> diff --git a/libstdc++-v3/include/bits/deque.tcc
> b/libstdc++-v3/include/bits/deque.tcc
> index fcbecca55b4..8444d810e03 100644
> --- a/libstdc++-v3/include/bits/deque.tcc
> +++ b/libstdc++-v3/include/bits/deque.tcc
> @@ -584,13 +584,72 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>  }
>
>template 
> -template 
> +template 
>void
>deque<_Tp, _Alloc>::
> -  _M_range_insert_aux(iterator __pos,
> - _InputIterator __first, _InputIterator __last,
> - std::input_iterator_tag)
> -  { std::copy(__first, __last, std::inserter(*this, __pos)); }
> +  _M_range_prepend(_InputIterator __first, _Sentinel __last,
> + size_type __n)
> +  {
> +iterator __new_start = _M_reserve_elements_at_front(__n);
> +__try
> +  {
> +std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last,
> +__new_start,
> _M_get_Tp_allocator());
> +this->_M_impl._M_start = __new_start;
> +  }
> +__catch(...)
> +  {
> +_M_destroy_nodes(__new_start._M_node,
> + this

[COMMITTED 128/146] gccrs: lang-item: Add LangItem::PrettyString

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

Which formats a lang item as it appears in source code.

gcc/rust/ChangeLog:

* util/rust-lang-item.cc (LangItem::PrettyString): New.
* util/rust-lang-item.h: New.
---
 gcc/rust/util/rust-lang-item.cc | 6 ++
 gcc/rust/util/rust-lang-item.h  | 1 +
 2 files changed, 7 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 4a609096144..e038e900f94 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -118,6 +118,12 @@ LangItem::ToString (LangItem::Kind type)
   return str.value ();
 }
 
+std::string
+LangItem::PrettyString (LangItem::Kind type)
+{
+  return "#[lang = \"" + LangItem::ToString (type) + "\"]";
+}
+
 LangItem::Kind
 LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op)
 {
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 62b15d7b3fc..f947f3f021c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -134,6 +134,7 @@ public:
 
   static tl::optional Parse (const std::string &item);
   static std::string ToString (Kind type);
+  static std::string PrettyString (Kind type);
   static Kind OperatorToLangItem (ArithmeticOrLogicalOperator op);
   static Kind
   CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op);
-- 
2.45.2



Re: C++/v3 PATCH to add/throw std::bad_array_new_length

2025-03-21 Thread Thomas Schwinge
Hi Jason!

On 2025-03-20T11:52:46-0400, Jason Merrill  wrote:
> On 3/19/25 1:35 PM, Thomas Schwinge wrote:
>> On 2013-05-03T16:24:43-0400, Jason Merrill  wrote:
>>> Last year Florian fixed the compiler to detect overflow in array new
>>> size calculations and pass (size_t)-1 in that case.  But C++11 specifies
>>> that in case of overflow the program throws std::bad_array_new_length
>>> (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#624), so
>>> I've adjusted the checking code accordingly.
>>>
>>> This patch also adds the type to libsupc++, and several exports to
>>> libstdc++.
>>>
>>> Tested x86_64-pc-linux-gnu, applying to trunk.
>> 
>> Subversion r198731 (Git commit 7d5e76c8de1b6c4b2ae5576ab909dc9e580b216b).
>> 
>>> Core 624/N2932: Throw bad_array_new_length on overflow
>>> in array new size calculation.
>>>  
>>>  libstdc++-v3/
>>> * libsupc++/new: Add std::bad_array_new_length.
>>> * libsupc++/bad_array_new.cc: New.
>>> * libsupc++/eh_aux_runtime.cc: Add __cxa_bad_array_new_length.
>>> * libsupc++/Makefile.in: Build them.
>>> * config/abi/pre/gnu.ver: Add new symbols.
>>> * config/abi/pre/gnu-versioned-namespace.ver: Add new symbols.
>>>  gcc/cp/
>>> * init.c (throw_bad_array_new_length): New.
>>> (build_new_1): Use it.  Don't warn about braced-init-list.
>>> (build_vec_init): Use it.
>>> * call.c (build_operator_new_call): Use it.
>> 
>> Here:
>> 
>>> --- a/gcc/cp/init.c
>>> +++ b/gcc/cp/init.c
>> 
>>> +/* Call __cxa_bad_array_new_length to indicate that the size calculation
>>> +   overflowed.  Pretend it returns sizetype so that it plays nicely in the
>>> +   COND_EXPR.  */
>>> +
>>> +tree
>>> +throw_bad_array_new_length (void)
>>> +{
>>> +  tree fn = get_identifier ("__cxa_bad_array_new_length");
>>> +  if (!get_global_value_if_present (fn, &fn))
>>> +fn = push_throw_library_fn (fn, build_function_type_list (sizetype,
>>> + NULL_TREE));
>>> +
>>> +  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
>>> +}
>> 
>> "Pretend it returns sizetype", doesn't work with nvptx, which complains
>> that the front end-synthesized prototype with the fake 'sizetype' return
>> type:
>> 
>>  .extern .func (.param .u64 %value_out) __cxa_throw_bad_array_new_length;
>> 
>> ... doesn't match the library code with 'void' return type:
>> 
>>> --- a/libstdc++-v3/libsupc++/cxxabi.h
>>> +++ b/libstdc++-v3/libsupc++/cxxabi.h
>> 
>>> +  void
>>> +  __cxa_bad_array_new_length() __attribute__((__noreturn__));
>> 
>>> --- a/libstdc++-v3/libsupc++/eh_aux_runtime.cc
>>> +++ b/libstdc++-v3/libsupc++/eh_aux_runtime.cc
>> 
>>> +extern "C" void
>>> +__cxxabiv1::__cxa_bad_array_new_length ()
>>> +{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_new_length()); }
>> 
>>  .visible .func __cxa_throw_bad_array_new_length
>>  {
>>  [...]
>>  }
>> 
>> ..., and thus results in execution test FAILs:
>> 
>>  error   : Prototype doesn't match for 
>> '__cxa_throw_bad_array_new_length' in 'input file 5 at offset 14095', first 
>> defined in 'input file 5 at offset 14095'
>>  nvptx-run: cuLinkAddData failed: device kernel image is invalid 
>> (CUDA_ERROR_INVALID_SOURCE, 300)
>> 
>> How can we improve on "Pretend it returns sizetype"?  Is there a standard
>> way to "bend" the types in the front end?
>
> Seems like we can just fix the return type, I don't see any regressions 
> from this:

Confirmed, thanks!


Grüße
 Thomas


> From cfc6e295ea19cb570c06d3281f41fd5ae0ba076b Mon Sep 17 00:00:00 2001
> From: Jason Merrill 
> Date: Thu, 20 Mar 2025 09:55:40 -0400
> Subject: [PATCH] c++: fix return typye of __cxa_bad_array_new_length
> To: gcc-patches@gcc.gnu.org
>
> We were lying about the return type, but that's not necessary; we already
> need to handle a COND_EXPR where one side is void for THROW_EXPR.
>
> gcc/cp/ChangeLog:
>
>   * init.cc (throw_bad_array_new_length): Returns void.
> ---
>  gcc/cp/init.cc | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
> index ce6e58e05f2..e589e45e891 100644
> --- a/gcc/cp/init.cc
> +++ b/gcc/cp/init.cc
> @@ -2810,8 +2810,7 @@ diagnose_uninitialized_cst_or_ref_member (tree type, 
> bool using_new, bool compla
>  }
>  
>  /* Call __cxa_bad_array_new_length to indicate that the size calculation
> -   overflowed.  Pretend it returns sizetype so that it plays nicely in the
> -   COND_EXPR.  */
> +   overflowed.  */
>  
>  tree
>  throw_bad_array_new_length (void)
> @@ -2823,7 +2822,7 @@ throw_bad_array_new_length (void)
>fn = get_global_binding (name);
>if (!fn)
>   fn = push_throw_library_fn
> -   (name, build_function_type_list (sizetype, NULL_TREE));
> +   (name, build_function_type_list (void_type_node, NULL_TREE));
>  }
>  
>return build_cxx_call (fn, 0, NULL, tf

[COMMITTED 130/146] gccrs: ast-collector: Adapt to lang item type path segments

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

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Fix collector to 
better
handle lang item type path segments.
---
 gcc/rust/ast/rust-ast-collector.cc | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index f493da3fa3f..4c9c360c04d 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -543,10 +543,14 @@ TokenCollector::visit (TypePathSegment &segment)
 {
   // Syntax:
   //PathIdentSegment
-  auto ident_segment = segment.get_ident_segment ();
-  auto id = ident_segment.as_string ();
-  push (
-Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
+
+  auto locus = segment.is_lang_item ()
+? segment.get_locus ()
+: segment.get_ident_segment ().get_locus ();
+  auto segment_string = segment.is_lang_item ()
+ ? LangItem::PrettyString (segment.get_lang_item ())
+ : segment.get_ident_segment ().as_string ();
+  push (Rust::Token::make_identifier (locus, std::move (segment_string)));
 }
 
 void
@@ -558,10 +562,13 @@ TokenCollector::visit (TypePathSegmentGeneric &segment)
   //`<` `>`
   //| `<` ( GenericArg `,` )* GenericArg `,`? `>`
 
-  auto ident_segment = segment.get_ident_segment ();
-  auto id = ident_segment.as_string ();
-  push (
-Rust::Token::make_identifier (ident_segment.get_locus (), std::move (id)));
+  auto locus = segment.is_lang_item ()
+? segment.get_locus ()
+: segment.get_ident_segment ().get_locus ();
+  auto segment_string = segment.is_lang_item ()
+ ? LangItem::PrettyString (segment.get_lang_item ())
+ : segment.get_ident_segment ().as_string ();
+  push (Rust::Token::make_identifier (locus, std::move (segment_string)));
 
   if (segment.get_separating_scope_resolution ())
 push (Rust::Token::make (SCOPE_RESOLUTION, UNDEF_LOCATION));
-- 
2.45.2



[PATCH] aarch64: Add support for -mcpu=olympus

2025-03-21 Thread Dhruv Chawla

This adds support for the NVIDIA Olympus core to the AArch64 backend. The
initial patch does not add any special tuning decisions, and those may come
later.

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

gcc/ChangeLog:

* config/aarch64/aarch64-cores.def (olympus): New entry.
* config/aarch64/aarch64-tune.md: Regenerate.
* doc/invoke.texi (AArch64 Options): Document the above.

Signed-off-by: Dhruv Chawla 
---
 gcc/config/aarch64/aarch64-cores.def | 3 +++
 gcc/config/aarch64/aarch64-tune.md   | 2 +-
 gcc/doc/invoke.texi  | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-cores.def 
b/gcc/config/aarch64/aarch64-cores.def
index 5ac81332b67..0e22d72976e 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -207,6 +207,9 @@ AARCH64_CORE("neoverse-v3ae", neoversev3ae, cortexa57, 
V9_2A, (SVE2_BITPERM, RNG
 
 AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
 
+/* NVIDIA ('N') cores. */

+AARCH64_CORE("olympus", olympus, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, 
MEMTAG, PROFILE, FAMINMAX, FP8DOT2, LUT, SVE2_AES, SVE2_SHA3, SVE2_SM4), neoversev3, 
0x4e, 0x10, -1)
+
 /* Generic Architecture Processors.  */
 AARCH64_CORE("generic",  generic, cortexa53, V8A,  (), generic, 0x0, 0x0, -1)
 AARCH64_CORE("generic-armv8-a",  generic_armv8_a, cortexa53, V8A, (), 
generic_armv8_a, 0x0, 0x0, -1)
diff --git a/gcc/config/aarch64/aarch64-tune.md 
b/gcc/config/aarch64/aarch64-tune.md
index 54c65cbf68d..56a914f12b9 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
 ;; -*- buffer-read-only: t -*-
 ;; Generated automatically by gentune.sh from aarch64-cores.def
 (define_attr "tune"
-   
"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,generic,generic_armv8_a,generic_armv9_a"
+   
"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,generic,generic_armv8_a,generic_armv9_a"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1819bcdcdfb..ca320db6f80 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -21745,7 +21745,7 @@ performance of the code.  Permissible values for this 
option are:
 @samp{oryon-1},
 @samp{neoverse-512tvb}, @samp{neoverse-e1}, @samp{neoverse-n1},
 @samp{neoverse-n2}, @samp{neoverse-v1}, @samp{neoverse-v2}, @samp{grace},
-@samp{neoverse-v3}, @samp{neoverse-v3ae}, @samp{neoverse-n3},
+@samp{neoverse-v3}, @samp{neoverse-v3ae}, @samp{neoverse-n3}, @samp{olympus},
 @samp{cortex-a725}, @samp{cortex-x925},
 @samp{qdf24xx}, @samp{saphira}, @samp{phecda}, @samp{xgene1}, @samp{vulcan},
 @samp{octeontx}, @samp{octeontx81},  @samp{octeontx83},
--
2.44.0
From ff6837993ef63ababbf95e2c1d4c5d3351ade0c9 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla 
Date: Wed, 19 Mar 2025 09:34:09 -0700
Subject: [PATCH] aarch64: Add support for -mcpu=olympus

This adds support for the NVIDIA Olympus core to the AArch64 backend. The
initial patch does not add any special tuning decisions, and those may come
later.

Bootstrapped and tested on aarch64-

[PATCH] c++: structural equality and partially inst typedef [PR119379]

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

-- >8 --

Complex alias templates (and their dependent specializations) use
structural equality because we want to treat them as transparent in some
contexts but not others.  Structural-ness however wasn't being preserved
during partial instantiation, which for the below testcase leads to the
checking ICE

  same canonical type node for different types 'S::P' and 'pair'

when comparing those two types with comparing_dependent_aliases set.

This patch makes us preserve structural-ness for partially instantiated
typedefs in general.

PR c++/119379

gcc/cp/ChangeLog:

* pt.cc (tsubst_decl) : Preserve structural-ness
of a partially instantiated typedef.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/class-deduction-alias24.C: New test.
---
 gcc/cp/pt.cc |  5 +
 .../g++.dg/cpp2a/class-deduction-alias24.C   | 16 
 2 files changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias24.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 538ff220d74..39c0ee610bb 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -15920,6 +15920,11 @@ tsubst_decl (tree t, tree args, tsubst_flags_t 
complain,
if (TYPE_USER_ALIGN (TREE_TYPE (t)))
  TREE_TYPE (r) = build_aligned_type (TREE_TYPE (r),
  TYPE_ALIGN (TREE_TYPE (t)));
+
+   /* Preserve structural-ness of a partially instantiated typedef.  */
+   if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t))
+   && dependent_type_p (TREE_TYPE (r)))
+ SET_TYPE_STRUCTURAL_EQUALITY (TREE_TYPE (r));
  }
 
layout_decl (r, 0);
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias24.C 
b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias24.C
new file mode 100644
index 000..cceddac0359
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias24.C
@@ -0,0 +1,16 @@
+// PR c++/119379
+// { dg-do compile { target c++20 } }
+
+template
+struct pair {
+  pair(T, U);
+};
+
+template
+struct S {
+  template requires true
+  using P = pair;
+};
+
+using type = decltype(S::P(1, 2));
+using type = S::P;
-- 
2.49.0.rc1.37.ge969bc8759



[PATCH] libiberty, gcc: Add memrchr to libiberty and use it [PR119283].

2025-03-21 Thread Iain Sandoe
It seems that libiberty already has replacements for most of the
mem* functions, but they are not published via include/libiberty.h.

Tested on x86_64 Linux, Darwin aarch64 Linux, OK for trunk?
thanks,
Iain

--- 8< ---

This adds an implementation of memrchr to libiberty and arranges
to configure gcc to use it, if the host does not have it.

gcc/ChangeLog:

* config.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for host memrchr.

include/ChangeLog:

* libiberty.h (memrchr): New.

libiberty/ChangeLog:

* Makefile.in: Add memrchr build rules.
* config.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for memrchr.
* functions.texi: Document memrchr.
* memrchr.c: New file.

Signed-off-by: Iain Sandoe 
---
 gcc/config.in|  6 ++
 gcc/configure|  2 +-
 gcc/configure.ac |  2 +-
 include/libiberty.h  | 10 ++
 libiberty/Makefile.in| 17 +
 libiberty/config.in  |  3 +++
 libiberty/configure  |  5 +++--
 libiberty/configure.ac   |  5 +++--
 libiberty/functions.texi | 14 ++
 libiberty/memrchr.c  | 33 +
 10 files changed, 87 insertions(+), 10 deletions(-)
 create mode 100644 libiberty/memrchr.c

diff --git a/gcc/config.in b/gcc/config.in
index 0d8a6ba1808..7c89cab7717 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1960,6 +1960,12 @@
 #endif
 
 
+/* Define to 1 if you have the `memrchr' function. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_MEMRCHR
+#endif
+
+
 /* Define to 1 if you have the `mmap' function. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_MMAP
diff --git a/gcc/configure b/gcc/configure
index 063b9ce6701..ab6bec1f0ae 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -10640,7 +10640,7 @@ for ac_func in times clock kill getrlimit setrlimit 
atoq \
popen sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
clearerr_unlocked feof_unlocked   ferror_unlocked fflush_unlocked 
fgetc_unlocked fgets_unlocked   fileno_unlocked fprintf_unlocked fputc_unlocked 
fputs_unlocked   fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked  
 putchar_unlocked putc_unlocked madvise mallinfo mallinfo2 fstatat getauxval \
-   clock_gettime munmap msync get_current_dir_name
+   clock_gettime munmap msync get_current_dir_name memrchr
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 3243472680c..fca0579574f 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1574,7 +1574,7 @@ AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoq \
popen sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap posix_fallocate setlocale \
gcc_UNLOCKED_FUNCS madvise mallinfo mallinfo2 fstatat getauxval \
-   clock_gettime munmap msync get_current_dir_name)
+   clock_gettime munmap msync get_current_dir_name memrchr)
 
 # At least for glibc, clock_gettime is in librt.  But don't pull that
 # in if it still doesn't give us the function we want.
diff --git a/include/libiberty.h b/include/libiberty.h
index f2e763a306a..d4e8791b14b 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -215,6 +215,16 @@ extern int ffs(int);
 extern int mkstemps(char *, int);
 #endif
 
+#if defined (HAVE_DECL_MKSTEMPS) && !HAVE_DECL_MKSTEMPS
+extern int mkstemps(char *, int);
+#endif
+
+/* Make memrchr available on systems that do not have it.  */
+#if !defined (__GNU_LIBRARY__ ) && !defined (__linux__) && \
+!defined (HAVE_MEMRCHR)
+extern void *memrchr(const void *, int, size_t);
+#endif
+
 /* Get the working directory.  The result is cached, so don't call
chdir() between calls to getpwd().  */
 
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 4870fa95f2f..ce54d88278d 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -139,8 +139,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c
\
ldirname.c  \
lrealpath.c \
make-relative-prefix.c  \
-   make-temp-file.c md5.c memchr.c memcmp.c memcpy.c memmem.c  \
-memmove.c mempcpy.c memset.c mkstemps.c\
+   make-temp-file.c md5.c memchr.c memrchr.c memcmp.c memcpy.c \
+   memmem.c memmove.c mempcpy.c memset.c mkstemps.c\
objalloc.c obstack.c\
partition.c pexecute.c  \
 pex-common.c pex-djgpp.c pex-msdos.c pex-one.c \
@@ -213,8 +213,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext) 
\
   

RE: [PATCH] cobol: Address some iconv issues.

2025-03-21 Thread Robert Dubner
As you have no doubt figured out, for input and output I am converting, as
best I can, from system locale to CP1252 for "ASCII" and CP1140 for
EBCDIC.

We can't use UTF-8 internally for most purposes, because going back to a
time before the Cuban Missile Crisis means that COBOL is built around an
assumption that a character is a byte is a character. Wide characters, and
the variable length codepoints of UTF-8, need not apply.

The language does have provision for that newfangled stuff, but we haven't
implemented it as yet.

So, please, stick with the default 1252 for existing code -- as you noted,
changing the page breaks some tests.  Handling additional code pages is a
can we've been kicking down the road.

(Actually, I have a "can cannon" that I use to launch cans over the
horizon.   But don't tell anybody.)

> -Original Message-
> From: Iain Sandoe 
> Sent: Friday, March 21, 2025 06:06
> To: rdub...@symas.com; gcc-patches@gcc.gnu.org
> Subject: [PATCH] cobol: Address some iconv issues.
> 
> Darwin/macOS installed libiconv does not accept // trailers on
> conversion codes; (it does accept // with TRANSLIT etc after it)
> Anyway the current setting causes the init_iconv to fail - and
> then that SEGVs later.  So let's at least print a warning if we
> fail to init the conversion.
> 
> Secondly, using Windows code page 1252 as a default seems overly
> restrictive. Ideally, we should be using something like "char"
> which represents the prevailing charset for the locale.  However
> that causes testsuite fails, since the tests are expecting CP1252
> or similar - for Apple/Darwin, we should use ISO-8859-1 (the actual
> system, in common with most modern systems uses UTF-8).
> 
> NOTE I seem to be unable to use LC_ALL= to override this (but I
> did not attempt to sort that out so far).  This is just a patch to
> allow build to succeed on Darwin/macOS.
> 
> gcc/cobol/ChangeLog:
> 
>   * symbols.cc : Initialise standard_internal to ISO8859-1
>   for Apple/Dawin platforms.
>   (cbl_field_t::internalize): Print a warning if we fail to
>   initialise iconv.
> 
> Signed-off-by: Iain Sandoe 
> ---
>  gcc/cobol/symbols.cc | 11 ++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
> index e078412e4ea..ebabcfd3070 100644
> --- a/gcc/cobol/symbols.cc
> +++ b/gcc/cobol/symbols.cc
> @@ -3566,7 +3566,12 @@ cbl_field_t::is_ascii() const {
>   * compilation, if it moves off the default, it adjusts only once, and
>   * never reverts.
>   */
> -static const char standard_internal[] = "CP1252//";
> +static const char standard_internal[] =
> +#if __APPLE__
> +"ISO8859-1";
> +#else
> +"CP1252//";
> +#endif
>  extern os_locale_t os_locale;
> 
>  static const char *
> @@ -3594,6 +3599,10 @@ cbl_field_t::internalize() {
>static  iconv_t cd = iconv_open(tocode, fromcode);
>static const size_t noconv = size_t(-1);
> 
> +  if (cd == (iconv_t)-1) {
> +yywarn("failed iconv_open tocode = '%s' fromcode = %s", tocode,
> fromcode);
> +  }
> +
>// Sat Mar 16 11:45:08 2024: require temporary environment for
testing
>if( getenv( "INTERNALIZE_NO") ) return data.initial;
> 
> --
> 2.39.2 (Apple Git-143)



Re: [PATCH] fnsplit: Set musttail call during function splitting if there are musttail calls [PR119376]

2025-03-21 Thread Richard Biener
On Fri, 21 Mar 2025, Jakub Jelinek wrote:

> Hi!
> 
> The just posted inliner patch can regress musttail calls if we perform
> function splitting and then inline the outlined body back into the original
> (or inline both the small function and outlined large body into something
> else).
> If there are any musttail calls, I think we need to call the outlined
> body using a musttail call, so that the inliner will preserve musttail
> attributes in the body.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2025-03-20  Jakub Jelinek  
> 
>   PR ipa/119376
>   * ipa-split.cc (split_function): Call gimple_call_set_must_tail
>   on the call to outlined partition if has_musttail and
>   !add_tsan_func_exit.
> 
>   * g++.dg/opt/musttail1.C: New test.
> 
> --- gcc/ipa-split.cc.jj   2025-01-02 11:23:02.827707968 +0100
> +++ gcc/ipa-split.cc  2025-03-20 13:54:57.541594191 +0100
> @@ -1473,6 +1473,8 @@ split_function (basic_block return_bb, c
>   args_to_pass[i] = arg;
>}
>call = gimple_build_call_vec (node->decl, args_to_pass);
> +  if (cur_node->get_fun ()->has_musttail && !add_tsan_func_exit)
> +gimple_call_set_must_tail (call, true);
>gimple_set_block (call, DECL_INITIAL (current_function_decl));
>args_to_pass.release ();
>  
> --- gcc/testsuite/g++.dg/opt/musttail1.C.jj   2025-03-20 15:07:38.236255098 
> +0100
> +++ gcc/testsuite/g++.dg/opt/musttail1.C  2025-03-20 15:08:48.625280661 
> +0100
> @@ -0,0 +1,35 @@
> +// PR ipa/119376
> +// { dg-do compile { target musttail } }
> +// { dg-options "-O2 -fdump-tree-optimized" }
> +// { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(\[^\n\r]*\\\); 
> \\\[tail call\\\] \\\[must tail call\\\]" 2 "optimized" } }
> +// { dg-final { scan-tree-dump-times "  \[^\n\r]* = foo \\\(\[^\n\r]*\\\); 
> \\\[tail call\\\]" 3 "optimized" } }
> +
> +int foo (int x);
> +typedef int (*F) (int);
> +int v;
> +
> +inline int
> +bar (int x)
> +{
> +  if (__builtin_expect (x == 42, 1))
> +return 1;
> +  [[gnu::musttail]] return foo (x + v * (x | v) * (x & v) * (x - v) * (x + v 
> * v));
> +}
> +
> +int
> +baz (int x)
> +{
> +  [[gnu::musttail]] return bar (x);
> +}
> +
> +int
> +qux (int x)
> +{
> +  return bar (x + 1);
> +}
> +
> +F
> +corge ()
> +{
> +  return &bar;
> +}
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


[COMMITTED 028/146] gccrs: asm: Fix clang warnings

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

Fixes a couple of warnings thrown by clang, with mismatched class/struct
usages and unused members.

gcc/rust/ChangeLog:

* ast/rust-expr.h: Remove invalid usage of `struct`.
* backend/rust-compile-asm.h: Remove unused `translated` member.
* backend/rust-compile-asm.cc (CompileAsm::CompileAsm): Remove usage
of `translated` member.
* checks/errors/rust-unsafe-checker.h: Mark visitor as `override`.
* hir/tree/rust-hir-expr.h (struct AnonConst): Remove unused `locus`
member.
---
 gcc/rust/ast/rust-expr.h | 24 ++--
 gcc/rust/backend/rust-compile-asm.cc |  5 ++--
 gcc/rust/backend/rust-compile-asm.h  |  2 --
 gcc/rust/checks/errors/rust-unsafe-checker.h |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.h|  4 ++--
 5 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 438d3d3b86e..483e599652b 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4810,14 +4810,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-In (const struct In &other)
+In (const In &other)
 {
   reg = other.reg;
 
   expr = other.expr->clone_expr ();
 }
 
-In operator= (const struct In &other)
+In operator= (const In &other)
 {
   reg = other.reg;
   expr = other.expr->clone_expr ();
@@ -4843,14 +4843,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-Out (const struct Out &other)
+Out (const Out &other)
 {
   reg = other.reg;
   late = other.late;
   expr = other.expr->clone_expr ();
 }
 
-Out operator= (const struct Out &other)
+Out operator= (const Out &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4876,14 +4876,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-InOut (const struct InOut &other)
+InOut (const InOut &other)
 {
   reg = other.reg;
   late = other.late;
   expr = other.expr->clone_expr ();
 }
 
-InOut operator= (const struct InOut &other)
+InOut operator= (const InOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4913,7 +4913,7 @@ public:
   rust_assert (this->out_expr != nullptr);
 }
 
-SplitInOut (const struct SplitInOut &other)
+SplitInOut (const SplitInOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4921,7 +4921,7 @@ public:
   out_expr = other.out_expr->clone_expr ();
 }
 
-SplitInOut operator= (const struct SplitInOut &other)
+SplitInOut operator= (const SplitInOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4953,12 +4953,12 @@ public:
 {
   rust_assert (this->expr != nullptr);
 }
-Sym (const struct Sym &other)
+Sym (const Sym &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
 }
 
-Sym operator= (const struct Sym &other)
+Sym operator= (const Sym &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
@@ -4981,12 +4981,12 @@ public:
   if (label_name.has_value ())
this->label_name = label_name.value ();
 }
-Label (const struct Label &other)
+Label (const Label &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
 }
 
-Label operator= (const struct Label &other)
+Label operator= (const Label &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index e85d08d0579..be553a3e70f 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -3,9 +3,8 @@
 namespace Rust {
 namespace Compile {
 
-CompileAsm::CompileAsm (Context *ctx)
-  : HIRCompileBase (ctx), translated (error_mark_node)
-{}
+CompileAsm::CompileAsm (Context *ctx) : HIRCompileBase (ctx) {}
+
 tree
 CompileAsm::tree_codegen_asm (HIR::InlineAsm &expr)
 {
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 402d950844c..4abd24eded4 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -28,8 +28,6 @@ namespace Compile {
 class CompileAsm : private HIRCompileBase
 {
 private:
-  tree translated;
-
   // RELEVANT MEMBER FUNCTIONS
 
   // The limit is 5 because it stands for the 5 things that the C version of
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h 
b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 96ccdc03c53..8dc6ab79071 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -113,7 +113,7 @@ private:
   virtual void visit (MatchExpr &expr) override;
   virtual void visit (AwaitExpr &expr) override;
   virtual void visit (AsyncBlockExpr &expr) override;
-  virtual void visit (InlineAsm &expr);
+  

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

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

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

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

>>> I don't think so, that's why I tried to explain above.
>>> "" is acceptable / accepted in arm_v8_2a_bf16_neon_ok
>>> (this is (A) (B) above, where the important parts are:
>>> -march=armv7-m -mcpu=unset -march=armv8.2-a+bf16
>>> (so -mfpu is set to the toolchain's default)
>>
>> That's never going to work reliably.  We need to check, somewhere, the full 
>> set of options we intend to pass to the compilation.  We can't assume that 
>> separately testing if A is ok and B is ok => A + B is ok.
>>
> 
> Hmmm I think I raised that problem years ago, because of the way the
> test system is designed...
> 
>>>
>>> but then the actual testcase is compiled with additional flags (C)
>>> defined by the test driver using arm_neon_fp16_ok
>>> C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a
>>> -mfpu=neon-fp16 -mfp16-format=ieee
>>>
>>> so the relevant parts of (A) (C) (B) are:
>>> -march=armv7-m  -mfpu=neon -mcpu=unset -march=armv7-a -mfpu=neon-fp16
>>> -mcpu=unset -march=armv8.2-a+bf16
>>> which can be simplified into
>>> -mfpu=neon-fp16 -march=armv8.2-a+bf16
>>>
>>> I think we need to start with -mfpu=auto instead of "", so that when
>>> -march=armv8.2-a+bf16 takes effect, we have cancelled any other -mfpu.
>>>
>>
>> Ideally a test shouldn't add any options in some test runs; that way we add 
>> some 'base configuration' coverage.  We obviously can't do that everywhere 
>> and there may still be cases where the system can't test anything useful at 
>> all (hopefully only when linking, or more is needed).
>>
> 
> Not sure to follow? If a test wants to check that a given feature
> works as expected, it has to use the appropriate options, doesn't it?

Not if the base configuration for the run (from the compiler config or from the 
RUNTEST flags) already supports that feature.

> 
> 
>>>
>>>

> +"-mfloat-abi=softfp -mfpu=neon-fp-armv8" \
> +"-mfloat-abi=hard -mfpu=neon-fp-armv8" ] {
>

Re: [PATCH] cobol: Replace quadratic loop removing std::set elements

2025-03-21 Thread James K. Lowden
On Thu, 20 Mar 2025 22:01:28 +
Jonathan Wakely  wrote:

> > LGTM.  I am gun-shy about using iterators while modifying
> > containers. I know there are rules.  :-/
> 
> Yes, the erased iterator is invalidated, but it returns an iterator to
> the next element after the erased one, so we can continue iterating
> from there instead of using the no-invalid one.

I did not know that!  

> The important thing is to _not_ increment in that case, because
> erasing *p and then pointing to the next element replaces the
> increment.

Clearly.  :-)  

> I've read them and they're straightforward.  If I
> > need to do more than just say that, please direct me.
> 
> OK, thanks. On that topic, should you be listed in the MAINTAINERS
> file? I see Bob in there, but don't see your name.

We're working on it.  I would like enter in MAINTAINERS this line:

COBOL front end James K. Lowden 

because that way the firm paying the freight gets to see its name in
lights.  

But as of today that address can't receive mail.  (We want it to
forward to the system I'm using now, so in short order all my
communications will use a business address instead of my personal one.)

I'm holding off committing that change until the address works, in case
there are other ramifications I don't know about.  

--jkl




[COMMITTED 129/146] gccrs: mappings: Add get_lang_item_node

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

This method errors out if the lang item has not been declared yet.

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::get_lang_item_node): New.
* util/rust-hir-map.h: New function.
---
 gcc/rust/util/rust-hir-map.cc | 10 ++
 gcc/rust/util/rust-hir-map.h  |  1 +
 2 files changed, 11 insertions(+)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index f11a77954ae..b94591e014c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1299,5 +1299,15 @@ Mappings::lookup_lang_item_node (LangItem::Kind 
item_type)
   return it->second;
 }
 
+NodeId
+Mappings::get_lang_item_node (LangItem::Kind item_type)
+{
+  if (auto lookup = lookup_lang_item_node (item_type))
+return *lookup;
+
+  rust_fatal_error (UNKNOWN_LOCATION, "failed to find lang item %qs",
+   LangItem::ToString (item_type).c_str ());
+}
+
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index aba51be4827..21e532812ff 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -261,6 +261,7 @@ public:
 
   void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id);
   tl::optional lookup_lang_item_node (LangItem::Kind item_type);
+  NodeId get_lang_item_node (LangItem::Kind item_type);
 
   // This will fatal_error when this lang item does not exist
   DefId get_lang_item (LangItem::Kind item_type, location_t locus);
-- 
2.45.2



[COMMITTED 076/146] gccrs: lang-item: Remove unused NodeId from LangItemPath

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

gcc/rust/ChangeLog:

* ast/rust-path.h: Adapt children of Path to fix some NodeId issues.
---
 gcc/rust/ast/rust-path.h | 76 +++-
 1 file changed, 37 insertions(+), 39 deletions(-)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index bece60f95ed..563ad52a9d6 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -599,9 +599,6 @@ public:
 return Pattern::Kind::Path;
   }
 
-  location_t get_locus () const override { return locus; }
-  NodeId get_node_id () const override { return node_id; }
-
   std::unique_ptr clone_path ()
   {
 return std::unique_ptr (clone_path_impl ());
@@ -613,22 +610,19 @@ public:
   }
 
 protected:
-  location_t locus;
-  NodeId node_id;
-
-  Path (location_t locus, NodeId node_id) : locus (locus), node_id (node_id) {}
-
   virtual Path *clone_path_impl () const = 0;
 };
 
 class RegularPath : public Path
 {
   std::vector segments;
+  NodeId node_id;
+  location_t locus;
 
 public:
   explicit RegularPath (std::vector &&segments,
location_t locus, NodeId node_id)
-: Path (locus, node_id), segments (std::move (segments))
+: segments (std::move (segments)), node_id (node_id), locus (locus)
   {}
 
   std::string as_string () const override;
@@ -657,17 +651,25 @@ public:
 return new RegularPath (std::vector (segments), locus,
node_id);
   }
+
+  NodeId get_node_id () const override { return node_id; }
+  location_t get_locus () const override { return locus; }
 };
 
 class LangItemPath : public Path
 {
-  NodeId lang_item;
-
   LangItem::Kind kind;
+  NodeId node_id;
+  location_t locus;
+
+  LangItemPath (LangItem::Kind kind, NodeId node_id, location_t locus)
+: kind (kind), node_id (node_id), locus (locus)
+  {}
 
 public:
   explicit LangItemPath (LangItem::Kind kind, location_t locus)
-: Path (locus, Analysis::Mappings::get ().get_next_node_id ()), kind (kind)
+: kind (kind), node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  locus (locus)
   {}
 
   Path::Kind get_path_kind () const override { return Path::Kind::LangItem; }
@@ -676,12 +678,15 @@ public:
 
   Path *clone_path_impl () const override
   {
-return new LangItemPath (kind, locus);
+return new LangItemPath (kind, node_id, locus);
   }
 
   std::string as_string () const override;
 
   LangItem::Kind get_lang_item_kind () { return kind; }
+
+  NodeId get_node_id () const override { return node_id; }
+  location_t get_locus () const override { return locus; }
 };
 
 /* AST node representing a path-in-expression pattern (path that allows
@@ -739,11 +744,10 @@ public:
   // Returns whether path in expression is in an error state.
   bool is_error () const
   {
-// FIXME: Cleanup
 if (path->get_path_kind () == Path::Kind::Regular)
   return !static_cast (*path).has_segments ();
 
-return false;
+rust_unreachable ();
   }
 
   /* Converts PathInExpression to SimplePath if possible (i.e. no generic
@@ -822,7 +826,7 @@ public:
 if (path->get_path_kind () == Path::Kind::Regular)
   return static_cast (*path).get_segments ().size () == 1;
 
-return false;
+rust_unreachable ();
   }
 
   Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
@@ -1201,17 +1205,13 @@ public:
   }
 };
 
-// Path used inside types
 class TypePath : public TypeNoBounds, public Path
 {
   bool has_opening_scope_resolution;
   std::vector > segments;
+  location_t locus;
 
 protected:
-  Kind get_path_kind () const override { return Kind::Type; }
-
-  Path *clone_path_impl () const override { return new TypePath (*this); }
-
   /* Use covariance to implement clone function as returning this object
* rather than base */
   TypePath *clone_type_no_bounds_impl () const override
@@ -1234,23 +1234,23 @@ public:
   static TypePath create_error ()
   {
 return TypePath (std::vector > (),
-UNKNOWN_LOCATION);
+UNDEF_LOCATION);
   }
 
   // Constructor
   TypePath (std::vector > segments,
location_t locus, bool has_opening_scope_resolution = false)
 : TypeNoBounds (),
-  Path (locus, Analysis::Mappings::get ().get_next_node_id ()),
   has_opening_scope_resolution (has_opening_scope_resolution),
-  segments (std::move (segments))
+  segments (std::move (segments)), locus (locus)
   {}
 
   // Copy constructor with vector clone
   TypePath (TypePath const &other)
-: Path (other.locus, other.Path::get_node_id ()),
-  has_opening_scope_resolution (other.has_opening_scope_resolution)
+: has_opening_scope_resolution (other.has_opening_scope_resolution),
+  locus (other.locus)
   {
+node_id = other.node_id;
 segments.reserve (other.segments.size ());
 for (const auto &e : other.segments)
   segments.push_back (e->clone_type_path_segment ());
@@ -1259,7 +1259,9 @@ public:
   // Overloaded assignment oper

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

2025-03-21 Thread Jakub Jelinek
On Fri, Mar 21, 2025 at 07:12:23PM +0100, Richard Biener wrote:
> So this is the following hunk where I totally misunderstood
> real_to_target when converting this from native_encode_expr and
> a tree to using REAL_VALUE_TYPE:
> 
> @@ -15702,13 +15714,16 @@ initial_from_float128(cbl_field_t *field, 
> _Float128 va
> lue)
>switch( field->data.capacity )
>  {
>  case 4:
> -  *(_Float32 *)retval = (_Float32) value;
> + value = real_value_truncate (TYPE_MODE (FLOAT), value);
> + real_to_target ((long *)retval, &value, TYPE_MODE (FLOAT));
>break;
>  case 8:
> -  *(_Float64 *)retval = (_Float64) value;
> + value = real_value_truncate (TYPE_MODE (DOUBLE), value);
> + real_to_target ((long *)retval, &value, TYPE_MODE (DOUBLE));
>break;
>  case 16:
> -  *(_Float128 *)retval = (_Float128) value;
> + value = real_value_truncate (TYPE_MODE (FLOAT128), value);
> + real_to_target ((long *)retval, &value, TYPE_MODE (FLOAT128));
>break;
> 
> an incremental fix is the following, exposing a native_encode_real
> with REAL_VALUE_TYPE input would be nicer, but going back to
> native_encode_expr works.  So - can you apply the following and
> re-try?  A testcase for the 0.01 vs. 0.0 thing would be nice to have
> as well.

I think you could avoid the jump through build_real + native_encode_expr
by moving parts of native_encode_real into a helper function and export
that helper function from fold-const.h (unless you want to duplicate it).
Basically add a helper where you pass REAL_VALUE_TYPE * + scalar_float_mode
instead of tree.
real_to_target writes up to 6 longs where each long contains 32 bits
and then one needs to store bytes from that according to target endianity.

> --- a/gcc/cobol/genapi.cc
> +++ b/gcc/cobol/genapi.cc
> @@ -15710,20 +15710,24 @@ initial_from_float128(cbl_field_t *field)
>  
>  case FldFloat:
>{
> +  tree tem;
>retval = (char *)xmalloc(field->data.capacity);
>switch( field->data.capacity )
>  {
>  case 4:
> value = real_value_truncate (TYPE_MODE (FLOAT), value);
> -   real_to_target ((long *)retval, &value, TYPE_MODE (FLOAT));
> +   tem = build_real (FLOAT, value);
> +   native_encode_expr (tem, (unsigned char *)retval, 4, 0);
>break;

Jakub



Re: [PATCH 09/10] testsuite: aarch64: arm: Fix -mfpu=auto support in fp16_neon_ok

2025-03-21 Thread Richard Earnshaw (lists)
On 20/03/2025 16:15, Christophe Lyon wrote:
> Like a previous patch, replace "" with -mfpu=auto to match the
> intended effect of -march=armv8.2-a+fp16.
> 
> No visible change because the effect is masked by other effective
> targets used in the tests, done for consistency.
> 
>   gcc/testsuite/
>   * lib/target-supports.exp
>   (check_effective_target_arm_v8_2a_bf16_neon_ok_nocache):
>   Conditionally use -mfpu=auto.

Again, see comments on patch 6.

R.

> ---
>  gcc/testsuite/lib/target-supports.exp | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/testsuite/lib/target-supports.exp 
> b/gcc/testsuite/lib/target-supports.exp
> index c2df22d2255..587db04b95e 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -6661,6 +6661,7 @@ proc 
> check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
>  global et_arm_v8_2a_fp16_neon_flags
>  set et_arm_v8_2a_fp16_neon_flags ""
>  set cpu_unset ""
> +set fpu_auto ""
>  
>  if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } {
>   return 0;
> @@ -6668,12 +6669,15 @@ proc 
> check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } {
>  
>  if { [istarget arm*-*-*] } {
>   set cpu_unset "-mcpu=unset"
> + set fpu_auto "-mfpu=auto"
>  }
>  
>  # Iterate through sets of options to find the compiler flags that
>  # need to be added to the -march option.
> -foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \
> -"-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} {
> +foreach flags [list "$fpu_auto" \
> +"-mfpu=neon-fp-armv8" \
> +"-mfloat-abi=softfp" \
> +"-mfpu=neon-fp-armv8 -mfloat-abi=softfp"] {
>   if { [check_no_compiler_messages_nocache \
> arm_v8_2a_fp16_neon_ok object {
>   #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)



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

2025-03-21 Thread Robert Dubner
Just so I understand your terminology:

Am I to understand that by pulling master, and then applying the patch in
this message, that the source code will be at the point you are ready to
have me test?

I am more used to being three hours ahead of the US west coast than I am
to being five hours behind the avalanche of activity that you folks are
happy with!

> -Original Message-
> From: Richard Biener 
> Sent: Friday, March 21, 2025 08:57
> To: gcc-patches@gcc.gnu.org
> Cc: rdub...@symas.com; Jakub Jelinek 
> Subject: [PATCH] change cbl_field_data_t::etc_t::value from _Float128 to
> tree
> 
> The following removes the main instance of _Float128 use in the cobol
> frontend and replaces it with a tree for cbl_field_data_t::etc_t::value
> and with REAL_VALUE_TYPE in some helpers.
> 
> The default value is changed to a float128_type_node zero from 0.0.
> 
> get_power_of_ten was picked from Jakubs PR119242 patch, it doesn't build
> on
> its own so I've included it here.
> 
> This builds and tests OK on x86_64-linux with the in-tree testsuite.
> Please give it extended testing.  All prerequesites have been pushed
> to master already.
> 
> Thanks,
> Richard.
> 
>   PR cobol/119241
>   PR cobol/119242
>   * genutil.h (get_power_of_ten): Return FIXED_WIDE_INT(128).
>   * genutil.cc (get_power_of_ten): Produce FIXED_WIDE_INT(128)
>   instead of __int128.
>   (scale_by_power_of_ten_N): Adjust.
>   (copy_little_endian_into_place): Likewise.
>   * genapi.cc (mh_source_is_literalN): Likewise.
>   * symbols.h (cbl_field_data_t::etc_t::value): Make a tree.
>   (cbl_field_data_t::etc_t::etc_t): Adjust.
>   (cbl_field_data_t::cbl_field_data_t): Likewise.
>   (cbl_field_data_t::value_of): Likewise.
>   (cbl_field_data_t::operator=): Likewise.
>   (cbl_field_data_t::valify): Likewise.
>   * symbols.cc (cbl_occurs_t::subscript_ok): Likewise.
>   * genapi.h (initial_from_float128): Remove.
>   * genapi.cc (initial_from_float128): Make local and adjust.
>   (initialize_variable_internal): Adjust.
>   (get_binary_value_from_float): Likewise.
>   (psa_FldLiteralN): Simplify.
>   (parser_display_internal): Adjust.
>   (mh_source_is_literalN): Likewise.
>   (real_powi10): New helper.
>   (binary_initial_from_float128): Adjust.
>   (digits_from_float128): Likewise.
>   (parser_symbol_add): Likewise.
>   * parse.y (YYVAL): Use REAL_VALUE_TYPE instead of _Float128.
>   (string_of): Adjust and add overload from tree.
>   (field): Adjust.
>   (const_value): Likewise.
>   (value78): Likewise.
>   (data_descr1): Likewise.
>   (value_clause): Likewise.
>   (allocate): Likewise.
>   (move_tgt): Likewise.
>   (cc_expr): Likewise.
>   (cce_factor): Likewise.
>   (literal_refmod_valid): Likewise.
> 
> gcc/testsuite/
>   * cobol.dg/literal1.cob: New testcase.
>   * cobol.dg/output1.cob: Likewise.
> Co-authored-by: Jakub Jelinek 
> ---
>  gcc/cobol/genapi.cc | 222 +++-
>  gcc/cobol/genapi.h  |   3 -
>  gcc/cobol/genutil.cc|  26 ++--
>  gcc/cobol/genutil.h |   2 +-
>  gcc/cobol/parse.y   | 118 ---
>  gcc/cobol/symbols.cc|  15 +-
>  gcc/cobol/symbols.h |  21 ++-
>  gcc/testsuite/cobol.dg/literal1.cob |  14 ++
>  gcc/testsuite/cobol.dg/output1.cob  |  14 ++
>  9 files changed, 251 insertions(+), 184 deletions(-)
>  create mode 100644 gcc/testsuite/cobol.dg/literal1.cob
>  create mode 100644 gcc/testsuite/cobol.dg/output1.cob
> 
> diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
> index 8f4f9b21370..382a796ec18 100644
> --- a/gcc/cobol/genapi.cc
> +++ b/gcc/cobol/genapi.cc
> @@ -52,6 +52,7 @@
>  #include "../../libgcobol/charmaps.h"
>  #include "../../libgcobol/valconv.h"
>  #include "show_parse.h"
> +#include "fold-const.h"
> 
>  extern int yylineno;
> 
> @@ -1041,7 +1042,9 @@ initialize_variable_internal( cbl_refer_t refer,
>default:
>  {
>  char ach[128];
> -strfromf128(ach, sizeof(ach), "%.16E", parsed_var-
> >data.value_of());
> + real_to_decimal (ach,
> +  TREE_REAL_CST_PTR
(parsed_var->data.value_of()),
> +  sizeof(ach), 16, 0);
>  SHOW_PARSE_TEXT(ach);
>  break;
>  }
> @@ -1296,8 +1299,8 @@ get_binary_value_from_float(tree value,
>gg_assign(fvalue,
>  gg_multiply(fvalue,
>  gg_float(ftype,
> - build_int_cst_type(INT,
> -
> get_power_of_ten(rdigits);
> + wide_int_to_tree(INT,
> +
> get_power_of_ten(rdigits);
> 
>// And we need to throw away any digits to the left of the leftmost
> digits:
>// At least, we need to do so in principl.  I am deferring this
problem
> unt

[COMMITTED 123/146] gccrs: collect-lang-items: Display attribute upon error finding it

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

gcc/rust/ChangeLog:

* ast/rust-collect-lang-items.cc (get_lang_item_attr): Show unknown 
attribute upon error.
---
 gcc/rust/ast/rust-collect-lang-items.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index 50d134a429f..168123ee56e 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -36,7 +36,8 @@ get_lang_item_attr (const T &maybe_lang_item)
   const auto &str_path = attr.get_path ().as_string ();
   if (!Analysis::Attributes::is_known (str_path))
{
- rust_error_at (attr.get_locus (), "unknown attribute");
+ rust_error_at (attr.get_locus (), "unknown attribute %qs",
+str_path.c_str ());
  continue;
}
 
-- 
2.45.2



Re: [PATCH 04/10] testsuite: aarch64: restore torture options in vml[as]_float_not_used.c

2025-03-21 Thread Richard Earnshaw (lists)
On 20/03/2025 16:15, Christophe Lyon wrote:
> Remove dg-options, so that the test is executed as expected using the
> options defined by advsimd-intrinsics.exp.
> 
>   gcc/testsuite/
>   * gcc.target/aarch64/advsimd-intrinsics/vmla_float_not_fused.c:
>   Remove dg-options.
>   * gcc.target/aarch64/advsimd-intrinsics/vmls_float_not_fused.c:
>   Likewise.
> ---
>  .../aarch64/advsimd-intrinsics/vmla_float_not_fused.c   | 2 --
>  .../aarch64/advsimd-intrinsics/vmls_float_not_fused.c   | 2 --
>  2 files changed, 4 deletions(-)
> 
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmla_float_not_fused.c 
> b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmla_float_not_fused.c
> index 18d176794f0..8f1d012230a 100644
> --- 
> a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmla_float_not_fused.c
> +++ 
> b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmla_float_not_fused.c
> @@ -1,7 +1,5 @@
>  /* { dg-do compile } */
>  /* { dg-skip-if "" { arm*-*-* } } */
> -/* { dg-options "-O3" } */
> -
>  
>  #include 
>  
> diff --git 
> a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmls_float_not_fused.c 
> b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmls_float_not_fused.c
> index 6c51d042de9..f4345644e08 100644
> --- 
> a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmls_float_not_fused.c
> +++ 
> b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmls_float_not_fused.c
> @@ -1,7 +1,5 @@
>  /* { dg-do compile } */
>  /* { dg-skip-if "" { arm*-*-* } } */
> -/* { dg-options "-O3" } */
> -
>  
>  #include 
>  


OK.

R.


Re: [PATCH 2/2] libstdc++: Fix std.compat exports of and

2025-03-21 Thread Tomasz Kaminski
On Thu, Mar 20, 2025 at 8:19 PM Jonathan Wakely  wrote:

> libstdc++-v3/ChangeLog:
>
> * src/c++23/std.compat.cc.in: Only export  and
>  contents for C++26 and later.
> ---
>
> Tested by compiling and importing both std and std.compat.
>
LGTM

>
>  libstdc++-v3/src/c++23/std.compat.cc.in | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/src/c++23/std.compat.cc.in
> b/libstdc++-v3/src/c++23/std.compat.cc.in
> index ba7ed0312ab..344502195b1 100644
> --- a/libstdc++-v3/src/c++23/std.compat.cc.in
> +++ b/libstdc++-v3/src/c++23/std.compat.cc.in
> @@ -21,11 +21,15 @@
>  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  // .
>
> +module;
> +
> +#include 
> +#include 
> +
>  export module std.compat;
>  export import std;
>
> -#include 
> -
> +#ifdef __STDC_VERSION_STDBIT_H__
>  // 
>  export
>  {
> @@ -52,7 +56,9 @@ _GLIBCXX_STDBIT_FUNC(stdc_bit_floor);
>  _GLIBCXX_STDBIT_FUNC(stdc_bit_ceil);
>  #undef _GLIBCXX_STDBIT_FUNC
>  }
> +#endif
>
> +#ifdef __STDC_VERSION_STDCKDINT_H__
>  // 
>  export
>  {
> @@ -60,6 +66,7 @@ export
>using __gnu_cxx::ckd_sub;
>using __gnu_cxx::ckd_mul;
>  }
> +#endif
>
>  #define STD_COMPAT 1
>
> --
> 2.49.0
>
>


[COMMITTED 104/146] gccrs: nr2.0: Resolve Self inside impl blocks

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Insert a definition for Self when visiting
InherentImpl and TraitImpl instances.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Add visitors for InherentImpl and TraitImpl.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 4aca709263c..4c6664f104b 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -103,6 +103,32 @@ TopLevel::visit (AST::Trait &trait)
   DefaultResolver::visit (trait);
 }
 
+void
+TopLevel::visit (AST::InherentImpl &impl)
+{
+  auto inner_fn = [this, &impl] () {
+insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
+impl.get_type (), Namespace::Types);
+
+AST::DefaultASTVisitor::visit (impl);
+  };
+
+  ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+}
+
+void
+TopLevel::visit (AST::TraitImpl &impl)
+{
+  auto inner_fn = [this, &impl] () {
+insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
+impl.get_type (), Namespace::Types);
+
+AST::DefaultASTVisitor::visit (impl);
+  };
+
+  ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+}
+
 void
 TopLevel::visit (AST::TraitItemType &trait_item)
 {
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 64d2174a7be..fabcb5bf707 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -148,6 +148,8 @@ private:
 
   void visit (AST::Module &module) override;
   void visit (AST::Trait &trait) override;
+  void visit (AST::InherentImpl &impl) override;
+  void visit (AST::TraitImpl &impl) override;
   void visit (AST::TraitItemType &trait_item) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index af7d105debc..9b1ee7ceaf9 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -39,13 +39,11 @@ generics6.rs
 generics9.rs
 if_let_expr.rs
 issue-1019.rs
-issue-1031.rs
 issue-1034.rs
 issue-1129-2.rs
 issue-1130.rs
 issue-1173.rs
 issue-1272.rs
-issue-1289.rs
 issue-1447.rs
 issue-1483.rs
 issue-1725-1.rs
@@ -85,7 +83,6 @@ issue-855.rs
 issue-925.rs
 iterators1.rs
 lookup_err1.rs
-macros/mbe/macro-issue1233.rs
 macros/mbe/macro-issue1400.rs
 macros/mbe/macro13.rs
 macros/mbe/macro15.rs
-- 
2.45.2



[COMMITTED 139/146] gccrs: derive(Clone): Add note about Clone::clone()

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc (DeriveClone::clone_call): Mention using 
`clone_fn`
lang item in the future.
---
 gcc/rust/expand/rust-derive-clone.cc | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 2f733fae910..b8c92dcc6fe 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -30,6 +30,15 @@ DeriveClone::clone_call (std::unique_ptr &&to_clone)
   // $crate::core::clone::Clone::clone for the fully qualified path - we don't
   // link with `core` yet so that might be an issue. Use `Clone::clone` for 
now?
   // TODO: Factor this function inside the DeriveAccumulator
+
+  // Interestingly, later versions of Rust have a `clone_fn` lang item which
+  // corresponds to this. But because we are first targeting 1.49, we cannot 
use
+  // it yet. Once we target a new, more recent version of the language, we'll
+  // have figured out how to compile and distribute `core`, meaning we'll be
+  // able to directly call `::core::clone::Clone::clone()`
+
+  // Not sure how to call it properly in the meantime...
+
   auto path = std::unique_ptr (
 new PathInExpression (builder.path_in_expression ({"Clone", "clone"})));
 
@@ -79,10 +88,7 @@ DeriveClone::clone_impl (
   std::unique_ptr &&clone_fn, std::string name,
   const std::vector> &type_generics)
 {
-  // should that be `$crate::core::clone::Clone` instead?
-  auto segments = std::vector> ();
-  segments.emplace_back (builder.type_path_segment ("Clone"));
-  auto clone = TypePath (std::move (segments), loc);
+  auto clone = builder.type_path (LangItem::Kind::CLONE);
 
   auto trait_items = std::vector> ();
   trait_items.emplace_back (std::move (clone_fn));
-- 
2.45.2



[committed 1/2] arm: testsuite: memcpy-aligned requires unaligned accesses

2025-03-21 Thread Richard Earnshaw
This test is designed to check that if one of the operands is
aligned (but the other isn't) we expand to a sensible sequence and
bypass most of the overhead of doing a memcpy.  But on targets without
unaligned accessess, we still end up calling memcpy.  It's then a
lottery as to whether the prologue and epilogue code, plus the
set-up for the memcpy itself, generate instructions that match the
scan patterns.

Since in those cases we're not actually testing what the test is looking
for anyway, just skip the test on strict-alignment targets.

gcc/testsuite:
* gcc.target/arm/memcpy-aligned-1.c: Require unaligned accesses.
---
 gcc/testsuite/gcc.target/arm/memcpy-aligned-1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.target/arm/memcpy-aligned-1.c 
b/gcc/testsuite/gcc.target/arm/memcpy-aligned-1.c
index 852b391388b..42e2a6bbdf7 100644
--- a/gcc/testsuite/gcc.target/arm/memcpy-aligned-1.c
+++ b/gcc/testsuite/gcc.target/arm/memcpy-aligned-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-require-effective-target arm_unaligned } */
 /* { dg-options "-O2 -save-temps" } */
 
 void *memcpy (void *dest, const void *src, unsigned int n);
-- 
2.34.1



[COMMITTED 146/146] gccrs: nr2.0: late: Better format PathInExpression resolution

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Improve 
formatting.
---
 .../resolve/rust-late-name-resolver-2.0.cc | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 9da56ea3214..5aea6a43ed6 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -218,19 +218,12 @@ Late::visit (AST::PathInExpression &expr)
   // in a function item` error here?
   // do we emit it in `get`?
 
-  rust_debug ("[ARTHUR]: %s", expr.as_simple_path ().as_string ().c_str ());
+  auto resolved
+= ctx.values.resolve_path (expr.get_segments ()).or_else ([&] () {
+   return ctx.types.resolve_path (expr.get_segments ());
+  });
 
-  tl::optional resolved = tl::nullopt;
-
-  if (auto value = ctx.values.resolve_path (expr.get_segments ()))
-{
-  resolved = value;
-}
-  else if (auto type = ctx.types.resolve_path (expr.get_segments ()))
-{
-  resolved = type;
-}
-  else
+  if (!resolved)
 {
   rust_error_at (expr.get_locus (),
 "could not resolve path expression: %qs",
@@ -244,6 +237,7 @@ Late::visit (AST::PathInExpression &expr)
 expr.as_string ().c_str ());
   return;
 }
+
   ctx.map_usage (Usage (expr.get_node_id ()),
 Definition (resolved->get_node_id ()));
 }
-- 
2.45.2



[pushed] c++: fix return type of __cxa_bad_array_new_length

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

Thomas Schwinge checked that it addresses the problem on nvptx.

-- 8< --

We were lying about the return type, but that's not necessary; we already
need to handle a COND_EXPR where one side is void for THROW_EXPR.

This fixes an execution failure on nvptx:
error: Prototype doesn't match for '__cxa_throw_bad_array_new_length'

gcc/cp/ChangeLog:

* init.cc (throw_bad_array_new_length): Returns void.
---
 gcc/cp/init.cc | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index ce6e58e05f2..e589e45e891 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -2810,8 +2810,7 @@ diagnose_uninitialized_cst_or_ref_member (tree type, bool 
using_new, bool compla
 }
 
 /* Call __cxa_bad_array_new_length to indicate that the size calculation
-   overflowed.  Pretend it returns sizetype so that it plays nicely in the
-   COND_EXPR.  */
+   overflowed.  */
 
 tree
 throw_bad_array_new_length (void)
@@ -2823,7 +2822,7 @@ throw_bad_array_new_length (void)
   fn = get_global_binding (name);
   if (!fn)
fn = push_throw_library_fn
- (name, build_function_type_list (sizetype, NULL_TREE));
+ (name, build_function_type_list (void_type_node, NULL_TREE));
 }
 
   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);

base-commit: 618c42d23726be6e2086d452d6718abe5e0daca8
-- 
2.48.1



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

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

That's never going to work reliably.  We need to check, somewhere, the full set 
of options we intend to pass to the compilation.  We can't assume that 
separately testing if A is ok and B is ok => A + B is ok.

> 
> but then the actual testcase is compiled with additional flags (C)
> defined by the test driver using arm_neon_fp16_ok
> C = -mfpu=neon -mfloat-abi=softfp -mcpu=unset -march=armv7-a
> -mfpu=neon-fp16 -mfp16-format=ieee
> 
> so the relevant parts of (A) (C) (B) are:
> -march=armv7-m  -mfpu=neon -mcpu=unset -march=armv7-a -mfpu=neon-fp16
> -mcpu=unset -march=armv8.2-a+bf16
> which can be simplified into
> -mfpu=neon-fp16 -march=armv8.2-a+bf16
> 
> I think we need to start with -mfpu=auto instead of "", so that when
> -march=armv8.2-a+bf16 takes effect, we have cancelled any other -mfpu.
> 

Ideally a test shouldn't add any options in some test runs; that way we add 
some 'base configuration' coverage.  We obviously can't do that everywhere and 
there may still be cases where the system can't test anything useful at all 
(hopefully only when linking, or more is needed).

> 
> 
>>
>>> +"-mfloat-abi=softfp -mfpu=neon-fp-armv8" \
>>> +"-mfloat-abi=hard -mfpu=neon-fp-armv8" ] {
>>>   if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok 
>>> object {
>>>   #include 
>>>   #if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)
>>
>> In fact, since aarch64 doesn't support -mfpu at all, only "" is ever going 
>> to work here, so perhaps we can recast all this code, perhaps along the 
>> lines of that in check_effective_target_arm_neon_h_ok_nocache so that we 
>> don't need to actually try to include arm_neon.h at all while figuring out 
>> the options.
>>
> 
> Maybe.
> 
> OTOH, actually including arm_neon.h is guaranteed to give the right
> answer to the question "which flags do we need to be able to include
> arm_neon.h?", rather than using several conditions tha

[COMMITTED 109/146] gccrs: rust/intrinsic: add new "catch_unwind" variant of API

2025-03-21 Thread arthur . cohen
From: liushuyu 

gcc/rust/ChangeLog:
* backend/rust-compile-intrinsic.cc: add the new `catch_unwind` variant
of the `try` intrinsic: this variant can be seen on Rust 1.78+
and returns `()` instead of `i32`.
---
 gcc/rust/backend/rust-compile-intrinsic.cc | 57 ++
 1 file changed, 47 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 77b67c36c3e..0f054588220 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -196,7 +196,15 @@ expect_handler (bool likely)
 }
 
 static tree
-try_handler (Context *ctx, TyTy::FnType *fntype);
+try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api);
+
+const static std::function
+try_handler (bool is_new_api)
+{
+  return [is_new_api] (Context *ctx, TyTy::FnType *fntype) {
+return try_handler_inner (ctx, fntype, is_new_api);
+  };
+}
 
 inline tree
 sorry_handler (Context *ctx, TyTy::FnType *fntype)
@@ -245,7 +253,8 @@ static const std::mapget_params ().size () == 3);
 
@@ -1283,6 +1292,13 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
 
   enter_intrinsic_block (ctx, fndecl);
 
+  // The following tricks are needed to make sure the try-catch blocks are not
+  // optimized away
+  TREE_READONLY (fndecl) = 0;
+  DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+  DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
+   NULL_TREE, DECL_ATTRIBUTES (fndecl));
+
   // BUILTIN try_handler FN BODY BEGIN
   // setup the params
   std::vector param_vars;
@@ -1296,15 +1312,31 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
   tree try_fn = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
   tree user_data = Backend::var_expression (param_vars[1], UNDEF_LOCATION);
   tree catch_fn = Backend::var_expression (param_vars[2], UNDEF_LOCATION);
-  tree normal_return_stmt
-= Backend::return_statement (fndecl, integer_zero_node, BUILTINS_LOCATION);
-  tree error_return_stmt
-= Backend::return_statement (fndecl, integer_one_node, BUILTINS_LOCATION);
+  tree normal_return_stmt = NULL_TREE;
+  tree error_return_stmt = NULL_TREE;
   tree try_call = Backend::call_expression (try_fn, {user_data}, nullptr,
BUILTINS_LOCATION);
   tree catch_call = NULL_TREE;
   tree try_block = Backend::block (fndecl, enclosing_scope, {}, UNDEF_LOCATION,
   UNDEF_LOCATION);
+
+  if (is_new_api)
+{
+  auto ret_type = TyTyResolveCompile::get_unit_type ();
+  auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
+  UNDEF_LOCATION);
+  normal_return_stmt
+   = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+  error_return_stmt
+   = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+}
+  else
+{
+  normal_return_stmt = Backend::return_statement (fndecl, 
integer_zero_node,
+ BUILTINS_LOCATION);
+  error_return_stmt = Backend::return_statement (fndecl, integer_one_node,
+BUILTINS_LOCATION);
+}
   Backend::block_add_statements (try_block,
 std::vector{try_call,
   normal_return_stmt});
@@ -1320,17 +1352,22 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
 = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1,
   integer_zero_node);
   catch_call = Backend::call_expression (catch_fn, {user_data, eh_pointer},
-nullptr, BUILTINS_LOCATION);
+NULL_TREE, BUILTINS_LOCATION);
 
   tree catch_block = Backend::block (fndecl, enclosing_scope, {},
 UNDEF_LOCATION, UNDEF_LOCATION);
   Backend::block_add_statements (catch_block,
 std::vector{catch_call,
   error_return_stmt});
+  // emulate what cc1plus is doing for C++ try-catch
+  tree inner_eh_construct
+= Backend::exception_handler_statement (catch_call, NULL_TREE,
+   error_return_stmt,
+   BUILTINS_LOCATION);
   // TODO(liushuyu): eh_personality needs to be implemented as a runtime thing
   auto eh_construct
-= Backend::exception_handler_statement (try_block, catch_block, NULL_TREE,
-   BUILTINS_LOCATION);
+= Backend::exception_handler_statement (try_block, inner_eh_construct,
+   NULL_TREE, BUILTINS_LOCATION);
   ctx->add_statement (eh_construct);
   // BUILTIN try_handler FN BODY END
   finalize_intri

[patch, avr] Add "used" attribute to code in .initN and .finiN

2025-03-21 Thread Georg-Johann Lay

For code in .initN and .finiN there are no calls, hence let the
compiler add "used" attribute.

Ok for trunk?

Johann

--

AVR: Add attribute "used" for code in .initN and .initN sections.

Code in .initN and .initN sections is never called since these
sections are special and part of the startup resp. shutdown code.
This patch adds attribute "used" so they won't be optimized out.

gcc/
* config/avr/avr.cc (avr_attrs_section_name): New function.
(avr_insert_attributes): Add "used" attribute to functions
in .initN and .finiN.commit e0e33695a97576cd8cc23da5d5162e4fa595e7ba
Author: Georg-Johann Lay 
Date:   Fri Mar 21 14:29:13 2025 +0100

AVR: Add attribute "used" for code in .initN and .initN sections.

Code in .initN and .initN sections is never called since these
sections are special and part of the startup resp. shutdown code.
This patch adds attribute "used" so they won't be optimized out.

gcc/
* config/avr/avr.cc (avr_attrs_section_name): New function.
(avr_insert_attributes): Add "used" attribute to functions
in .initN and .finiN.

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 71c03b42148..0ce06a1e580 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -11736,6 +11736,23 @@ avr_handle_isr_attribute (tree node, tree *attrs, const char *name)
 }
 
 
+/* Helper for `avr_insert_attributes'.
+   Return the section name from attribute "section" in attribute list ATTRS.
+   When no "section" attribute is present, then return nullptr.  */
+
+static const char *
+avr_attrs_section_name (tree attrs)
+{
+  if (tree a_sec = lookup_attribute ("section", attrs))
+if (TREE_VALUE (a_sec))
+  if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec)))
+	if (TREE_CODE (t_section_name) == STRING_CST)
+	  return TREE_STRING_POINTER (t_section_name);
+
+  return nullptr;
+}
+
+
 /* Implement `TARGET_INSERT_ATTRIBUTES'.  */
 
 static void
@@ -11768,25 +11785,31 @@ avr_insert_attributes (tree node, tree *attributes)
 			   NULL, *attributes);
 }
 
+  const char *section_name = avr_attrs_section_name (*attributes);
+
+  // When the function is in an .initN or .finiN section, then add "used"
+  // since such functions are never called.
+  if (section_name
+  && strlen (section_name) == strlen (".init*")
+  && IN_RANGE (section_name[5], '0', '9')
+  && (startswith (section_name, ".init")
+	  || startswith (section_name, ".fini"))
+  && !lookup_attribute ("used", *attributes))
+{
+  *attributes = tree_cons (get_identifier ("used"), NULL, *attributes);
+}
+
 #if defined WITH_AVRLIBC
   if (avropt_call_main == 0
   && TREE_CODE (node) == FUNCTION_DECL
   && MAIN_NAME_P (DECL_NAME (node)))
 {
-  const char *s_section_name = nullptr;
-
-  if (tree a_sec = lookup_attribute ("section", *attributes))
-	if (TREE_VALUE (a_sec))
-	  if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec)))
-	if (TREE_CODE (t_section_name) == STRING_CST)
-	  s_section_name = TREE_STRING_POINTER (t_section_name);
-
-  bool in_init9_p = s_section_name && !strcmp (s_section_name, ".init9");
+  bool in_init9_p = section_name && !strcmp (section_name, ".init9");
 
-  if (s_section_name && !in_init9_p)
+  if (section_name && !in_init9_p)
 	{
 	  warning (OPT_Wattributes, "% attribute on main"
-		   " function inhibits %<-mno-call-main%>", s_section_name);
+		   " function inhibits %<-mno-call-main%>", section_name);
 	}
   else
 	{


Re: [Fortran, Patch, PR119349, v1] Fix regression of polymorphic dummy sourced from array constructors.

2025-03-21 Thread Andre Vehreschild
Hi Paul,

thanks for the (additional) review. The patch has been merged already as
gcc-15-8481-g0f344846a62.

But I totally agree, that conv_procedure_call is calling (pun intended) for a
refactoring.

Thanks again,
Andre

On Fri, 21 Mar 2025 14:34:13 +
Paul Richard Thomas  wrote:

> Hi Andre,
>
> I am reasonably familiar with the mess that is gfc_conv_procedure_call :-)
> So in spite of you having a hard time explaining things today, I see your
> patch as verging on 'obvious' and is certainly the best that can be done
> without refactoring the whole thing.
>
> OK fo mainline.
>
> Thanks for the patch
>
> Paul
>
>
> On Thu, 20 Mar 2025 at 16:36, Andre Vehreschild  wrote:
>
> > Hi all,
> >
> > attached patch fixes a 15-regression where an element of an actual
> > temporary array, i.e., elemental([ e1, e2...]) passed to the formal
> > polymorphic
> > dummy leads to a double free of the derived types components. This patch
> > prevents this by preventing the deallocation of the array constructors
> > temporary, when the formal is polymorphic. ...
> >
> > Folks its so hard to explain this in prose. I rewrote above paragraph the
> > third
> > time now. And I still don't understand on re-reading. So here is some
> > pseudo
> > code:
> >
> > struct derived {
> >   char *c; // This is the component suffering from double-free
> > };
> >
> > derived[2] atmp = [ derived(""), derived("")]
> >
> > forall a in atmp
> >   derived t_a = a; // <- Copy of a, but no deep copy, i.e. t_a.c == a.c
> >   class_temp = class_derived(a); // set _vtype left out for brevity
> >   call elemental_function(class_temp);
> >   if (class_temp._data.c != NULL)
> > free(class_temp._data.c); // and set it to NULL
> >   if (t_a.c != NULL)
> > free(t_a.c); // BOOM, this is freeing the same c
> > end
> >
> > Generating the last if-block and the free is what this patch prevents for
> > polymorphic dummys that stem from an array construction. And only for
> > those.
> >
> > Sorry, I am having a hard time explaining things today. So I hope the code
> > above will do.
> >
> > Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
> >
> > Regards,
> > Andre
> > --
> > Andre Vehreschild * Email: vehre ad gmx dot de
> >


--
Andre Vehreschild * Email: vehre ad gmx dot de


[COMMITTED 145/146] gccrs: derive(Clone): Add lang item typepaths failure testcases to nr2 exclude

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

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Add failing lang item typepaths tests.
* rust/execute/torture/derive_macro4.rs: Mark Clone as lang item.
---
 gcc/testsuite/rust/compile/nr2/exclude  | 5 +
 gcc/testsuite/rust/execute/torture/derive_macro4.rs | 1 +
 2 files changed, 6 insertions(+)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 1a9c8e7113a..60322f3276a 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -146,4 +146,9 @@ cmp1.rs
 derive_clone_enum1.rs
 derive_clone_enum2.rs
 derive_clone_enum3.rs
+derive_macro4.rs
+derive_macro6.rs
+issue-2987.rs
+issue-3139-1.rs
+issue-3139-3.rs
 # please don't delete the trailing newline
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro4.rs 
b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
index c355ac7905f..38c4808574a 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro4.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
@@ -1,6 +1,7 @@
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
-- 
2.45.2



  1   2   >