[gcc r15-7983] tree.def: Improve RAW_DATA_CST documentation

2025-03-12 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:0787a65d953612a9812d69f23e3699b9e13c152d

commit r15-7983-g0787a65d953612a9812d69f23e3699b9e13c152d
Author: Jakub Jelinek 
Date:   Wed Mar 12 10:11:39 2025 +0100

tree.def: Improve RAW_DATA_CST documentation

In PR117262 David was asking for better documentation of RAW_DATA_CST
and in the review of the PR119076 patch Jason was asking for that as well.

Here is an attempt to do so.

2025-03-12  Jakub Jelinek  

* tree.def (RAW_DATA_CST): Document meaning of NULL RAW_DATA_OWNER.
(CONSTRUCTOR): Document meaning of RAW_DATA_CST used as element
value.

Diff:
---
 gcc/tree.def | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/tree.def b/gcc/tree.def
index 9d31fee84545..c4ad8d08f10c 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -313,7 +313,9 @@ DEFTREECODE (STRING_CST, "string_cst", tcc_constant, 0)
of the raw data, plus RAW_DATA_OWNER for owner of the
data.  That can be either a STRING_CST, used e.g. when writing
PCH header, or another RAW_DATA_CST representing data owned by
-   libcpp and representing the original range (if possible).
+   libcpp and representing the original range (if possible)
+   or NULL_TREE if it is the RAW_DATA_OWNER of other RAW_DATA_CST
+   nodes (and represents data owned by libcpp).
TREE_TYPE is the type of each of the RAW_DATA_LENGTH elements.  */
 DEFTREECODE (RAW_DATA_CST, "raw_data_cst", tcc_constant, 0)
 
@@ -505,6 +507,14 @@ DEFTREECODE (OBJ_TYPE_REF, "obj_type_ref", tcc_expression, 
3)
one for each index in the range.  (If the corresponding field VALUE
has side-effects, they are evaluated once for each element.  Wrap the
value in a SAVE_EXPR if you want to evaluate side effects only once.)
+   If the index is INTEGER_CST or NULL_TREE and value RAW_DATA_CST, it is
+   a short-hand for RAW_DATA_LENGTH consecutive nodes, first at the given
+   index or current location, each node being
+   build_int_cst (TREE_TYPE (value), TYPE_UNSIGNED (TREE_TYPE (value))
+ ? (HOST_WIDE_INT) RAW_DATA_UCHAR_ELT (value, n)
+ : (HOST_WIDE_INT) RAW_DATA_SCHAR_ELT (value, n)) at index
+   tree_to_uhwi (index) + n (or current location + n) for n from 0 to
+   RAW_DATA_LENGTH (value) - 1.
 
Components that aren't present are cleared as per the C semantics,
unless the CONSTRUCTOR_NO_CLEARING flag is set, in which case their


[gcc r15-7980] c++: Handle RAW_DATA_CST in modules.cc [PR119076]

2025-03-12 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:28b05e4317a6eade2ba46076ef17f9e138c57a34

commit r15-7980-g28b05e4317a6eade2ba46076ef17f9e138c57a34
Author: Jakub Jelinek 
Date:   Wed Mar 12 08:01:09 2025 +0100

c++: Handle RAW_DATA_CST in modules.cc [PR119076]

The following testcases (one with #embed, one with large initializer
turned into RAW_DATA_CST) show that I forgot to handle RAW_DATA_CST in
module streaming.

Similar to the PCH case we need to stream out RAW_DATA_CST with NULL
RAW_DATA_OWNER (i.e. a tree which has data owned by libcpp buffer) so
that it will be streamed back in as STRING_CST which owns the data,
but because the data can be really large (hopefully not so much for
header modules though), without actually trying to build a STRING_CST
on the module writing side because that would mean another large
allocation and copying of the large data.
RAW_DATA_CST with RAW_DATA_OWNER then needs to be streamed out and in
by streaming the owner and offset from owner's data and length.

2025-03-12  Jakub Jelinek  

PR c++/119076
* module.cc (trees_out::start): Handle RAW_DATA_CST.
(trees_in::start): Likewise.
(trees_out::core_vals): Likewise.
(trees_in::core_vals): Likewise.

* g++.dg/modules/pr119076-1_a.H: New test.
* g++.dg/modules/pr119076-1_b.C: New test.
* g++.dg/modules/pr119076-2_a.H: New test.
* g++.dg/modules/pr119076-2_b.C: New test.

Diff:
---
 gcc/cp/module.cc| 65 +
 gcc/testsuite/g++.dg/modules/pr119076-1_a.H | 41 ++
 gcc/testsuite/g++.dg/modules/pr119076-1_b.C | 12 ++
 gcc/testsuite/g++.dg/modules/pr119076-2_a.H | 65 +
 gcc/testsuite/g++.dg/modules/pr119076-2_b.C | 12 ++
 5 files changed, 195 insertions(+)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 97c3549093c9..9a1cd5244c2c 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5379,6 +5379,30 @@ trees_out::start (tree t, bool code_streamed)
   str (TREE_STRING_POINTER (t), TREE_STRING_LENGTH (t));
   break;
 
+case RAW_DATA_CST:
+  if (RAW_DATA_OWNER (t) == NULL_TREE)
+   {
+ /* Stream RAW_DATA_CST with no owner (i.e. data pointing
+into libcpp buffers) as something we can stream in as
+STRING_CST which owns the data.  */
+ u (0);
+ /* Can't use str (RAW_DATA_POINTER (t), RAW_DATA_LENGTH (t));
+here as there isn't a null termination after it.  */
+ z (RAW_DATA_LENGTH (t));
+ if (RAW_DATA_LENGTH (t))
+   if (void *ptr = buf (RAW_DATA_LENGTH (t) + 1))
+ {
+   memcpy (ptr, RAW_DATA_POINTER (t), RAW_DATA_LENGTH (t));
+   ((char *) ptr)[RAW_DATA_LENGTH (t)] = '\0';
+ }
+   }
+  else
+   {
+ gcc_assert (RAW_DATA_LENGTH (t));
+ u (RAW_DATA_LENGTH (t));
+   }
+  break;
+
 case VECTOR_CST:
   u (VECTOR_CST_LOG2_NPATTERNS (t));
   u (VECTOR_CST_NELTS_PER_PATTERN (t));
@@ -5472,6 +5496,24 @@ trees_in::start (unsigned code)
   }
   break;
 
+case RAW_DATA_CST:
+  {
+   size_t l = u ();
+   if (l == 0)
+ {
+   /* Stream in RAW_DATA_CST with no owner as STRING_CST
+  which owns the data.  */
+   const char *chars = str (&l);
+   t = build_string (l, chars);
+ }
+   else
+ {
+   t = make_node (RAW_DATA_CST);
+   RAW_DATA_LENGTH (t) = l;
+ }
+  }
+  break;
+
 case VECTOR_CST:
   {
unsigned log2_npats = u ();
@@ -6383,6 +6425,22 @@ trees_out::core_vals (tree t)
   /* Streamed during start.  */
   break;
 
+case RAW_DATA_CST:
+  if (RAW_DATA_OWNER (t) == NULL_TREE)
+   break; /* Streamed as STRING_CST during start.  */
+  WT (RAW_DATA_OWNER (t));
+  if (streaming_p ())
+   {
+ if (TREE_CODE (RAW_DATA_OWNER (t)) == RAW_DATA_CST)
+   z (RAW_DATA_POINTER (t) - RAW_DATA_POINTER (RAW_DATA_OWNER (t)));
+ else if (TREE_CODE (RAW_DATA_OWNER (t)) == STRING_CST)
+   z (RAW_DATA_POINTER (t)
+  - TREE_STRING_POINTER (RAW_DATA_OWNER (t)));
+ else
+   gcc_unreachable ();
+   }
+  break;
+
 case VECTOR_CST:
   for (unsigned ix = vector_cst_encoded_nelts (t); ix--;)
WT (VECTOR_CST_ENCODED_ELT (t, ix));
@@ -6917,6 +6975,13 @@ trees_in::core_vals (tree t)
   /* Streamed during start.  */
   break;
 
+case RAW_DATA_CST:
+  RT (RAW_DATA_OWNER (t));
+  gcc_assert (TREE_CODE (RAW_DATA_OWNER (t)) == STRING_CST
+ && TREE_STRING_LENGTH (RAW_DATA_OWNER (t)));
+  RAW_DATA_POINTER (t) = TREE_STRING_POINTER (RAW_DATA_OWNER (t)) + z ();
+  break;
+
 case VECTOR_CST:
   for (unsigned ix = vector_cst_encoded_nelt

[gcc r15-7985] vect: Fix ncopies when costing SLP reductions [PR116901]

2025-03-12 Thread Richard Sandiford via Gcc-cvs
https://gcc.gnu.org/g:855b61b61e63b17cc9770cbe1c5387e4f59c1ffe

commit r15-7985-g855b61b61e63b17cc9770cbe1c5387e4f59c1ffe
Author: Richard Sandiford 
Date:   Wed Mar 12 09:40:10 2025 +

vect: Fix ncopies when costing SLP reductions [PR116901]

pr110625_[24].c started failing after r15-1329-gd66b820f392aa9a7,
which switched to single def-use cycles for single-lane SLP.
The problem is that we only costed one vector accumulator
operation for an N-vector cycle.

The problem seems to have been latent, and meant that we also
only costed one FADDA for reduc_strict_4.c and reduc_strict_5.c,
even though they need 4 and 6 FADDAs respectively.

I'm not sure why:

   if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
   && ncopies > 1)

was previously only necessary for non-SLP, but the patch preserves
that for safety.

gcc/
PR tree-optimization/116901
* tree-vect-loop.cc (vectorizable_reduction): Set ncopies to
SLP_TREE_NUMBER_OF_VEC_STMTS for SLP.

gcc/testsuite/
PR tree-optimization/116901
* gcc.target/aarch64/sve/reduc_strict_4.c: Turn off costing.
* gcc.target/aarch64/sve/reduc_strict_5.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_4.c |  2 +-
 gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_5.c |  2 +-
 gcc/tree-vect-loop.cc | 14 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_4.c 
b/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_4.c
index 9a12edad42ec..8dad5ee60166 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_4.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model" } */
 
 double mat[100][8];
 
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_5.c 
b/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_5.c
index 7c3068fe87ad..9e117812d340 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/reduc_strict_5.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model" } */
 
 double mat[100][12];
 
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 52533623cab9..9413dcef7025 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -8180,7 +8180,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
 return false;
 
   if (slp_node)
-ncopies = 1;
+ncopies = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
   else
 ncopies = vect_get_num_copies (loop_vinfo, vectype_in);
 
@@ -8288,7 +8288,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
|| reduction_type == CONST_COND_REDUCTION
|| reduction_type == EXTRACT_LAST_REDUCTION)
   && slp_node
-  && SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) > 1)
+  && ncopies > 1)
 {
   if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -8297,6 +8297,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
 }
 
   if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
+  && !slp_node
   && ncopies > 1)
 {
   if (dump_enabled_p ())
@@ -8523,11 +8524,10 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
participating.  When unrolling we want each unrolled iteration to have its
own reduction accumulator since one of the main goals of unrolling a
reduction is to reduce the aggregate loop-carried latency.  */
-  if ((ncopies > 1
-   || (slp_node
-  && !REDUC_GROUP_FIRST_ELEMENT (stmt_info)
-  && SLP_TREE_LANES (slp_node) == 1
-  && vect_get_num_copies (loop_vinfo, vectype_in) > 1))
+  if (ncopies > 1
+  && (!slp_node
+ || (!REDUC_GROUP_FIRST_ELEMENT (stmt_info)
+ && SLP_TREE_LANES (slp_node) == 1))
   && (STMT_VINFO_RELEVANT (stmt_info) <= vect_used_only_live)
   && reduc_chain_length == 1
   && loop_vinfo->suggested_unroll_factor == 1)


[gcc r15-7984] aarch64: Tighten pr110625_1.c regexp

2025-03-12 Thread Richard Sandiford via Gcc-cvs
https://gcc.gnu.org/g:5cef719596400a712fc72dc54dd4ec8cdb694dd5

commit r15-7984-g5cef719596400a712fc72dc54dd4ec8cdb694dd5
Author: Richard Sandiford 
Date:   Wed Mar 12 09:40:10 2025 +

aarch64: Tighten pr110625_1.c regexp

Before r14-2877-gbf67bf4880ce5be0, the aarch64 code assumed that
every multi-vector reduction would use single def-use cycles.
The patch fixed it to test what the vectoriser actually planned
to do, using newly provided information.

At the time, we didn't try to use single def-use cycles for any costed
variant in the associated testcase (gcc.target/aarch64/pr110625_1.c),
so it was enough to check that the single-def-use latency was never
printed to the dump file.  However, we do now consider using single
def-use cycles for the single-lane SLP fallback.

This patch therefore switches to a positive test of the
non-single-def-use latency.  I checked that the test still failed
in this form before r14-2877-gbf67bf4880ce5be0.

gcc/testsuite/
* gcc.target/aarch64/pr110625_1.c: Turn into a positive test for
a vector latency of 2, rather than a negative test for a vector
latency of 8.

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

diff --git a/gcc/testsuite/gcc.target/aarch64/pr110625_1.c 
b/gcc/testsuite/gcc.target/aarch64/pr110625_1.c
index 0965cac33a00..1d0033c98333 100644
--- a/gcc/testsuite/gcc.target/aarch64/pr110625_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/pr110625_1.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-Ofast -mcpu=neoverse-n2 -fdump-tree-vect-details 
-fno-tree-slp-vectorize" } */
-/* { dg-final { scan-tree-dump-not "reduction latency = 8" "vect" } } */
+/* { dg-final { scan-tree-dump {Vector issue estimate:(?:(?!Cost 
model).)*reduction latency = 2\n} "vect" } } */
 
 /* Do not increase the vector body cost due to the incorrect reduction latency
 Original vector body cost = 51


[gcc r15-7992] libstdc++: Add lambda example to case transformation docs

2025-03-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:597ca24445462f11aaa3f7164a81f2f4f74bb80a

commit r15-7992-g597ca24445462f11aaa3f7164a81f2f4f74bb80a
Author: Jonathan Wakely 
Date:   Wed Mar 12 11:30:04 2025 +

libstdc++: Add lambda example to case transformation docs

libstdc++-v3/ChangeLog:

* doc/xml/manual/strings.xml: Tweak formatting. Add example
using lambda.
* doc/html/manual/strings.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/strings.html | 19 ++-
 libstdc++-v3/doc/xml/manual/strings.xml   | 19 +++
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/strings.html 
b/libstdc++-v3/doc/html/manual/strings.html
index 34a34dfa980c..5344d0e89238 100644
--- a/libstdc++-v3/doc/html/manual/strings.html
+++ b/libstdc++-v3/doc/html/manual/strings.html
@@ -50,10 +50,12 @@

  Note that these calls all
   involve the global C locale through the use of the C functions
-  toupper/tolower.  This is absolutely 
guaranteed to work --
-  but only if the string contains 
only characters
-  from the basic source character set, and there are only
-  96 of those.  Which means that not even all English text can be
+  toupper/tolower.
+  This is absolutely guaranteed to work
+  -- but only if the string contains
+  only characters from the basic 
source character set,
+  and there are only 96 of those.
+  Which means that not even all English text can be
   represented (certain British spellings, proper names, and so forth).
   So, if all your input forevermore consists of only those 96
   characters (hahahahahaha), then you're done.
@@ -73,7 +75,14 @@
   // std::tolower(c) is undefined if c < 0 so cast to unsigned char.
   return std::tolower((unsigned char)c);
} (Thanks to James Kanze for assistance and suggestions on all of 
this.)
-   Another common operation is trimming off excess whitespace.  Much
+   
+ Since C++11 the wrapper can be replaced with a lambda expression,
+ which can perform the conversion to unsigned 
char and
+ also ensure the single-argument form of std::lower is used:
+   
+ std::transform (s.begin(), s.end(), capital_s.begin(),
+ [](unsigned char c) { return std::tolower(c); });
+   Another common operation is trimming off excess whitespace.  Much
   like transformations, this task is trivial with the use of string's
   find family.  These examples are broken into 
multiple
   statements for readability:
diff --git a/libstdc++-v3/doc/xml/manual/strings.xml 
b/libstdc++-v3/doc/xml/manual/strings.xml
index 4a63dd964771..58a78d01d239 100644
--- a/libstdc++-v3/doc/xml/manual/strings.xml
+++ b/libstdc++-v3/doc/xml/manual/strings.xml
@@ -66,10 +66,12 @@

  Note that these calls all
   involve the global C locale through the use of the C functions
-  toupper/tolower.  This is absolutely guaranteed to work --
-  but only if the string contains 
only characters
-  from the basic source character set, and there are 
only
-  96 of those.  Which means that not even all English text can be
+  toupper/tolower.
+  This is absolutely guaranteed to work
+  -- but only if the string contains
+  only characters from the basic source character set,
+  and there are only 96 of those.
+  Which means that not even all English text can be
   represented (certain British spellings, proper names, and so forth).
   So, if all your input forevermore consists of only those 96
   characters (hahahahahaha), then you're done.
@@ -93,6 +95,15 @@
} 
(Thanks to James Kanze for assistance and suggestions on all of this.)

+   
+ Since C++11 the wrapper can be replaced with a lambda expression,
+ which can perform the conversion to unsigned char and
+ also ensure the single-argument form of std::lower is used:
+   
+   
+ std::transform (s.begin(), s.end(), capital_s.begin(),
+ [](unsigned char c) { return std::tolower(c); });
+   
Another common operation is trimming off excess whitespace.  Much
   like transformations, this task is trivial with the use of string's
   find family.  These examples are broken into multiple


[gcc r15-7993] Regenerate cobol/lang.opt.urls

2025-03-12 Thread Mark Wielaard via Gcc-cvs
https://gcc.gnu.org/g:74be867452d62f2199e317de92e2e34d217cc47f

commit r15-7993-g74be867452d62f2199e317de92e2e34d217cc47f
Author: Mark Wielaard 
Date:   Wed Mar 12 12:29:24 2025 +0100

Regenerate cobol/lang.opt.urls

With the COBOL: Frontend (commit 3c5ed996a) came a lang.opt.urls,
which is different from what regenerate-opt-urls.py generates. Make
the CI bot happy by regenerating it.

Longer term, the COBOL docs need to be sorted out (see e.g. PR119227)
and then perhaps regenerate-opt-urls.py adjusted so that it can deal
with the COBOL docs.

gcc/cobol/ChangeLog:

* lang.opt.urls: Regenerated.

Diff:
---
 gcc/cobol/lang.opt.urls | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/gcc/cobol/lang.opt.urls b/gcc/cobol/lang.opt.urls
index a0e1f1944fe3..6a5dc1c0f580 100644
--- a/gcc/cobol/lang.opt.urls
+++ b/gcc/cobol/lang.opt.urls
@@ -10,20 +10,27 @@ UrlSuffix(gcc/Preprocessor-Options.html#index-D-1)
 I
 UrlSuffix(gcc/Directory-Options.html#index-I) 
LangUrlSuffix_D(gdc/Directory-Options.html#index-I)
 
+ffixed-form
+LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-ffixed-form)
+
 fsyntax-only
-UrlSuffix(gcc/Warning-Options.html#index-fsyntax-only) 
LangUrlSuffix_D(gdc/Warnings.html#index-fno-syntax-only)
+UrlSuffix(gcc/Warning-Options.html#index-fsyntax-only) 
LangUrlSuffix_D(gdc/Warnings.html#index-fno-syntax-only) 
LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-fsyntax-only)
+
+ffree-form
+LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-ffree-form)
 
 fmax-errors
 UrlSuffix(gcc/Warning-Options.html#index-fmax-errors) 
LangUrlSuffix_D(gdc/Warnings.html#index-fmax-errors)
 
 iprefix
-UrlSuffix(gcc/Directory-Options.html#index-iprefix) 
LangUrlSuffix_D(gdc/Directory-Options.html#index-iprefix)
+UrlSuffix(gcc/Directory-Options.html#index-iprefix) 
LangUrlSuffix_D(gdc/Directory-Options.html#index-iprefix) 
LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-iprefix)
 
 include
 UrlSuffix(gcc/Preprocessor-Options.html#index-include)
 
 isysroot
-UrlSuffix(gcc/Directory-Options.html#index-isysroot)
+UrlSuffix(gcc/Directory-Options.html#index-isysroot) 
LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-isysroot)
 
 isystem
-UrlSuffix(gcc/Directory-Options.html#index-isystem)
+UrlSuffix(gcc/Directory-Options.html#index-isystem) 
LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-isystem)
+


[gcc r15-7989] libstdc++: Make range adaptor __has_arrow helper use a const type

2025-03-12 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:04815ae0a2b27895411506813db3a8b460be1d6d

commit r15-7989-g04815ae0a2b27895411506813db3a8b460be1d6d
Author: Jonathan Wakely 
Date:   Tue Mar 11 15:47:21 2025 +

libstdc++: Make range adaptor __has_arrow helper use a const type

LWG 4112 (approved in Wrocław, November 2024) changes the has-arrow
helper to require operator-> to be valid on a const-qualified lvalue.
This affects the constraints for filter_view::_Iterator::operator-> and
join_view::_Iterator::operator-> so that they can only be used if the
underlying iterator supports operator-> on const.

The change also adds semantic (i.e. not checkable and not enforced)
requirements that operator-> must have the same semantics whether called
on a const or non-const value, and on an lvalue or rvalue (due to the
implicit expression variation rules in [concepts.equality]).

libstdc++-v3/ChangeLog:

* include/bits/ranges_util.h (ranges::_detail::__has_arrow):
Require operator->() to be valid on const-qualified type, as per
LWG 4112.
* testsuite/std/ranges/adaptors/lwg4112.cc: New test.

Reviewed-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/bits/ranges_util.h|  5 ++-
 .../testsuite/std/ranges/adaptors/lwg4112.cc   | 41 ++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/ranges_util.h 
b/libstdc++-v3/include/bits/ranges_util.h
index 54e4f6261b05..53b7f5c17f1c 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -54,9 +54,12 @@ namespace ranges
&& same_as, iterator_t>
&& same_as, sentinel_t>;
 
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 4112. has-arrow should required operator->() to be const-qualified
 template
   concept __has_arrow = input_iterator<_It>
-   && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
+   && (is_pointer_v<_It>
+ || requires(const _It __it) { __it.operator->(); });
 
 using std::__detail::__different_from;
   } // namespace __detail
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/lwg4112.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/lwg4112.cc
new file mode 100644
index ..a283504b636d
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/lwg4112.cc
@@ -0,0 +1,41 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 4112. has-arrow should required operator->() to be const-qualified
+
+// The issue resolution means that range adaptors which use has-arrow to
+// constrain their iterator's operator-> should require a const-qualified
+// operator-> on the underlying view's iterator.
+
+#include 
+
+struct Int { int i = 0; };
+
+struct Iter
+{
+  using value_type = Int;
+  using difference_type = int;
+
+  mutable Int val;
+
+  Int& operator*() const { return val; }
+  Int* operator->() /* non-const */ { return &val; }
+  Iter& operator++() { ++val.i; return *this; }
+  void operator++(int) { ++val.i; }
+  bool operator==(const Iter& j) const { return val.i == j.val.i; }
+};
+
+template
+concept has_op_arrow = requires (T t) { t.operator->(); };
+
+static_assert( has_op_arrow );
+static_assert( ! has_op_arrow );
+
+using Range = std::ranges::subrange;
+using Pred = bool(*)(Int);
+using FilterView = std::ranges::filter_view;
+using FilterIterator = std::ranges::iterator_t;
+
+static_assert( ! has_op_arrow );
+static_assert( ! has_op_arrow );
+static_assert( ! has_op_arrow );
+static_assert( ! has_op_arrow );


[gcc r15-7988] libstdc++: Reject basic_format_parse_context::check_dynamic_spec<>(n)

2025-03-12 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:a21847acb8bb1101c15deef1b55d929e65c9ada4

commit r15-7988-ga21847acb8bb1101c15deef1b55d929e65c9ada4
Author: Jonathan Wakely 
Date:   Sat Mar 8 11:58:49 2025 +

libstdc++: Reject basic_format_parse_context::check_dynamic_spec<>(n)

LWG 4142 (approved in Wrocław, November 2024) made it ill-formed to call
basic_format_parse_context::check_dynamic_spec with an empty template
argument list.

This adds a static_assert to enforce that, and adjusts the tests.

libstdc++-v3/ChangeLog:

* include/std/format
(basic_format_parse_context::check_dynamic_spec): Require a
non-empty parameter pack, as per LWG 4142.
* testsuite/std/format/parse_ctx.cc: Remove call of
check_dynamic_spec with empty template argument list.
* testsuite/std/format/parse_ctx_neg.cc: Add dg-error to call of
check_dynamic_spec with empty template argument list.

Reviewed-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/std/format| 3 +++
 libstdc++-v3/testsuite/std/format/parse_ctx.cc | 1 -
 libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc | 8 ++--
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index e7e0d2d142bb..0d6cc7f6bef4 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -4338,6 +4338,9 @@ namespace __format
 constexpr void
 basic_format_parse_context<_CharT>::check_dynamic_spec(size_t __id) 
noexcept
 {
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 4142. check_dynamic_spec should require at least one type
+  static_assert(sizeof...(_Ts) >= 1);
   // This call enforces the Mandates: condition that _Ts contains valid
   // types and each type appears at most once. It could be a static_assert
   // but this way failures give better diagnostics, due to calling the
diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc 
b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
index 88ffd77debe0..b5dd7cdba782 100644
--- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc
+++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc
@@ -491,7 +491,6 @@ test_dynamic_type_check()
   std::format_parse_context pc("{1}.{2}");
 
   // None of these calls should do anything at runtime, only during consteval:
-  pc.check_dynamic_spec<>(0);
   pc.check_dynamic_spec(0);
   pc.check_dynamic_spec_integral(0);
   pc.check_dynamic_spec_string(0);
diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc 
b/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
index f19107c886fc..d83fd8c7a7b0 100644
--- a/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
+++ b/libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc
@@ -12,8 +12,9 @@ test_invalid()
   pc.check_dynamic_spec(0);
-  // For some reason, an empty pack of types is valid:
-  pc.check_dynamic_spec<>(0);
+
+  // LWG 4142. check_dynamic_spec should require at least one type
+  pc.check_dynamic_spec<>(0); // { dg-error "here" }
 
   pc.check_dynamic_spec(0); // { dg-error "here" }
   // const void* is allowed, but void* is not
@@ -25,6 +26,7 @@ test_invalid()
   pc.check_dynamic_spec(0); // { dg-error "here" }
   // std::string_view is allowed, but std::string is not
   pc.check_dynamic_spec(0); // { dg-error "here" }
+  // The types in the pack must be unique.
   pc.check_dynamic_spec(0); // { dg-error "here" }
 
   std::wformat_parse_context wpc(L"");
@@ -38,3 +40,5 @@ test_invalid()
 
 // Each failure above will point to a call to this non-constexpr function:
 // { dg-error "__invalid_dynamic_spec" "" { target *-*-* } 0 }
+// Except the check_dynamic_spec<>(0) one for LWG 4142 which matches this:
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }


[gcc r15-7991] cobol: Remove unnecesssary CPPFLAGS update and restore MacOS build

2025-03-12 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:503f10e34dcdeb8bd1cf78c2f14c7ac41cae31a5

commit r15-7991-g503f10e34dcdeb8bd1cf78c2f14c7ac41cae31a5
Author: Simon Martin 
Date:   Wed Mar 12 09:09:35 2025 +0100

cobol: Remove unnecesssary CPPFLAGS update and restore MacOS build

The build currently fails on MacOS even when the Cobol front-end and
libgcobol builds are disabled.

The problem is that gcc/cobol/Make-lang.in adds -Iinclude to CPPFLAGS,
which somehow makes clang unhappy about the include order:
  error:  tried including  but didn't find libc++'s
   header. This usually means that your header search paths
  are not configured properly.

It turns out that this addition is unnecessary: simply removing it fixes
the build on MacOS, without impacting the build x86_64-pc-linux-gnu when
configured with --enable-languages=default,cobol.

It feels like there might be more cleanup opportunities there, but they
can be taken care of later.

gcc/cobol/ChangeLog:

* Make-lang.in: Remove unnecessary CPPFLAGS update.

Diff:
---
 gcc/cobol/Make-lang.in | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index cbb31d63c303..9fa3b1cdfdb3 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -56,7 +56,6 @@ LIB_SOURCE ?= $(srcdir)/../libgcobol
 #
 CPPFLAGS = \
  -std=c++14\
- -Iinclude \
  -I$(BINCLUDE) \
  -I$(LIB_INCLUDE)  \
  -DEXEC_LIB=\"$(prefix)/lib64\"\


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction PR100020.f90

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:14eacab78b9f91851eca51679ffe34e0c44c2554

commit 14eacab78b9f91851eca51679ffe34e0c44c2554
Author: Mikael Morin 
Date:   Wed Mar 12 15:57:05 2025 +0100

Correction PR100020.f90

Diff:
---
 gcc/fortran/trans-types.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 53216a25847e..7c481490eb1c 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2852,7 +2852,10 @@ get_class_canonical_type (gfc_symbol *derived, int rank, 
int corank)
   if (rank != 0 || corank != 0)
 {
   as = gfc_get_array_spec ();
-  as->type = AS_DEFERRED;
+  if (rank == -1)
+   as->type = AS_ASSUMED_RANK;
+  else
+   as->type = AS_DEFERRED;
   as->rank = rank;
   as->corank = corank;
 }


[gcc] Created branch 'rdubner/heads/bobdev' in namespace 'refs/users'

2025-03-12 Thread Robert Dubner via Gcc-cvs
The branch 'rdubner/heads/bobdev' was created in namespace 'refs/users' 
pointing to:

 52e297a3aa91... MAINTAINERS: Remove extraneous "Robert Dubner" entries


[gcc r15-8000] df: Treat partial defs as uses in df_simulate_defs [PR116564]

2025-03-12 Thread Alex Coplan via Gcc-cvs
https://gcc.gnu.org/g:758e617bcf224dc9d4a7e26dd858d43c1e63b916

commit r15-8000-g758e617bcf224dc9d4a7e26dd858d43c1e63b916
Author: Alex Coplan 
Date:   Mon Mar 10 16:44:15 2025 +

df: Treat partial defs as uses in df_simulate_defs [PR116564]

The PR shows us spinning in dce.cc:fast_dce at the start of combine.
This spinning appears to be because of a disagreement between the fast_dce 
code
and the code in df-problems.cc:df_lr_bb_local_compute.  Specifically, they
disagree on the treatment of partial defs.  For the testcase in the PR, we 
have
the following insn in bb 3:

(insn 10 8 13 3 (clobber (subreg:V1DF (reg/v:V2x1DF 104 [ __val ]) 8)) -1
 (nil))

which gives rise to a DF def with DF_REF_FLAGS = 0x8b0, i.e.
DF_REF_PARTIAL | DF_REF_READ_WRITE | DF_REF_MUST_CLOBBER | DF_REF_SUBREG.

Eliding the large block comment for readability, the code in
df_lr_bb_local_compute does the following (for each insn):

  FOR_EACH_INSN_INFO_DEF (def, insn_info)
{
  unsigned int dregno = DF_REF_REGNO (def);
  bitmap_set_bit (&bb_info->def, dregno);
  if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))
bitmap_set_bit (&bb_info->use, dregno);
  else
bitmap_clear_bit (&bb_info->use, dregno);
}

i.e. it models partial defs as a RMW operation; thus for the def arising
from i10 above, it records a use of r104; hence it ends up in the
live-in set for bb 3.

However, as it stands, the code in dce.cc:fast_dce (and its callee
dce_process_block) has no such provision for DF_REF_PARTIAL defs.  It
does not treat these as a RMW and does not compute r104 above as being
live-in to bb 3.  At the end of dce_process_block we compute the
following "did something happen" condition used to decide termination of
the analysis:

  block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));
  if (block_changed)
bitmap_copy (DF_LR_IN (bb), local_live);

  BITMAP_FREE (local_live);
  return block_changed;

because of the disagreement between df_lr_local_compute and the local
analysis done by fast_dce, we invariably have r104 in DF_LR_IN, but not
in local_live.  Hence we always return true here, call
df_analyze_problem (which re-computes DF_LR_IN according to
df_lr_bb_local_compute, re-adding r104), and so the analysis never
terminates.

This patch therefore adjusts df_simulate_defs (called from
dce_process_block) to match the behaviour of df_lr_bb_local_compute in
this respect, namely we make it model partial defs as RMW operations by
setting the relevant register live.  This fixes the spinning in fast_dce
for this testcase.

gcc/ChangeLog:

PR rtl-optimization/116564
* df-problems.cc (df_simulate_defs): For partial defs, mark the
register live (treat it as a RMW operation).

gcc/testsuite/ChangeLog:

PR rtl-optimization/116564
* gcc.target/aarch64/torture/pr116564.c: New test.

Diff:
---
 gcc/df-problems.cc  |  8 +---
 gcc/testsuite/gcc.target/aarch64/torture/pr116564.c | 11 +++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/gcc/df-problems.cc b/gcc/df-problems.cc
index f32185b3eac3..907537930982 100644
--- a/gcc/df-problems.cc
+++ b/gcc/df-problems.cc
@@ -3893,9 +3893,11 @@ df_simulate_defs (rtx_insn *insn, bitmap live)
 {
   unsigned int dregno = DF_REF_REGNO (def);
 
-  /* If the def is to only part of the reg, it does
-not kill the other defs that reach here.  */
-  if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+  /* If the def is to only part of the reg, model it as a RMW operation
+by marking it live.  It only kills the reg if it is a complete def.  */
+  if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))
+   bitmap_set_bit (live, dregno);
+  else
bitmap_clear_bit (live, dregno);
 }
 }
diff --git a/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c 
b/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c
new file mode 100644
index ..d471e097294c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+#include 
+void test()
+{
+  for (int L = 0; L < 4; ++L) {
+float64_t ResData[1 * 2];
+float64x1x2_t Src1;
+vst2_f64(ResData, Src1);
+  }
+}


[gcc r15-7998] arm: allow type-punning subregs in vpr_register_operand [PR115439]

2025-03-12 Thread Richard Earnshaw via Gcc-cvs
https://gcc.gnu.org/g:6e4045513d789587b2c7750e9016c7035b461299

commit r15-7998-g6e4045513d789587b2c7750e9016c7035b461299
Author: Richard Earnshaw 
Date:   Mon Mar 10 14:12:38 2025 +

arm: allow type-punning subregs in vpr_register_operand [PR115439]

Subregs that only change the mode of an operand (ie don't change the
size) should be safe for the VPR register.  If we don't permit them
we may end up with some redundant copy instructions.

gcc:
PR target/115439
* config/arm/predicates.md (vpr_register_operand): Allow 
type-punning
subregs.

Diff:
---
 gcc/config/arm/predicates.md | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 5c78421ff697..75c06d9be255 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -99,11 +99,21 @@
 })
 
 (define_predicate "vpr_register_operand"
-  (match_code "reg")
+  (match_code "reg,subreg")
 {
-  return REG_P (op)
+  if (SUBREG_P (op))
+{
+  /* Only allow subregs if they are strictly type punning. */
+  if ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))
+  != GET_MODE_SIZE (GET_MODE (op)))
+ || SUBREG_BYTE (op) != 0)
+   return false;
+  op = SUBREG_REG (op);
+}
+
+  return (REG_P (op)
  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
- || IS_VPR_REGNUM (REGNO (op)));
+ || IS_VPR_REGNUM (REGNO (op;
 })
 
 (define_predicate "imm_for_neon_inv_logic_operand"


[gcc r15-7999] libphobos: Merge upstream phobos 0faae92d6

2025-03-12 Thread Iain Buclaw via Gcc-cvs
https://gcc.gnu.org/g:d63b52e059a7d77b98a2ef005920a85feb1e2446

commit r15-7999-gd63b52e059a7d77b98a2ef005920a85feb1e2446
Author: Iain Buclaw 
Date:   Wed Mar 12 12:04:59 2025 +0100

libphobos: Merge upstream phobos 0faae92d6

Phobos changes:

- Import phobos v2.111.0-beta.1.
- Added `bitCast' function to `std.conv'.
- Added `readfln' and `File.readfln' functions to `std.stdio'.
- New procedural API for `std.sumtype'.

libphobos/ChangeLog:

* src/MERGE: Merge upstream phobos 0faae92d6.
* testsuite/libphobos.phobos/std_array.d: Regenerate.
* testsuite/libphobos.phobos/std_conv.d: Regenerate.
* testsuite/libphobos.phobos/std_functional.d: Regenerate.
* testsuite/libphobos.phobos/std_sumtype.d: Regenerate.

Diff:
---
 libphobos/src/MERGE|   2 +-
 libphobos/src/std/algorithm/iteration.d|  34 +-
 libphobos/src/std/array.d  | 387 ++
 libphobos/src/std/bigint.d |  26 +-
 libphobos/src/std/checkedint.d |   2 +-
 libphobos/src/std/container/dlist.d|   2 +-
 libphobos/src/std/conv.d   |  36 ++
 libphobos/src/std/datetime/stopwatch.d |   1 -
 libphobos/src/std/format/internal/floats.d | 193 +++
 libphobos/src/std/format/internal/read.d   |   5 +-
 libphobos/src/std/format/internal/write.d  |  13 +-
 libphobos/src/std/format/read.d|  10 +
 libphobos/src/std/functional.d |  72 ++-
 libphobos/src/std/getopt.d | 111 +++-
 libphobos/src/std/math/operations.d|  95 ++--
 libphobos/src/std/process.d|  60 +--
 libphobos/src/std/random.d | 127 -
 libphobos/src/std/range/interfaces.d   |   2 +-
 libphobos/src/std/range/package.d  |  21 +-
 libphobos/src/std/stdio.d  | 144 ++
 libphobos/src/std/sumtype.d| 560 ++---
 libphobos/src/std/typecons.d   | 109 ++--
 libphobos/testsuite/libphobos.phobos/std_array.d   |  17 +
 libphobos/testsuite/libphobos.phobos/std_conv.d|  12 +
 .../testsuite/libphobos.phobos/std_functional.d|  33 ++
 libphobos/testsuite/libphobos.phobos/std_sumtype.d | 153 ++
 26 files changed, 1787 insertions(+), 440 deletions(-)

diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 9603e65aa423..a5a685de2362 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-1b242048c9db88c52cb0df6cd50c2b7455bedc01
+0faae92d62bdc1cc1982f0e9c65830ece1677289
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/phobos repository.
diff --git a/libphobos/src/std/algorithm/iteration.d 
b/libphobos/src/std/algorithm/iteration.d
index 8a3add3b7333..f8e1c05b658a 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -446,35 +446,21 @@ if (fun.length >= 1)
 auto map(Range)(Range r)
 if (isInputRange!(Unqual!Range))
 {
-import std.meta : AliasSeq, staticMap;
+import std.meta : staticMap;
+import std.functional : adjoin;
 
 alias RE = ElementType!(Range);
-static if (fun.length > 1)
-{
-import std.functional : adjoin;
-import std.meta : staticIndexOf;
 
-alias _funs = staticMap!(unaryFun, fun);
-alias _fun = adjoin!_funs;
+alias _funs = staticMap!(unaryFun, fun);
+alias _fun = adjoin!_funs;
 
-// Once https://issues.dlang.org/show_bug.cgi?id=5710 is fixed
-// accross all compilers (as of 2020-04, it wasn't fixed in LDC 
and GDC),
-// this validation loop can be moved into a template.
-foreach (f; _funs)
-{
-static assert(!is(typeof(f(RE.init)) == void),
-"Mapping function(s) must not return void: " ~ 
_funs.stringof);
-}
-}
-else
+// Once https://issues.dlang.org/show_bug.cgi?id=5710 is fixed
+// accross all compilers (as of 2020-04, it wasn't fixed in LDC and 
GDC),
+// this validation loop can be moved into a template.
+foreach (f; _funs)
 {
-alias _fun = unaryFun!fun;
-alias _funs = AliasSeq!(_fun);
-
-// Do the validation separately for single parameters due to
-// https://issues.dlang.org/show_bug.cgi?id=15777.
-static assert(!is(typeof(_fun(RE.init)) == void),
-"Mapping function(s) must not return void: " ~ _funs.stringof);
+static assert(!is(typeof(f(RE.init)) == void),
+"Mapping function(s) must not return void: " ~ 
_funs.stringof);
 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Renseignement type canonique pour descripteurs de classe.

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:dcbfcf816af8c00e233e9a5c679a149381ff27e2

commit dcbfcf816af8c00e233e9a5c679a149381ff27e2
Author: Mikael Morin 
Date:   Mon Mar 10 10:08:37 2025 +0100

Renseignement type canonique pour descripteurs de classe.

Diff:
---
 gcc/fortran/class.cc   | 75 ++
 gcc/fortran/gfortran.h |  2 ++
 gcc/fortran/trans-types.cc | 60 +
 3 files changed, 112 insertions(+), 25 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index df18601e45bd..41be63bf768f 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -632,6 +632,51 @@ gfc_get_len_component (gfc_expr *e, int k)
 }
 
 
+gfc_namespace *
+gfc_class_namespace (gfc_symbol * derived)
+{
+  if (derived->attr.unlimited_polymorphic)
+{
+  /* Find the top-level namespace.  */
+  for (gfc_namespace * ns = gfc_current_ns; ns; ns = ns->parent)
+   if (!ns->parent)
+ return ns;
+
+  gcc_unreachable ();
+}
+  else
+return derived->ns;
+}
+
+
+char *
+gfc_class_name (gfc_symbol *derived, int rank, int corank,
+   bool allocatable, bool pointer)
+{
+  char tname[GFC_MAX_SYMBOL_LEN+1];
+  char * name;
+
+  get_unique_hashed_string (tname, derived);
+  if (rank == -1)
+rank = GFC_MAX_DIMENSIONS;
+  bool array = rank != 0 || corank != 0;
+  if (array && allocatable)
+name = xasprintf ("__class_%s_%d_%da", tname, rank, corank);
+  else if (array && pointer)
+name = xasprintf ("__class_%s_%d_%dp", tname, rank, corank);
+  else if (array)
+name = xasprintf ("__class_%s_%d_%dt", tname, rank, corank);
+  else if (pointer)
+name = xasprintf ("__class_%s_p", tname);
+  else if (allocatable)
+name = xasprintf ("__class_%s_a", tname);
+  else
+name = xasprintf ("__class_%s_t", tname);
+
+  return name;
+}
+
+
 /* Build a polymorphic CLASS entity, using the symbol that comes from
build_sym. A CLASS entity is represented by an encapsulating type,
which contains the declared type as '_data' component, plus a pointer
@@ -644,7 +689,6 @@ bool
 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
gfc_array_spec **as)
 {
-  char tname[GFC_MAX_SYMBOL_LEN+1];
   char *name;
   gfc_typespec *orig_ts = ts;
   gfc_symbol *fclass;
@@ -683,34 +727,15 @@ gfc_build_class_symbol (gfc_typespec *ts, 
symbol_attribute *attr,
 return true;
 
   /* Determine the name of the encapsulating type.  */
-  rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
+  rank = !(*as) ? 0 : (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
 
   if (!ts->u.derived)
 return false;
 
-  get_unique_hashed_string (tname, ts->u.derived);
-  if ((*as) && attr->allocatable)
-name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
-  else if ((*as) && attr->pointer)
-name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
-  else if ((*as))
-name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
-  else if (attr->pointer)
-name = xasprintf ("__class_%s_p", tname);
-  else if (attr->allocatable)
-name = xasprintf ("__class_%s_a", tname);
-  else
-name = xasprintf ("__class_%s_t", tname);
-
-  if (ts->u.derived->attr.unlimited_polymorphic)
-{
-  /* Find the top-level namespace.  */
-  for (ns = gfc_current_ns; ns; ns = ns->parent)
-   if (!ns->parent)
- break;
-}
-  else
-ns = ts->u.derived->ns;
+  int corank = (*as) == nullptr ? 0 : (*as)->corank;
+  name = gfc_class_name (ts->u.derived, rank,  corank,
+attr->allocatable, attr->pointer);
+  ns = gfc_class_namespace (ts->u.derived);
 
   /* Although this might seem to be counterintuitive, we can build separate
  class types with different array specs because the TKR interface checks
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index e60c150dad2b..052f884f3ea4 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -4138,6 +4138,8 @@ bool gfc_is_class_container_ref (gfc_expr *e);
 gfc_expr *gfc_class_initializer (gfc_typespec *, gfc_expr *);
 unsigned int gfc_hash_value (gfc_symbol *);
 gfc_expr *gfc_get_len_component (gfc_expr *e, int);
+char * gfc_class_name (gfc_symbol *, int, int, bool, bool);
+gfc_namespace *gfc_class_namespace (gfc_symbol *derived);
 bool gfc_build_class_symbol (gfc_typespec *, symbol_attribute *,
 gfc_array_spec **);
 void gfc_change_class (gfc_typespec *, symbol_attribute *,
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 49ec5a6a8a49..83c004b0455d 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2823,6 +2823,60 @@ cobounds_match_decl (const gfc_symbol *derived)
   return true;
 }
 
+
+gfc_symbol *
+get_class_canonical_type (gfc_symbol *cls)
+{
+  gcc_assert (cls->attr.is_class);
+
+  gfc_component * data_comp = cls->components;
+
+  gfc_symbol *deriv

[gcc r15-8001] contrib: relpath.sh /lib /include [PR119081]

2025-03-12 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:90f5dabddbdc47bfbabaabb5b560d3d5cc2acf9c

commit r15-8001-g90f5dabddbdc47bfbabaabb5b560d3d5cc2acf9c
Author: Jason Merrill 
Date:   Tue Mar 11 17:43:35 2025 -0400

contrib: relpath.sh /lib /include [PR119081]

Previously, if the common ancestor of the two paths is / we would print the
absolute second argument, but this PR asks for a relative path in that case
as well, which makes sense for the libstdc++.modules.json use case.

PR libstdc++/119081

contrib/ChangeLog:

* relpath.sh: Give relative path even at /.

Diff:
---
 contrib/relpath.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/relpath.sh b/contrib/relpath.sh
index ac6b769ef81a..1b329fc04a78 100755
--- a/contrib/relpath.sh
+++ b/contrib/relpath.sh
@@ -59,9 +59,9 @@ while [ "${to#$from}" = "$to" ]; do
 from=$(dirname $from);
 back=../$back
 
-if [ "$from" = "/" ]; then
-   echo $to
-   exit 0
+if [ "$from" = / ] && [ "${to#/}" = "$to" ]; then
+   echo no common ancestor between $1 and $2 >&2
+   exit 1
 elif [ "$from" = . ]; then
echo no common ancestor between $1 and $2 >&2
exit 1


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction dynamic_dispatch_4.f03.

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ff6f2cd7e8ed66a7d49b57b32ee98445307d36b2

commit ff6f2cd7e8ed66a7d49b57b32ee98445307d36b2
Author: Mikael Morin 
Date:   Tue Mar 11 21:43:38 2025 +0100

Correction dynamic_dispatch_4.f03.

Diff:
---
 gcc/fortran/f95-lang.cc | 46 +-
 1 file changed, 41 insertions(+), 5 deletions(-)

diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc
index c5098a24102a..dec2485168b3 100644
--- a/gcc/fortran/f95-lang.cc
+++ b/gcc/fortran/f95-lang.cc
@@ -309,24 +309,60 @@ gfc_finish (void)
 }
 
 
+static bool
+is_non_root_class_wrapper_type (tree t)
+{
+  if (!TYPE_P (t))
+return false;
+
+  if (!GFC_CLASS_TYPE_P (t))
+return false;
+
+  if (!(TYPE_LANG_SPECIFIC (t) && GFC_TYPE_PARENT_CLASS_TYPE (t)))
+return false;
+
+  return true;
+}
+
+
 static alias_set_type
 gfc_get_alias_set (tree t)
 {
   if (!TYPE_P (t))
 return -1;
 
-  if (!GFC_CLASS_TYPE_P (t))
-return -1;
+  tree parent_type = NULL_TREE;
+  if (POINTER_TYPE_P (t))
+{
+  tree pointee_type = TREE_TYPE (t);
+  if (!is_non_root_class_wrapper_type (pointee_type))
+   return -1;
 
-  if (!(TYPE_LANG_SPECIFIC (t) && GFC_TYPE_PARENT_CLASS_TYPE (t)))
+  tree parent_wrapper_type = GFC_TYPE_PARENT_CLASS_TYPE (pointee_type);
+  if (TREE_CODE (t) == REFERENCE_TYPE)
+   parent_type = build_reference_type (parent_wrapper_type);
+  else
+   parent_type = build_pointer_type (parent_wrapper_type);
+}
+  else if (!is_non_root_class_wrapper_type (t))
 return -1;
+  else
+parent_type = GFC_TYPE_PARENT_CLASS_TYPE (t);
 
   alias_set_type new_set = get_default_alias_set (t);
   TYPE_ALIAS_SET (t) = new_set;
-  tree parent_wrapper_type = GFC_TYPE_PARENT_CLASS_TYPE (t);
-  alias_set_type parent_set = get_alias_set (parent_wrapper_type);
+  alias_set_type parent_set = get_alias_set (parent_type);
 
   record_alias_subset (parent_set, new_set);
+  
+  if (!POINTER_TYPE_P (t))
+{
+  alias_set_type parent_base_set = get_alias_set (TREE_TYPE (TYPE_FIELDS 
(parent_type)));
+  alias_set_type child_base_set = get_alias_set (TREE_TYPE (TYPE_FIELDS 
(t)));
+
+  record_alias_subset (parent_base_set, child_base_set);
+}
+
   return new_set;
 }


[gcc r15-7995] libstdc++: Correct preprocessing checks for floatX_t and bfloat_16 formatting

2025-03-12 Thread Tomasz Kaminski via Gcc-cvs
https://gcc.gnu.org/g:445128c12cf22081223f7385196ee3889ef4c4b2

commit r15-7995-g445128c12cf22081223f7385196ee3889ef4c4b2
Author: Tomasz Kamiński 
Date:   Tue Mar 11 11:59:36 2025 +0100

libstdc++: Correct preprocessing checks for floatX_t and bfloat_16 
formatting

Floating points types _Float16, _Float32, _Float64, and bfloat16,
can be formatted only if std::to_chars overloads for such types
were provided. Currently this is only the case for architectures
where float and double are 32-bits and 64-bits IEEE floating points types.

This patch updates the preprocessing checks for formatters
for above types to check _GLIBCXX_FLOAT_IS_IEEE_BINARY32
and _GLIBCXX_DOUBLE_IS_IEEE_BINARY64. Making them non-formattable
on non-IEEE architectures.

Remove a potential UB, where we could produce basic_format_arg
with _M_type set to _Arg_fp32 or _Arg_fp64, that was later not
handled by `_M_visit`.

libstdc++-v3/ChangeLog:

* include/std/format (formatter<_Float16, _CharT>): Define only if
_GLIBCXX_FLOAT_IS_IEEE_BINARY32 macro is defined.
(formatter<_Float16, _CharT>): As above.
(formatter<__gnu_cxx::__bfloat16_t, _CharT>): As above.
(formatter<_Float64, _CharT>): Define only if
_GLIBCXX_DOUBLE_IS_IEEE_BINARY64 is defined.
(basic_format_arg::_S_to_arg_type): Normalize _Float32 and _Float64
only to float and double respectivelly.
(basic_format_arg::_S_to_enum): Remove handling of _Float32 and 
_Float64.

Reviewed-by: Jonathan Wakely 
Signed-off-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/std/format | 32 
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 0d6cc7f6bef4..6cfc84cd01b7 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -2276,7 +2276,7 @@ namespace __format
 };
 #endif
 
-#ifdef __STDCPP_FLOAT16_T__
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   // Reuse __formatter_fp::format for _Float16.
   template<__format::__char _CharT>
 struct formatter<_Float16, _CharT>
@@ -2298,7 +2298,7 @@ namespace __format
 };
 #endif
 
-#if defined(__FLT32_DIG__)
+#if defined(__FLT32_DIG__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   // Reuse __formatter_fp::format for _Float32.
   template<__format::__char _CharT>
 struct formatter<_Float32, _CharT>
@@ -2320,7 +2320,7 @@ namespace __format
 };
 #endif
 
-#if defined(__FLT64_DIG__)
+#if defined(__FLT64_DIG__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
   // Reuse __formatter_fp::format for _Float64.
   template<__format::__char _CharT>
 struct formatter<_Float64, _CharT>
@@ -2364,7 +2364,7 @@ namespace __format
 };
 #endif
 
-#ifdef __STDCPP_BFLOAT16_T__
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   // Reuse __formatter_fp::format for bfloat16_t.
   template<__format::__char _CharT>
 struct formatter<__gnu_cxx::__bfloat16_t, _CharT>
@@ -3443,22 +3443,16 @@ namespace __format
return type_identity();
 #endif
 
-#ifdef __FLT32_DIG__
+#if defined(__FLT32_DIG__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
  else if constexpr (is_same_v<_Td, _Float32>)
-# ifdef _GLIBCXX_FLOAT_IS_IEEE_BINARY32
return type_identity();
-# else
-   return type_identity<_Float32>();
-# endif
 #endif
-#ifdef __FLT64_DIG__
+
+#if defined(__FLT64_DIG__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
  else if constexpr (is_same_v<_Td, _Float64>)
-# ifdef _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
return type_identity();
-# else
-   return type_identity<_Float64>();
-# endif
 #endif
+
 #if _GLIBCXX_FORMAT_F128
 # if __FLT128_DIG__
  else if constexpr (is_same_v<_Td, _Float128>)
@@ -3538,16 +3532,6 @@ namespace __format
return _Arg_u128;
 #endif
 
- // N.B. some of these types will never actually be used here,
- // because they get normalized to a standard floating-point type.
-#if defined __FLT32_DIG__ && ! _GLIBCXX_FLOAT_IS_IEEE_BINARY32
- else if constexpr (is_same_v<_Tp, _Float32>)
-   return _Arg_f32;
-#endif
-#if defined __FLT64_DIG__ && ! _GLIBCXX_DOUBLE_IS_IEEE_BINARY64
- else if constexpr (is_same_v<_Tp, _Float64>)
-   return _Arg_f64;
-#endif
 #if _GLIBCXX_FORMAT_F128 == 2
  else if constexpr (is_same_v<_Tp, __format::__float128_t>)
return _Arg_f128;


[gcc r14-11406] c++: ICE with aligned member and trivial assign op [PR117512]

2025-03-12 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:a27b24c9f4ee7fc12d077ea111200223e4a95c7d

commit r14-11406-ga27b24c9f4ee7fc12d077ea111200223e4a95c7d
Author: Marek Polacek 
Date:   Wed Mar 12 14:49:53 2025 -0400

c++: ICE with aligned member and trivial assign op [PR117512]

build_over_call has:

  t = build2 (MODIFY_EXPR, void_type_node,
  build2 (MEM_REF, array_type, arg0, alias_set),
  build2 (MEM_REF, array_type, arg, alias_set));
  val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);

which creates an expression that can look like:

  d = MEM  [(struct A *)&TARGET_EXPR  [(struct A *)(const struct A &) &e],
  TARGET_EXPR 

that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its
address is taken in the left-hand side operand, so it can't be elided.
But set_target_expr_eliding simply recurses on the second operand of
a COMPOUND_EXPR and marks the TARGET_EXPR as eliding.  This then causes
a crash.

cp_build_indirect_ref_1 should not be changing the value category.
While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would
render is a prvalue of class type.

PR c++/117512

gcc/cp/ChangeLog:

* typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e
folding if the result would be an lvalue.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas23.C: New test.
* g++.dg/ext/align3.C: New test.
* g++.dg/ext/align4.C: New test.
* g++.dg/ext/align5.C: New test.

Reviewed-by: Jason Merrill 
(cherry picked from commit 3dd7b598065ea0280fc65ce656c575c5142fa4fc)

Diff:
---
 gcc/cp/typeck.cc   |  6 +-
 gcc/testsuite/g++.dg/cpp0x/alignas23.C | 15 +++
 gcc/testsuite/g++.dg/ext/align3.C  | 14 ++
 gcc/testsuite/g++.dg/ext/align4.C  | 14 ++
 gcc/testsuite/g++.dg/ext/align5.C  | 18 ++
 5 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index e32e4a7b7acd..a3b1e52f2243 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3838,7 +3838,11 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, 
ref_operator errorstring,
  return error_mark_node;
}
   else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
-  && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0
+  && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))
+  /* Don't let this change the value category.  '*&TARGET_EXPR'
+ is an lvalue, but folding it into 'TARGET_EXPR' would turn
+ it into a prvalue of class type.  */
+  && lvalue_p (TREE_OPERAND (pointer, 0)))
/* The POINTER was something like `&x'.  We simplify `*&x' to
   `x'.  */
return TREE_OPERAND (pointer, 0);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas23.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas23.C
new file mode 100644
index ..3c218a3542c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas23.C
@@ -0,0 +1,15 @@
+// PR c++/117512
+// { dg-do compile { target c++11 } }
+
+struct A {
+  alignas(sizeof (long long)) int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align3.C 
b/gcc/testsuite/g++.dg/ext/align3.C
new file mode 100644
index ..6a20dfc57b13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align3.C
@@ -0,0 +1,14 @@
+// PR c++/117512
+
+struct A {
+  __attribute__((aligned)) int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align4.C 
b/gcc/testsuite/g++.dg/ext/align4.C
new file mode 100644
index ..b0d83e302373
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align4.C
@@ -0,0 +1,14 @@
+// PR c++/117512
+
+struct __attribute__((aligned (2 * sizeof (int A {
+  int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align5.C 
b/gcc/testsuite/g++.dg/ext/align5.C
new file mode 100644
index ..7e8212743520
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align5.C
@@ -0,0 +1,18 @@
+// PR c++/117512
+// { dg-do run }
+
+struct A {
+  __attribute__((aligned(2 * sizeof (int int i;
+  ~A() {}
+};
+
+A foo () { A a = { 19 }; return a; }
+
+int
+main ()
+{
+  A a = { 42 };
+  A r = foo () = a;
+  if (r.i != 42)
+__builtin_abort ();
+}


[gcc r15-8006] Remove bogus dg-error statements from binding_label_tests_26b.f90.

2025-03-12 Thread Thomas Koenig via Gcc-cvs
https://gcc.gnu.org/g:fdcff3f0313ddbc6948f3678833ddf30b9d30441

commit r15-8006-gfdcff3f0313ddbc6948f3678833ddf30b9d30441
Author: Thomas Koenig 
Date:   Wed Mar 12 18:53:28 2025 +0100

Remove bogus dg-error statements from binding_label_tests_26b.f90.

gcc/testsuite/ChangeLog:

PR fortran/119078
* gfortran.dg/binding_label_tests_26b.f90: Remove bogus dg-error
statements.

Diff:
---
 gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90 
b/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90
index ca399757dc83..c86cba3c77a2 100644
--- a/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90
+++ b/gcc/testsuite/gfortran.dg/binding_label_tests_26b.f90
@@ -5,8 +5,8 @@
 !
 ! Contributed by Andrew Bensons 
 
-module f! { dg-error "uses the same global identifier" }
-  use fg! { dg-error "uses the same global identifier" }
+module f
+  use fg
 end module
 
 ! { dg-final { cleanup-modules "fg f" } }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction régression class_array_9.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:198238fd1f704b11d9aaffd4e2badc8c8c24f6d7

commit 198238fd1f704b11d9aaffd4e2badc8c8c24f6d7
Author: Mikael Morin 
Date:   Wed Mar 12 19:04:10 2025 +0100

Correction régression class_array_9.f03

Diff:
---
 gcc/fortran/trans-expr.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index d8e5a5bd41d8..0b532861982c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -2959,7 +2959,7 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
   field = f2;
 }
 
-  if (ref->u.c.sym && ref->u.c.sym->ts.type == BT_CLASS
+  if (ref->u.c.sym && ref->u.c.sym->attr.is_class
   && strcmp ("_data", c->name) == 0)
 {
   /* Found a ref to the _data component.  Store the associated ref to


[gcc r13-9425] c++: ICE with lambda in fold expression in requires [PR119134]

2025-03-12 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:a4f980e837f0d2cc8fccd026570f92d3830d788b

commit r13-9425-ga4f980e837f0d2cc8fccd026570f92d3830d788b
Author: Marek Polacek 
Date:   Fri Mar 7 11:26:46 2025 -0500

c++: ICE with lambda in fold expression in requires [PR119134]

The r12-8258 fix assumes that DECL_CONTEXT of 'pack' in
check_for_bare_parameter_packs is going to be an operator()
but as this test shows, it can be empty.

PR c++/119134

gcc/cp/ChangeLog:

* pt.cc (check_for_bare_parameter_packs): Check DECL_CONTEXT.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-uneval24.C: New test.

Reviewed-by: Jason Merrill 
(cherry picked from commit 0e47062ce70d147091f1a97ec94bd6efad92bc5e)

Diff:
---
 gcc/cp/pt.cc | 1 +
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C | 4 
 2 files changed, 5 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index bb53d9881405..54b145cedc4b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4334,6 +4334,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* 
= UNKNOWN_LOCATION */)
tree pack = TREE_VALUE (parameter_packs);
if (is_capture_proxy (pack)
|| (TREE_CODE (pack) == PARM_DECL
+   && DECL_CONTEXT (pack)
&& DECL_CONTEXT (DECL_CONTEXT (pack)) == lam))
  break;
   }
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C
new file mode 100644
index ..a2b45595e479
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C
@@ -0,0 +1,4 @@
+// PR c++/119134
+// { dg-do compile { target c++20 } }
+
+void f(auto... args) requires(([args] {}, ..., true)) {}


[gcc r15-8008] arm: testsuite: remove gcc.target/arm/lp1243022.c [PR117931]

2025-03-12 Thread Richard Earnshaw via Gcc-cvs
https://gcc.gnu.org/g:9ee6c2619b256878d43800a16f7b98b3ddf59e52

commit r15-8008-g9ee6c2619b256878d43800a16f7b98b3ddf59e52
Author: Richard Earnshaw 
Date:   Wed Mar 12 18:48:55 2025 +

arm: testsuite: remove gcc.target/arm/lp1243022.c [PR117931]

This test has been failing since gcc-6.  The test was always very
fragile anyway since it relied on an auto-inc being created and then
split by the subreg2 (later the subreg3) pass.  But the code to get
precisely these conditions was very long-winded and unlikely to be
immune to other changes in the compiler (as proved to be the case).

There's no obvious way to recreate the exact conditions we were
testing for, so just remove the test.

gcc/testsuite:

PR target/117931
* gcc.target/arm/lp1243022.c: Delete non-functional test.

Diff:
---
 gcc/testsuite/gcc.target/arm/lp1243022.c | 202 ---
 1 file changed, 202 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/lp1243022.c 
b/gcc/testsuite/gcc.target/arm/lp1243022.c
deleted file mode 100644
index 11025eebd712..
--- a/gcc/testsuite/gcc.target/arm/lp1243022.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* { dg-do compile { target arm_thumb2 } } */
-/* { dg-options "-O2 -fdump-rtl-subreg2" } */
-
-/* { dg-final { scan-rtl-dump "REG_INC" "subreg2" { target { ! arm_neon } } } 
} */
-struct device;
-typedef unsigned int __u32;
-typedef unsigned long long u64;
-typedef __u32 __le32;
-typedef u64 dma_addr_t;
-typedef unsigned gfp_t;
-int dev_warn (const struct device *dev, const char *fmt, ...);
-struct usb_bus
-{
-struct device *controller;
-};
-struct usb_hcd
-{
-struct usb_bus self;
-};
-struct xhci_generic_trb
-{
-__le32 field[4];
-};
-union xhci_trb
-{
-struct xhci_generic_trb generic;
-};
-struct xhci_segment
-{
-union xhci_trb *trbs;
-dma_addr_t dma;
-};
-struct xhci_ring
-{
-struct xhci_segment *first_seg;
-};
-struct xhci_hcd
-{
-struct xhci_ring *cmd_ring;
-struct xhci_ring *event_ring;
-};
-struct usb_hcd *xhci_to_hcd (struct xhci_hcd *xhci)
-{
-}
-dma_addr_t xhci_trb_virt_to_dma (struct xhci_segment * seg,
-union xhci_trb * trb);
-struct xhci_segment *trb_in_td (struct xhci_segment *start_seg,
-   dma_addr_t suspect_dma);
-int
-xhci_test_trb_in_td (struct xhci_hcd *xhci, struct xhci_segment *input_seg,
-union xhci_trb *start_trb, union xhci_trb *end_trb,
-dma_addr_t input_dma, struct xhci_segment *result_seg,
-char *test_name, int test_number)
-{
-unsigned long long start_dma;
-unsigned long long end_dma;
-struct xhci_segment *seg;
-start_dma = xhci_trb_virt_to_dma (input_seg, start_trb);
-end_dma = xhci_trb_virt_to_dma (input_seg, end_trb);
-{
-dev_warn (xhci_to_hcd (xhci)->self.controller,
-  "%d\n", test_number);
-dev_warn (xhci_to_hcd (xhci)->self.controller,
-  "Expected seg %p, got seg %p\n", result_seg, seg);
-}
-}
-int
-xhci_check_trb_in_td_math (struct xhci_hcd *xhci, gfp_t mem_flags)
-{
-struct
-{
-dma_addr_t input_dma;
-struct xhci_segment *result_seg;
-}
-simple_test_vector[] =
-{
-{
-0, ((void *) 0)
-}
-,
-{
-xhci->event_ring->first_seg->dma - 16, ((void *) 0)}
-,
-{
-xhci->event_ring->first_seg->dma - 1, ((void *) 0)}
-,
-{
-xhci->event_ring->first_seg->dma, xhci->event_ring->first_seg}
-,
-{
-xhci->event_ring->first_seg->dma + (64 - 1) * 16,
-xhci->event_ring->first_seg
-}
-,
-{
-xhci->event_ring->first_seg->dma + (64 - 1) * 16 + 1, ((void 
*) 0)}
-,
-{
-xhci->event_ring->first_seg->dma + (64) * 16, ((void *) 0)}
-,
-{
-(dma_addr_t) (~0), ((void *) 0)
-}
-};
-struct
-{
-struct xhci_segment *input_seg;
-union xhci_trb *start_trb;
-union xhci_trb *end_trb;
-dma_addr_t input_dma;
-struct xhci_segment *result_seg;
-}
-complex_test_vector[] =
-{
-{
-.input_seg = xhci->event_ring->first_seg,.start_trb =
-xhci->event_ring->first_seg->trbs,.end_trb =
-&xhci->event_ring->first_seg->trbs[64 - 1],.input_dma =
-xhci->cmd_ring->first_seg->dma,.result_seg = ((void *) 0),
-}
-,
-{
-.input_seg = xhci->event_ring->first_seg,.start_trb =
-xhci->event_ring->first_seg->trbs,.end_trb =
-&xhci->cmd_ring->first_seg->trbs[64 - 1],.input_dma =
-xhc

[gcc r15-8005] c++: ICE with lambda in fold expression in requires [PR119134]

2025-03-12 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:0e47062ce70d147091f1a97ec94bd6efad92bc5e

commit r15-8005-g0e47062ce70d147091f1a97ec94bd6efad92bc5e
Author: Marek Polacek 
Date:   Fri Mar 7 11:26:46 2025 -0500

c++: ICE with lambda in fold expression in requires [PR119134]

The r12-8258 fix assumes that DECL_CONTEXT of 'pack' in
check_for_bare_parameter_packs is going to be an operator()
but as this test shows, it can be empty.

PR c++/119134

gcc/cp/ChangeLog:

* pt.cc (check_for_bare_parameter_packs): Check DECL_CONTEXT.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-uneval24.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/pt.cc | 1 +
 gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C | 4 
 2 files changed, 5 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 6ac9e6f163ec..8aaae4468687 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4375,6 +4375,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* 
= UNKNOWN_LOCATION */)
tree pack = TREE_VALUE (parameter_packs);
if (is_capture_proxy (pack)
|| (TREE_CODE (pack) == PARM_DECL
+   && DECL_CONTEXT (pack)
&& DECL_CONTEXT (DECL_CONTEXT (pack)) == lam))
  break;
   }
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C
new file mode 100644
index ..a2b45595e479
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval24.C
@@ -0,0 +1,4 @@
+// PR c++/119134
+// { dg-do compile { target c++20 } }
+
+void f(auto... args) requires(([args] {}, ..., true)) {}


[gcc r15-7982] Simple cobol.dg testsuite

2025-03-12 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:5712e33378bb96d29035cfd00d1774b149e54782

commit r15-7982-g5712e33378bb96d29035cfd00d1774b149e54782
Author: Richard Biener 
Date:   Tue Mar 11 09:39:06 2025 +0100

Simple cobol.dg testsuite

The following adds a simple cobol.dg test harness, based on gfortran.dg.
It's invoked by make check-cobol, has three tests, two execution test and
one test exercising dg-error.  The existing FAIL is due to an assembling
error, tracked by PR119214.

Running /home/rguenther/src/gcc/gcc/testsuite/cobol.dg/dg.exp ...
FAIL: cobol.dg/pass.cob   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (test for excess errors)
FAIL: cobol.dg/fail.cob   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (test for excess errors)

=== cobol Summary ===

 # of expected passes12
 # of unexpected failures1
 # of unresolved testcases   1

gcc/cobol/
* Make-lang.in (lang_checks): Add check-cobol.

gcc/testsuite/
* lib/cobol-dg.exp: New, based on gfortran-dg.exp.
* lib/cobol.exp: New, based on gfortran.exp.
* cobol.dg/dg.exp: New.
* cobol.dg/pass.cob: New test.
* cobol.dg/fail.cob: Likewise.
* cobol.dg/error-1.cob: Likewise.

Diff:
---
 gcc/cobol/Make-lang.in |   2 +
 gcc/testsuite/cobol.dg/dg.exp  |  41 ++
 gcc/testsuite/cobol.dg/error-1.cob |   9 ++
 gcc/testsuite/cobol.dg/fail.cob|   6 +
 gcc/testsuite/cobol.dg/pass.cob|   6 +
 gcc/testsuite/lib/cobol-dg.exp |  85 +++
 gcc/testsuite/lib/cobol.exp| 291 +
 7 files changed, 440 insertions(+)

diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index a4e005ac2bd2..cbb31d63c303 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -367,3 +367,5 @@ cobol.stagefeedback: stagefeedback-start
-mv cobol/*$(objext) stagefeedback/cobol
 
 selftest-cobol:
+
+lang_checks += check-cobol
diff --git a/gcc/testsuite/cobol.dg/dg.exp b/gcc/testsuite/cobol.dg/dg.exp
new file mode 100644
index ..c81634ac8170
--- /dev/null
+++ b/gcc/testsuite/cobol.dg/dg.exp
@@ -0,0 +1,41 @@
+#   Copyright (C) 2004-2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib cobol-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_COBFLAGS
+if ![info exists DEFAULT_COBFLAGS] then {
+set DEFAULT_COBFLAGS " "
+}
+
+# Initialize `dg'.
+dg-init
+
+global cobol_test_path
+set cobol_test_path $srcdir/$subdir
+
+set all_flags $DEFAULT_COBFLAGS
+
+# Main loop.
+cobol-dg-runtest [lsort \
+   [glob -nocomplain $srcdir/$subdir/*.cob ] ] "" $all_flags
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/cobol.dg/error-1.cob 
b/gcc/testsuite/cobol.dg/error-1.cob
new file mode 100644
index ..9e51a90b841c
--- /dev/null
+++ b/gcc/testsuite/cobol.dg/error-1.cob
@@ -0,0 +1,9 @@
+*> { dg-do compile }
+IDENTIFICATION DIVISION.
+PROGRAM-ID. error-1.
+ENVIRONMENT DIVISION.
+DATA DIVISION.
+WORKING-STORAGE SECTION.
+02 VAR PIC S9(3) VALUE 1. *> { dg-error "not part of" }
+PROCEDURE DIVISION.
+STOP RUN.
diff --git a/gcc/testsuite/cobol.dg/fail.cob b/gcc/testsuite/cobol.dg/fail.cob
new file mode 100644
index ..e0dd3eade215
--- /dev/null
+++ b/gcc/testsuite/cobol.dg/fail.cob
@@ -0,0 +1,6 @@
+*> { dg-do run { xfail *-*-* } }
+IDENTIFICATION DIVISION.
+PROGRAM-ID. fail.
+ENVIRONMENT DIVISION.
+PROCEDURE DIVISION.
+STOP RUN ERROR 1.
diff --git a/gcc/testsuite/cobol.dg/pass.cob b/gcc/testsuite/cobol.dg/pass.cob
new file mode 100644
index ..47cfd2bb09a0
--- /dev/null
+++ b/gcc/testsuite/cobol.dg/pass.cob
@@ -0,0 +1,6 @@
+*> { dg-do run }
+IDENTIFICATION DIVISION.
+PROGRAM-ID. pass.
+ENVIRONMENT DIVISION.
+PROCEDURE DIVISION.
+STOP RUN.
diff --git a/gcc/testsuite/lib/cobol-dg.exp b/gcc/testsuite/lib/cobol-dg.exp
new file mode 100644
index ..51df13df19f1
--- /dev/null
+++ b/gcc/testsuite/lib/cobol-dg.exp
@@ -0,0 +1,85 @@
+#   Copyright (C) 2004-2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribut

[gcc r15-7996] MAINTAINERS: Remove extraneous "Robert Dubner" entries

2025-03-12 Thread Robert Dubner via Gcc-cvs
https://gcc.gnu.org/g:52e297a3aa91ade5ee248fb728cf3b2f0ef320e7

commit r15-7996-g52e297a3aa91ade5ee248fb728cf3b2f0ef320e7
Author: Robert Dubner 
Date:   Wed Mar 12 08:38:57 2025 -0400

MAINTAINERS: Remove extraneous "Robert Dubner" entries

ChangeLog:

* MAINTAINERS: Remove extraneous entries for "Robert Dubner"

Diff:
---
 MAINTAINERS | 2 --
 1 file changed, 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 34e2f9f53b74..5b3fe407860f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -277,7 +277,6 @@ check in changes outside of the parts of the compiler they 
maintain.
 arm port (MVE)  Christophe Lyon 
 callgraph   Martin Jambor   
 C front end Marek Polacek   
-COBOL front end Robert Dubner   
 CTF, BTFIndu Bhagat 
 CTF, BTF, bpf port  David Faust 
 dataflowPaolo Bonzini   
@@ -447,7 +446,6 @@ Dimitar Dimitrovdimitar 

 Benoit Dupont de Dinechin   bd3 

 Lehua Ding  -   
 Ulrich Drepper  drepper 
-Robert Dubner   rdubner 
 François Dumont fdumont 
 Zdenek Dvorak   rakdver 
 Michael Eager   eager   


[gcc r15-7990] libstdc++: Prevent dangling references in std::unique_ptr::operator*

2025-03-12 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:8ff7ff1a0691b7b409aa31c8f6dfcefec3e4720b

commit r15-7990-g8ff7ff1a0691b7b409aa31c8f6dfcefec3e4720b
Author: Jonathan Wakely 
Date:   Tue Mar 11 17:29:01 2025 +

libstdc++: Prevent dangling references in std::unique_ptr::operator*

LWG 4148 (approved in Wrocław, November 2024) makes it ill-formed to
dereference a std::unique_ptr if that would return a dangling reference.

That can happen with a custom pointer type and a const-qualified
element_type, such that std::add_lvalue_reference_t is a
reference-to-const that could bind to a short-lived temporary.

In C++26 the compiler diagnoses this as an error anyway:
bits/unique_ptr.h:457:16: error: returning reference to temporary 
[-Wreturn-local-addr]
But that can be disabled with -Wno-return-local-addr so the
static_assert ensures it is enforced consistently.

libstdc++-v3/ChangeLog:

* include/bits/unique_ptr.h (unique_ptr::operator*): Add
static_assert to check for dangling reference, as per LWG 4148.
* testsuite/20_util/unique_ptr/lwg4148.cc: New test.

Reviewed-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/bits/unique_ptr.h |  8 ++
 .../testsuite/20_util/unique_ptr/lwg4148.cc| 31 ++
 2 files changed, 39 insertions(+)

diff --git a/libstdc++-v3/include/bits/unique_ptr.h 
b/libstdc++-v3/include/bits/unique_ptr.h
index 746989dfe47e..6ae46a93800c 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -445,6 +445,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   typename add_lvalue_reference::type
   operator*() const noexcept(noexcept(*std::declval()))
   {
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__reference_converts_from_temporary)
+   // _GLIBCXX_RESOLVE_LIB_DEFECTS
+   // 4148. unique_ptr::operator* should not allow dangling references
+   using _ResT = typename add_lvalue_reference::type;
+   using _DerefT = decltype(*get());
+   static_assert(!__reference_converts_from_temporary(_ResT, _DerefT),
+ "operator* must not return a dangling reference");
+#endif
__glibcxx_assert(get() != pointer());
return *get();
   }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/lwg4148.cc 
b/libstdc++-v3/testsuite/20_util/unique_ptr/lwg4148.cc
new file mode 100644
index ..c70d7a60631b
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/lwg4148.cc
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+
+// LWG 4148. unique_ptr::operator* should not allow dangling references
+
+#include 
+
+struct pointer
+{
+  pointer() { }
+  pointer(std::nullptr_t) { }
+  int operator*() const { return 0; }
+  bool operator==(pointer) const { return true; }
+  bool operator==(std::nullptr_t) const { return false; }
+#ifndef __cpp_lib_three_way_comparison
+  bool operator!=(pointer) const { return false; }
+  bool operator!=(std::nullptr_t) const { return true; }
+#endif
+};
+
+struct Deleter
+{
+  using pointer = ::pointer;
+  void operator()(pointer) const { }
+};
+
+std::unique_ptr up;
+int i = *up; // { dg-error "here" }
+// { dg-error "dangling reference" "" { target *-*-* } 0 }
+
+// { dg-warning "returning reference to temporary" "" { target c++23_down } 0 }
+// { dg-error "returning reference to temporary" "" { target c++26 } 0 }


[gcc r15-7997] Fortran: Add F2018 TEAM_NUMBER to coindexed expressions [PR98903]

2025-03-12 Thread Andre Vehreschild via Gcc-cvs
https://gcc.gnu.org/g:baa9b2b8d2eef7177118652d93ca0e7c933ba174

commit r15-7997-gbaa9b2b8d2eef7177118652d93ca0e7c933ba174
Author: Andre Vehreschild 
Date:   Thu Mar 6 15:14:24 2025 +0100

Fortran: Add F2018 TEAM_NUMBER to coindexed expressions [PR98903]

Add missing parsing and code generation for a[..., TEAM_NUMBER=...] as
defined from F2015 onwards.  Because F2015 is not used as dedicated
standard in GFortran add it to the F2018 standard feature set.

PR fortran/98903

gcc/fortran/ChangeLog:

* array.cc (gfc_copy_array_ref): Copy team, team_type and stat.
(match_team_or_stat): Match a single team(_number)= or stat=.
(gfc_match_array_ref): Add switching to image_selector_parsing
and error handling when indices come after named arguments.
* coarray.cc (move_coarray_ref): Move also team_type.
* expr.cc (gfc_free_ref_list): Free team and stat expression.
(gfc_find_team_co): Find team or team_number in array-ref.
* gfortran.h (enum gfc_array_ref_team_type): New enum to
distinguish unset, team or team_number expression.
(gfc_find_team_co): Default searching to team= expressions.
* resolve.cc (resolve_array_ref): Check for type correctness of
team(_number) and stats in coindices.
* trans-array.cc (gfc_conv_array_ref): Ensure stat is cleared
when fcoarray=single is used.
* trans-intrinsic.cc (conv_stat_and_team): Including team_number
in conversion.
(gfc_conv_intrinsic_caf_get): Propagate team_number to ABI
routine.
(conv_caf_send_to_remote): Same.
(conv_caf_sendget): Same.

gcc/testsuite/ChangeLog:

* gfortran.dg/coarray/coindexed_2.f90: New test.
* gfortran.dg/coarray/coindexed_3.f08: New test.
* gfortran.dg/coarray/coindexed_4.f08: New test.

Diff:
---
 gcc/fortran/array.cc  | 172 +++---
 gcc/fortran/coarray.cc|   2 +
 gcc/fortran/expr.cc   |  12 +-
 gcc/fortran/gfortran.h|   9 +-
 gcc/fortran/resolve.cc|  75 ++
 gcc/fortran/trans-array.cc|   9 ++
 gcc/fortran/trans-intrinsic.cc|  50 ---
 gcc/testsuite/gfortran.dg/coarray/coindexed_2.f90 |  44 ++
 gcc/testsuite/gfortran.dg/coarray/coindexed_3.f08 |  30 
 gcc/testsuite/gfortran.dg/coarray/coindexed_4.f08 |  13 ++
 10 files changed, 342 insertions(+), 74 deletions(-)

diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index 841a0ac4a844..fa177fa91f7e 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -51,6 +51,9 @@ gfc_copy_array_ref (gfc_array_ref *src)
   dest->stride[i] = gfc_copy_expr (src->stride[i]);
 }
 
+  dest->stat = gfc_copy_expr (src->stat);
+  dest->team = gfc_copy_expr (src->team);
+
   return dest;
 }
 
@@ -172,6 +175,76 @@ matched:
   return (saw_boz ? MATCH_ERROR : MATCH_YES);
 }
 
+/** Match one of TEAM=, TEAM_NUMBER= or STAT=.  */
+
+match
+match_team_or_stat (gfc_array_ref *ar)
+{
+  gfc_expr *tmp;
+  bool team_error = false;
+
+  if (gfc_match (" team = %e", &tmp) == MATCH_YES)
+{
+  if (ar->team == NULL && ar->team_type == TEAM_UNSET)
+   {
+ ar->team = tmp;
+ ar->team_type = TEAM_TEAM;
+   }
+  else if (ar->team_type == TEAM_TEAM)
+   {
+ gfc_error ("Duplicate TEAM= attribute in %C");
+ return MATCH_ERROR;
+   }
+  else
+   team_error = true;
+}
+  else if (gfc_match (" team_number = %e", &tmp) == MATCH_YES)
+{
+  if (!gfc_notify_std (GFC_STD_F2018, "TEAM_NUMBER= not supported at %C"))
+   return MATCH_ERROR;
+  if (ar->team == NULL && ar->team_type == TEAM_UNSET)
+   {
+ ar->team = tmp;
+ ar->team_type = TEAM_NUMBER;
+   }
+  else if (ar->team_type == TEAM_NUMBER)
+   {
+ gfc_error ("Duplicate TEAM_NUMBER= attribute in %C");
+ return MATCH_ERROR;
+   }
+  else
+   team_error = true;
+}
+  else if (gfc_match (" stat = %e", &tmp) == MATCH_YES)
+{
+  if (ar->stat == NULL)
+   {
+ if (gfc_is_coindexed (tmp))
+   {
+ gfc_error ("Expression in STAT= at %C must not be coindexed");
+ gfc_free_expr (tmp);
+ return MATCH_ERROR;
+   }
+ ar->stat = tmp;
+   }
+  else
+   {
+ gfc_error ("Duplicate STAT= attribute in %C");
+ return MATCH_ERROR;
+   }
+}
+  else
+return MATCH_NO;
+
+  if (ar->team && team_error)
+{
+  gfc_error ("Only one of TEAM= or TEAM_NUMBER= may appear in a "
+"coarray reference at %C");
+  return MATCH_ERROR;
+}
+
+  return MATCH_YES;
+}
 
 /* Match an array r

[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa: dce fix marking

2025-03-12 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:775add98a313f182c3f45e6a0931f2ed612dab24

commit 775add98a313f182c3f45e6a0931f2ed612dab24
Author: Ondřej Machota 
Date:   Tue Mar 11 11:03:56 2025 +0100

rtl-ssa: dce fix marking

Diff:
---
 gcc/dce.cc | 77 ++
 1 file changed, 67 insertions(+), 10 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index 14d7e1fa9120..e612243c01be 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1582,6 +1582,57 @@ rtl_ssa_dce_mark()
 {
   std::unordered_set marked{};
   auto worklist = rtl_ssa_dce_prelive(marked);
+  auto_vec worklist_new{};
+  for (auto && item : worklist) {
+insn_info * insn = item;
+for (auto&& use : insn->uses()) {
+  set_info* set = use->def();
+  if (set) {
+worklist_new.safe_push(set);
+  }
+}
+  }
+
+  while (!worklist_new.is_empty()) {
+set_info* set = worklist_new.pop();
+insn_info* insn = set->insn();
+if (!insn) {
+  continue;
+}
+
+if (!(marked.count(insn) > 0))
+{
+  marked.emplace(insn);
+}
+
+// use_array uses = insn->uses();
+if (insn->is_phi()) {
+  phi_info* pi = as_a (set);
+  
+  for (auto && input : pi->inputs()) {
+use_info* use = input;
+set_info* parent_set = use->def();
+if (!parent_set) { // Clobber...
+  continue;
+}
+
+worklist_new.safe_push(parent_set);
+  }
+} else {
+  if (dump_file)
+fprintf(dump_file, "  Adding insn %d to worklist - mark\n", 
insn->uid());
+  
+  for (auto && use__ : insn->uses()) {
+use_info * use = use__;
+set_info* parent_set = use->def();
+if (!parent_set) {
+  continue;
+}
+
+worklist_new.safe_push(parent_set);
+  }
+}
+  }
 
   if (dump_file)
 fprintf(dump_file, "Finished inherently live, marking parents\n");
@@ -1620,17 +1671,23 @@ rtl_ssa_dce_mark()
   // debug(use);
   // std::cerr << '\n';
   
-  
-  insn_info *parent_insn = use->def()->insn();
-  if (parent_insn->is_phi()) { // this is weird...
-// debug(use->def());
-phi_info * pi = as_a (use->def());
-// std::cerr << "phi inputs: " << pi->num_inputs() << '\n';
-for (auto&& input: pi->inputs()) {
-  use_info* phi_use = input;
-  std::cerr << "Via phi insn: " << phi_use->def()->insn()->uid() << 
'\n';
-}
+  set_info* set = use->def();
+  if (!set) {
+continue;
+  }
+  insn_info *parent_insn = set->insn();
+  if (!parent_insn) {
+continue;
   }
+  // if (parent_insn->is_phi()) { // this is weird...
+  //   // debug(use->def());
+  //   phi_info * pi = as_a (use->def());
+  //   // std::cerr << "phi inputs: " << pi->num_inputs() << '\n';
+  //   for (auto&& input: pi->inputs()) {
+  // use_info* phi_use = input;
+  // std::cerr << "Via phi insn: " << phi_use->def()->insn()->uid() << 
'\n';
+  //   }
+  // }
   int parent_insn_uid = parent_insn->uid();
   // propage that some instruction in chain is live from bottom to top
   if (dump_file)


[gcc(refs/users/omachota/heads/rtl-ssa-dce)] rtl-ssa-dce: improve marking, but still not correct

2025-03-12 Thread Ondrej Machota via Gcc-cvs
https://gcc.gnu.org/g:0950f89fdd8a433f2dcccf45dcb088d3be16130c

commit 0950f89fdd8a433f2dcccf45dcb088d3be16130c
Author: Ondřej Machota 
Date:   Wed Mar 12 13:12:43 2025 +0100

rtl-ssa-dce: improve marking, but still not correct

Diff:
---
 gcc/dce.cc | 211 +
 1 file changed, 113 insertions(+), 98 deletions(-)

diff --git a/gcc/dce.cc b/gcc/dce.cc
index e612243c01be..959677663855 100644
--- a/gcc/dce.cc
+++ b/gcc/dce.cc
@@ -1387,10 +1387,12 @@ bool side_effects_with_mem (const_rtx x)
   return true;
 
 case MEM: // We might want tu return true iff volatile or mem is a 
destination
+  // write or possible null read
 case ASM_INPUT:
 case ASM_OPERANDS:
return true;
 
+// This should rather by RTX_BODY in is_rtx_insn_prelive - like global 
clobber
 case USE:
   return true;
 
@@ -1468,6 +1470,9 @@ bool is_rtx_insn_prelive(rtx_insn *insn) {
 return true;
 
   rtx body = PATTERN(insn);
+  if (GET_CODE(body) == CLOBBER) // 
~/Documents/gcc/gcc/testsuite/gcc.c-torture/compile/2605-1.c
+return true;
+
   if (side_effects_with_mem(body) || can_throw_internal(body))
 return true;
 
@@ -1585,6 +1590,7 @@ rtl_ssa_dce_mark()
   auto_vec worklist_new{};
   for (auto && item : worklist) {
 insn_info * insn = item;
+std::cerr << "cp Current: " << insn->uid() << '\n';
 for (auto&& use : insn->uses()) {
   set_info* set = use->def();
   if (set) {
@@ -1600,118 +1606,119 @@ rtl_ssa_dce_mark()
   continue;
 }
 
-if (!(marked.count(insn) > 0))
-{
-  marked.emplace(insn);
-}
+/*
+ * TODO : a phi insn might be visited more times due to having more phi 
nodes
+ * Either we have to mark phi nodes or do not mark phi insn
+*/
+std::cerr << "Current: " << insn->uid() << '\n';
+// if (insn->uid() == -21) {
+  // std::cerr << "Insn -21 phi? " << insn->is_phi() << '\n';
+// }
 
-// use_array uses = insn->uses();
-if (insn->is_phi()) {
-  phi_info* pi = as_a (set);
-  
-  for (auto && input : pi->inputs()) {
-use_info* use = input;
-set_info* parent_set = use->def();
-if (!parent_set) { // Clobber...
-  continue;
-}
-
-worklist_new.safe_push(parent_set);
-  }
-} else {
-  if (dump_file)
-fprintf(dump_file, "  Adding insn %d to worklist - mark\n", 
insn->uid());
-  
-  for (auto && use__ : insn->uses()) {
-use_info * use = use__;
-set_info* parent_set = use->def();
-if (!parent_set) {
-  continue;
-}
-
-worklist_new.safe_push(parent_set);
-  }
+if ((marked.count(insn) > 0)) {
+  continue;
 }
-  }
 
-  if (dump_file)
-fprintf(dump_file, "Finished inherently live, marking parents\n");
-  while (!worklist.is_empty())
-  {
-insn_info *insn = worklist.pop();
+marked.emplace(insn);
+
 use_array uses = insn->uses();
 if (insn->is_phi()) {
-  std::cerr << "Phi : "<< insn->uid() << " - uses: " << insn->num_uses() 
<< ", defs:" << insn->num_defs() << '\n';
-  for (auto&& use : uses) {
-debug(use);
-std::cerr << '\n';
-  }
-} else if (insn->is_artificial()) {
-  std::cerr << "Artificial " << insn->uid() << " - uses: " << 
insn->num_uses() << ", defs:" << insn->num_defs() << '\n';
-  for (auto&& use : uses) {
-debug(use);
-std::cerr << '\n';
-  }
+  phi_info* pi = as_a (set);
+  uses = pi->inputs();
 }
 
 if (dump_file)
-  fprintf(dump_file, "Looking at: %d, uses: %d\n", insn->uid(), 
uses.size());
-
-//std::cerr << "Insn: " << insn->uid() << ", uses: " << uses.size() << 
'\n';
-  std::cerr << "Current: " << insn->uid() << '\n';
-for (size_t i = 0; i < uses.size(); i++)
-{
-  // debug(uses[i]);
-  use_info* use = uses[i];
-  // debug(use->def());
-  // if (use->def() != nullptr) {
-  //   std::cerr << use->def()->insn()->uid() << '\n';
-  // }
-  // std::cerr << '\n';
-  // debug(use);
-  // std::cerr << '\n';
-  
-  set_info* set = use->def();
-  if (!set) {
+  fprintf(dump_file, "  Adding insn %d to worklist - mark\n", insn->uid());
+
+for (auto && use__ : uses) {
+  use_info * use = use__;
+  set_info* parent_set = use->def();
+  if (!parent_set) {
 continue;
   }
-  insn_info *parent_insn = set->insn();
-  if (!parent_insn) {
-continue;
-  }
-  // if (parent_insn->is_phi()) { // this is weird...
-  //   // debug(use->def());
-  //   phi_info * pi = as_a (use->def());
-  //   // std::cerr << "phi inputs: " << pi->num_inputs() << '\n';
-  //   for (auto&& input: pi->inputs()) {
-  // use_info* phi_use = input;
-  // std::cerr << "Via phi insn: " << phi_use->def()->insn()->uid() << 
'\n';
-  //   }
-  // }
-  int parent_insn_uid = par

[gcc r15-7994] libgcobol: Fix typo in comment

2025-03-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:2ac842a1e82efc6e4e4d21f880c9888c523788e7

commit r15-7994-g2ac842a1e82efc6e4e4d21f880c9888c523788e7
Author: Jonathan Wakely 
Date:   Wed Mar 12 11:34:08 2025 +

libgcobol: Fix typo in comment

libgcobol/ChangeLog:

* charmaps.cc: Fix typo in comment.

Diff:
---
 libgcobol/charmaps.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgcobol/charmaps.cc b/libgcobol/charmaps.cc
index 3b75c08dd2f7..561fe2301215 100644
--- a/libgcobol/charmaps.cc
+++ b/libgcobol/charmaps.cc
@@ -250,7 +250,7 @@ cp1252_to_utf8_values[256] =
 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 
0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, // F0
 };
 
-// This map table doe the reverse UTF-8 conversion back to cp1252
+// This map table does the reverse UTF-8 conversion back to cp1252
 static const std::unordered_maputf8_to_cp1252_values =
 {
 {0x, 0x00}, {0x0001, 0x01}, {0x0002, 0x02}, {0x0003, 0x03}, {0x0004, 
0x04}, {0x0005, 0x05}, {0x0006, 0x06}, {0x0007, 0x07},


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction régression typebound_generic_6.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d656665abfb7c6172f982d13c1da825c3eb4786d

commit d656665abfb7c6172f982d13c1da825c3eb4786d
Author: Mikael Morin 
Date:   Mon Mar 10 22:42:35 2025 +0100

Correction régression typebound_generic_6.f03

Diff:
---
 gcc/alias.cc   | 11 ++-
 gcc/alias.h|  1 +
 gcc/fortran/f95-lang.cc| 28 +++
 gcc/fortran/trans-types.cc | 48 +++---
 gcc/fortran/trans.h|  4 +++-
 5 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/gcc/alias.cc b/gcc/alias.cc
index 497c2ac0e33a..1b512f655f21 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -972,11 +972,20 @@ get_alias_set (tree t)
   set = lang_hooks.get_alias_set (t);
   if (set != -1)
 return set;
+  else
+return get_default_alias_set (t);
+}
+
 
+alias_set_type
+get_default_alias_set (tree t)
+{
+  alias_set_type set;
+  
   /* There are no objects of FUNCTION_TYPE, so there's no point in
  using up an alias set for them.  (There are, of course, pointers
  and references to functions, but that's different.)  */
-  else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
+  if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
 set = 0;
 
   /* Unless the language specifies otherwise, let vector types alias
diff --git a/gcc/alias.h b/gcc/alias.h
index 7c2e33eaa73e..6271dcc7089a 100644
--- a/gcc/alias.h
+++ b/gcc/alias.h
@@ -42,6 +42,7 @@ int compare_base_decls (tree, tree);
 bool refs_same_for_tbaa_p (tree, tree);
 bool mems_same_for_tbaa_p (rtx, rtx);
 bool view_converted_memref_p (tree);
+alias_set_type get_default_alias_set (tree);
 
 /* This alias set can be used to force a memory to conflict with all
other memories, creating a barrier across which no memory reference
diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc
index 124d62f45295..c5098a24102a 100644
--- a/gcc/fortran/f95-lang.cc
+++ b/gcc/fortran/f95-lang.cc
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "trans-types.h"
 #include "trans-const.h"
 #include "attribs.h"
+#include "alias.h"
 
 /* Language-dependent contents of an identifier.  */
 
@@ -78,6 +79,8 @@ static void gfc_finish (void);
 static void gfc_be_parse_file (void);
 static void gfc_init_ts (void);
 static tree gfc_builtin_function (tree);
+static alias_set_type gfc_get_alias_set (tree t);
+
 
 /* Handle an "omp declare target" attribute; arguments as in
struct attribute_spec.handler.  */
@@ -134,6 +137,7 @@ gfc_get_sarif_source_language (const char *)
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #undef LANG_HOOKS_TYPE_FOR_SIZE
 #undef LANG_HOOKS_INIT_TS
+#undef LANG_HOOKS_GET_ALIAS_SET
 #undef LANG_HOOKS_OMP_ARRAY_DATA
 #undef LANG_HOOKS_OMP_ARRAY_SIZE
 #undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR
@@ -174,6 +178,7 @@ gfc_get_sarif_source_language (const char *)
 #define LANG_HOOKS_TYPE_FOR_MODE   gfc_type_for_mode
 #define LANG_HOOKS_TYPE_FOR_SIZE   gfc_type_for_size
 #define LANG_HOOKS_INIT_TS gfc_init_ts
+#define LANG_HOOKS_GET_ALIAS_SETgfc_get_alias_set
 #define LANG_HOOKS_OMP_ARRAY_DATA  gfc_omp_array_data
 #define LANG_HOOKS_OMP_ARRAY_SIZE  gfc_omp_array_size
 #define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR   gfc_omp_is_allocatable_or_ptr
@@ -303,6 +308,29 @@ gfc_finish (void)
   return;
 }
 
+
+static alias_set_type
+gfc_get_alias_set (tree t)
+{
+  if (!TYPE_P (t))
+return -1;
+
+  if (!GFC_CLASS_TYPE_P (t))
+return -1;
+
+  if (!(TYPE_LANG_SPECIFIC (t) && GFC_TYPE_PARENT_CLASS_TYPE (t)))
+return -1;
+
+  alias_set_type new_set = get_default_alias_set (t);
+  TYPE_ALIAS_SET (t) = new_set;
+  tree parent_wrapper_type = GFC_TYPE_PARENT_CLASS_TYPE (t);
+  alias_set_type parent_set = get_alias_set (parent_wrapper_type);
+
+  record_alias_subset (parent_set, new_set);
+  return new_set;
+}
+
+
 /* These functions and variables deal with binding contours.  We only
need these functions for the list of PARM_DECLs, but we leave the
functions more general; these are a simplified version of the
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 83c004b0455d..2a1ab3c6ef58 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2825,15 +2825,8 @@ cobounds_match_decl (const gfc_symbol *derived)
 
 
 gfc_symbol *
-get_class_canonical_type (gfc_symbol *cls)
+get_class_canonical_type (gfc_symbol *derived, int rank, int corank)
 {
-  gcc_assert (cls->attr.is_class);
-
-  gfc_component * data_comp = cls->components;
-
-  gfc_symbol *derived = data_comp->ts.u.derived;
-  int rank = data_comp->as ? data_comp->as->rank : 0;
-  int corank = data_comp->as ? data_comp->as->corank : 0;
   const char *class_name = gfc_class_name (derived, rank, corank, 0, 0);
 
   gfc_namespace *ns = gfc_class_namespace (derived);
@@ -2857,12 +2850,12 @@ get_class_canonical_type (gfc_symbol *cls)
 
   gfc_array_spec as;
   gfc_array_spec *pas;

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction class_defined_operator_1.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ebad9592fab8e31ed15092b2cfa1ed23af3e9569

commit ebad9592fab8e31ed15092b2cfa1ed23af3e9569
Author: Mikael Morin 
Date:   Wed Mar 12 15:19:04 2025 +0100

Correction class_defined_operator_1.f03

Diff:
---
 gcc/fortran/f95-lang.cc | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/f95-lang.cc b/gcc/fortran/f95-lang.cc
index dec2485168b3..851723bc9704 100644
--- a/gcc/fortran/f95-lang.cc
+++ b/gcc/fortran/f95-lang.cc
@@ -357,10 +357,17 @@ gfc_get_alias_set (tree t)
   
   if (!POINTER_TYPE_P (t))
 {
-  alias_set_type parent_base_set = get_alias_set (TREE_TYPE (TYPE_FIELDS 
(parent_type)));
-  alias_set_type child_base_set = get_alias_set (TREE_TYPE (TYPE_FIELDS 
(t)));
-
+  tree parent_field = TYPE_FIELDS (parent_type);
+  tree child_field = TYPE_FIELDS (t);
+  alias_set_type parent_base_set = get_alias_set (parent_field);
+  alias_set_type child_base_set = get_alias_set (child_field);
   record_alias_subset (parent_base_set, child_base_set);
+
+  parent_field = TREE_CHAIN (parent_field);
+  child_field = TREE_CHAIN (child_field);
+  alias_set_type parent_vtype_ptr_set = get_alias_set (TREE_TYPE 
(parent_field));
+  alias_set_type child_vtype_ptr_set = get_alias_set (TREE_TYPE 
(child_field));
+  record_alias_subset (parent_vtype_ptr_set, child_vtype_ptr_set);
 }
 
   return new_set;


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction dynamic_dispatch_6.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:dbc518c31fd3da3050ce399fb30ad951cddea8cf

commit dbc518c31fd3da3050ce399fb30ad951cddea8cf
Author: Mikael Morin 
Date:   Tue Mar 11 15:21:14 2025 +0100

Correction dynamic_dispatch_6.f03

Diff:
---
 gcc/fortran/trans-types.cc | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 3b818ba74fd4..53216a25847e 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2863,7 +2863,11 @@ get_class_canonical_type (gfc_symbol *derived, int rank, 
int corank)
 
   gfc_find_symbol (class_name, ns, 0, &canonical_class);
   if (canonical_class)
-gfc_resolve_symbol (canonical_class);
+{
+  if (derived->module)
+   canonical_class->module = gfc_get_string ("%s", derived->module);
+  gfc_resolve_symbol (canonical_class);
+}
 
   return canonical_class;
 }
@@ -3222,7 +3226,10 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen)
 {
   gfc_symbol * canonical_sym = get_class_canonical_type (derived);
   if (canonical_sym != nullptr)
-   TYPE_CANONICAL (typenode) = gfc_get_derived_type (canonical_sym, 
codimen);
+   {
+ tree canonical_sym_decl = gfc_get_derived_type (canonical_sym, 
codimen);
+ TYPE_CANONICAL (typenode) = TYPE_CANONICAL (canonical_sym_decl);
+   }
   gfc_component * data_comp = derived->components;
   gfc_symbol *orig_type = data_comp->ts.u.derived;
   if (orig_type->attr.extension)


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction régression dynamic_dispatch_11.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:9439e1aeaa0abf0de5ca6c9d3b46c2d2f5dd4b6f

commit 9439e1aeaa0abf0de5ca6c9d3b46c2d2f5dd4b6f
Author: Mikael Morin 
Date:   Tue Mar 11 12:17:15 2025 +0100

Correction régression dynamic_dispatch_11.f03

Resolve class symbol type.

Diff:
---
 gcc/fortran/gfortran.h | 1 +
 gcc/fortran/resolve.cc | 7 +++
 gcc/fortran/trans-types.cc | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 052f884f3ea4..29ad015f0d10 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3485,6 +3485,7 @@ void gfc_maybe_initialize_eh (void);
 /* iresolve.cc */
 const char * gfc_get_string (const char *, ...) ATTRIBUTE_PRINTF_1;
 bool gfc_find_sym_in_expr (gfc_symbol *, gfc_expr *);
+void gfc_resolve_symbol (gfc_symbol *);
 
 /* error.cc */
 locus gfc_get_location_range (locus *, unsigned, locus *, unsigned, locus *);
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 2c8fb78ca6a9..5fcfc2c83b7d 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -18525,6 +18525,13 @@ skip_interfaces:
 }
 
 
+void
+gfc_resolve_symbol (gfc_symbol *sym)
+{
+  resolve_symbol (sym);
+}
+
+
 /* Resolve DATA statements */
 
 static struct
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 2a1ab3c6ef58..6b8dbf1225aa 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2865,6 +2865,8 @@ get_class_canonical_type (gfc_symbol *derived, int rank, 
int corank)
   gfc_build_class_symbol (&ts, &attr, &pas);
 
   gfc_find_symbol (class_name, ns, 0, &canonical_class);
+  if (canonical_class)
+gfc_resolve_symbol (canonical_class);
 
   return canonical_class;
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction reste régression class_defined_operator_2.f03

2025-03-12 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:996cb111be0a759162dd37e819ddbfdba4d50a7d

commit 996cb111be0a759162dd37e819ddbfdba4d50a7d
Author: Mikael Morin 
Date:   Tue Mar 11 13:39:58 2025 +0100

Correction reste régression class_defined_operator_2.f03

Diff:
---
 gcc/fortran/trans-types.cc | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 6b8dbf1225aa..3b818ba74fd4 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -2845,24 +2845,21 @@ get_class_canonical_type (gfc_symbol *derived, int 
rank, int corank)
   symbol_attribute attr;
   memset (&attr, 0, sizeof (attr));
   attr.dummy = 1;
-  attr.dimension = derived->attr.dimension;
-  attr.codimension = derived->attr.codimension;
+  attr.dimension = rank != 0;
+  attr.codimension = corank != 0;
 
-  gfc_array_spec as;
-  gfc_array_spec *pas;
+  gfc_array_spec *as;
   if (rank != 0 || corank != 0)
 {
-  memset (&as, 0, sizeof (as));
-  as.type = AS_DEFERRED;
-  as.rank = rank;
-  as.corank = corank;
-
-  pas = &as;
+  as = gfc_get_array_spec ();
+  as->type = AS_DEFERRED;
+  as->rank = rank;
+  as->corank = corank;
 }
   else
-pas = nullptr;
+as = nullptr;
 
-  gfc_build_class_symbol (&ts, &attr, &pas);
+  gfc_build_class_symbol (&ts, &attr, &as);
 
   gfc_find_symbol (class_name, ns, 0, &canonical_class);
   if (canonical_class)


gcc-cvs@gcc.gnu.org

2025-03-12 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:4d2683b04fd329c97e3da09498345fe3ee00455f

commit r15-8003-g4d2683b04fd329c97e3da09498345fe3ee00455f
Author: Jonathan Wakely 
Date:   Mon Mar 10 14:29:36 2025 +

libstdc++: Add static_assert to std::packaged_task::packaged_task(F&&)

LWG 4154 (approved in Wrocław, November 2024) fixed the Mandates:
precondition for std::packaged_task::packaged_task(F&&) to match what
the implementation actually requires. We already gave a diagnostic in
the right cases as required by the issue resolution, so strictly
speaking we don't need to do anything. But the current diagnostic comes
from inside the implementation of std::__invoke_r and could be more
user-friendly.

For C++17 (when std::is_invocable_r_v is available) add a static_assert
to the constructor, so the error is clear:

.../include/c++/15.0.1/future: In instantiation of 
'std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(_Fn&&) [with _Fn = 
const F&;  = void; _Res = void; _ArgTypes = {}]':
lwg4154_neg.cc:15:31:   required from here
   15 | std::packaged_task p(f); // { dg-error "here" "" { target 
c++17 } }
  |   ^
.../include/c++/15.0.1/future:1575:25: error: static assertion failed
 1575 |   static_assert(is_invocable_r_v<_Res, decay_t<_Fn>&, 
_ArgTypes...>);
  | 
^~~

Also add a test to confirm we get a diagnostic as the standard requires.

libstdc++-v3/ChangeLog:

* include/std/future (packaged_task::packaged_task(F&&)): Add
static_assert.
* testsuite/30_threads/packaged_task/cons/dangling_ref.cc: Add
dg-error for new static assertion.
* testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc: New
test.

Reviewed-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/std/future|  9 -
 .../30_threads/packaged_task/cons/dangling_ref.cc  |  1 +
 .../30_threads/packaged_task/cons/lwg4154_neg.cc   | 38 ++
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 2a855f262a0a..b7ab233b85f0 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -1567,7 +1567,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
packaged_task(_Fn&& __fn)
: _M_state(
__create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn)))
-   { }
+   {
+#ifdef __cpp_lib_is_invocable // C++ >= 17
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4154. The Mandates for std::packaged_task's constructor
+ // from a callable entity should consider decaying
+ static_assert(is_invocable_r_v<_Res, decay_t<_Fn>&, _ArgTypes...>);
+#endif
+   }
 
 #if __cplusplus < 201703L
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
diff --git 
a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc 
b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
index 225b65fe6a7d..51c6ade91c36 100644
--- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
@@ -10,3 +10,4 @@ std::packaged_task task(f);
 // { dg-error "reference to temporary" "" { target { c++14_down } } 0 }
 // { dg-error "no matching function" "" { target c++17 } 0 }
 // { dg-error "enable_if" "" { target c++17 } 0 }
+// { dg-error "static assertion failed" "" { target c++17 } 0 }
diff --git 
a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc 
b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc
new file mode 100644
index ..6ba1bb1a53e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc
@@ -0,0 +1,38 @@
+// { dg-do compile { target c++11 } }
+
+// LWG 4154. The Mandates for std::packaged_task's constructor from
+// a callable entity should consider decaying
+
+#include 
+
+struct F {
+  void operator()() & = delete;
+  void operator()() const & { }
+};
+
+// Mandates: is_invocable_r_v&, ArgTypes...> is true.
+const F f;
+std::packaged_task p(f); // { dg-error "here" "" { target c++17 } }
+// { dg-error "static assertion failed" "" { target c++17 } 0 }
+// { dg-error "invoke_r" "" { target *-*-* } 0 }
+// { dg-prune-output "enable_if p2(Frv{}); // { dg-error "here" "" { target c++17 } 
}
+
+// Only callable as non-const lvalue
+struct Fnc {
+  void operator()() const & = delete;
+  void operator()() & { }
+};
+
+// In C++11/14/17/20 std::packaged_task::packaged_task(F&&) incorrectly
+// required that the callable passed to the constructor can be invoked.
+// If the type of the parameter is const F& we might not be able to invoke
+// the parameter, but that's OK because we store and invoke a non-const F.
+// So this should work without errors:
+

[gcc r15-8002] libstdc++: Update tzdata to 2025a

2025-03-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:0ce4c1c48564e465a331c100e757e2258b4c632a

commit r15-8002-g0ce4c1c48564e465a331c100e757e2258b4c632a
Author: Jonathan Wakely 
Date:   Fri Jan 12 16:57:41 2024 +

libstdc++: Update tzdata to 2025a

Import the new 2025a tzdata.zi file. The leapseconds file was also
updated to have a new expiry (no new leap seconds were added).

libstdc++-v3/ChangeLog:

* include/std/chrono (__detail::__get_leap_second_info): Update
expiry date for leap seconds list.
* src/c++20/tzdata.zi: Import new file from 2025a release.
* src/c++20/tzdb.cc (tzdb_list::_Node::_S_read_leap_seconds)
Update expiry date for leap seconds list.

Diff:
---
 libstdc++-v3/include/std/chrono  |2 +-
 libstdc++-v3/src/c++20/tzdata.zi | 1682 +++---
 libstdc++-v3/src/c++20/tzdb.cc   |4 +-
 3 files changed, 840 insertions(+), 848 deletions(-)

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index 095a35e5b75b..8eb9fd9baac0 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -3260,7 +3260,7 @@ namespace __detail
   };
   // The list above is known to be valid until (at least) this date
   // and only contains positive leap seconds.
-  const sys_seconds __expires(1735344000s); // 2024-12-28 00:00:00 UTC
+  const sys_seconds __expires(176688s); // 2025-12-28 00:00:00 UTC
 
 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   if (__ss > __expires)
diff --git a/libstdc++-v3/src/c++20/tzdata.zi b/libstdc++-v3/src/c++20/tzdata.zi
index be1c40859202..db6ba4af2b01 100644
--- a/libstdc++-v3/src/c++20/tzdata.zi
+++ b/libstdc++-v3/src/c++20/tzdata.zi
@@ -1,4 +1,4 @@
-# version 2024a
+# version 2025a
 # This zic input file is in the public domain.
 R d 1916 o - Jun 14 23s 1 S
 R d 1916 1919 - O Su>=1 23s 0 -
@@ -721,12 +721,16 @@ R P 2085 o - Ap 21 2 0 -
 R P 2085 o - Jun 9 2 1 S
 R P 2086 o - Ap 13 2 0 -
 R P 2086 o - May 25 2 1 S
-R PH 1936 o - N 1 0 1 D
-R PH 1937 o - F 1 0 0 S
-R PH 1954 o - Ap 12 0 1 D
-R PH 1954 o - Jul 1 0 0 S
-R PH 1978 o - Mar 22 0 1 D
-R PH 1978 o - S 21 0 0 S
+R PH 1936 o - O 31 24 1 D
+R PH 1937 o - Ja 15 24 0 S
+R PH 1941 o - D 15 24 1 D
+R PH 1945 o - N 30 24 0 S
+R PH 1954 o - Ap 11 24 1 D
+R PH 1954 o - Jun 4 24 0 S
+R PH 1977 o - Mar 27 24 1 D
+R PH 1977 o - S 21 24 0 S
+R PH 1990 o - May 21 0 1 D
+R PH 1990 o - Jul 28 24 0 S
 R S 1920 1923 - Ap Su>=15 2 1 S
 R S 1920 1923 - O Su>=1 2 0 -
 R S 1962 o - Ap 29 2 1 S
@@ -1324,14 +1328,10 @@ R O 1961 1964 - May lastSu 1s 1 S
 R O 1962 1964 - S lastSu 1s 0 -
 R p 1916 o - Jun 17 23 1 S
 R p 1916 o - N 1 1 0 -
-R p 1917 o - F 28 23s 1 S
-R p 1917 1921 - O 14 23s 0 -
-R p 1918 o - Mar 1 23s 1 S
-R p 1919 o - F 28 23s 1 S
-R p 1920 o - F 29 23s 1 S
-R p 1921 o - F 28 23s 1 S
+R p 1917 1921 - Mar 1 0 1 S
+R p 1917 1921 - O 14 24 0 -
 R p 1924 o - Ap 16 23s 1 S
-R p 1924 o - O 14 23s 0 -
+R p 1924 o - O 4 23s 0 -
 R p 1926 o - Ap 17 23s 1 S
 R p 1926 1929 - O Sa>=1 23s 0 -
 R p 1927 o - Ap 9 23s 1 S
@@ -1349,8 +1349,9 @@ R p 1938 o - Mar 26 23s 1 S
 R p 1939 o - Ap 15 23s 1 S
 R p 1939 o - N 18 23s 0 -
 R p 1940 o - F 24 23s 1 S
-R p 1940 1941 - O 5 23s 0 -
+R p 1940 o - O 7 23s 0 -
 R p 1941 o - Ap 5 23s 1 S
+R p 1941 o - O 5 23s 0 -
 R p 1942 1945 - Mar Sa>=8 23s 1 S
 R p 1942 o - Ap 25 22s 2 M
 R p 1942 o - Au 15 22s 1 S
@@ -1360,16 +1361,16 @@ R p 1943 1945 - Au Sa>=25 22s 1 S
 R p 1944 1945 - Ap Sa>=21 22s 2 M
 R p 1946 o - Ap Sa>=1 23s 1 S
 R p 1946 o - O Sa>=1 23s 0 -
-R p 1947 1965 - Ap Su>=1 2s 1 S
+R p 1947 1966 - Ap Su>=1 2s 1 S
 R p 1947 1965 - O Su>=1 2s 0 -
-R p 1977 o - Mar 27 0s 1 S
-R p 1977 o - S 25 0s 0 -
-R p 1978 1979 - Ap Su>=1 0s 1 S
-R p 1978 o - O 1 0s 0 -
-R p 1979 1982 - S lastSu 1s 0 -
-R p 1980 o - Mar lastSu 0s 1 S
-R p 1981 1982 - Mar lastSu 1s 1 S
-R p 1983 o - Mar lastSu 2s 1 S
+R p 1976 o - S lastSu 1 0 -
+R p 1977 o - Mar lastSu 0s 1 S
+R p 1977 o - S lastSu 0s 0 -
+R p 1978 1980 - Ap Su>=1 1s 1 S
+R p 1978 o - O 1 1s 0 -
+R p 1979 1980 - S lastSu 1s 0 -
+R p 1981 1986 - Mar lastSu 0s 1 S
+R p 1981 1985 - S lastSu 0s 0 -
 R z 1932 o - May 21 0s 1 S
 R z 1932 1939 - O Su>=1 0s 0 -
 R z 1933 1939 - Ap Su>=2 0s 1 S
@@ -1728,7 +1729,7 @@ R Y 1972 2006 - O lastSu 2 0 S
 R Y 1987 2006 - Ap Su>=1 2 1 D
 R Yu 1965 o - Ap lastSu 0 2 DD
 R Yu 1965 o - O lastSu 2 0 S
-R m 1931 o - May 1 23 1 D
+R m 1931 o - Ap 30 0 1 D
 R m 1931 o - O 1 0 0 S
 R m 1939 o - F 5 0 1 D
 R m 1939 o - Jun 25 0 0 S
@@ -2022,9 +2023,9 @@ R y 2002 2004 - Ap Su>=1 0 0 -
 R y 2002 2003 - S Su>=1 0 1 -
 R y 2004 2009 - O Su>=15 0 1 -
 R y 2005 2009 - Mar Su>=8 0 0 -
-R y 2010 ma - O Su>=1 0 1 -
+R y 2010 2024 - O Su>=1 0 1 -
 R y 2010 2012 - Ap Su>=8 0 0 -
-R y 2013 ma - Mar Su>=22 0 0 -
+R y 2013 2024 - Mar Su>=22 0 0 -
 R PE 1938 o - Ja 1 0 1 -
 R PE 1938 o - Ap 1 0 0 -
 R PE 1938 1939 - S lastSu 0 1 -
@@ -2096,15 +2097,15 @@ Z Africa/Algiers 0:12:

[gcc r15-8004] libstdc++: Optimize basic_format_parse_context::check_dynamic_spec

2025-03-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:256060380c30e2d8ced63c2f04a0856d46b77343

commit r15-8004-g256060380c30e2d8ced63c2f04a0856d46b77343
Author: Jonathan Wakely 
Date:   Sat Mar 8 12:07:40 2025 +

libstdc++: Optimize basic_format_parse_context::check_dynamic_spec

This change makes the check_dynamic_spec precondition checks slightly
faster to compile, and avoids those checks entirely for the common cases
of calling check_dynamic_spec_integral or check_dynamic_spec_string.

Instead of checking for unique types by keeping counts in an array and
looping over that array, we can just keep a sum of how many valid types
are present, and check that it equals the total number of types in the
pack.

The diagnostic is slightly worse now, because there's only a single
"invalid template argument types" string that appears in the output,
where previously we had either "non-unique template argument type" or
"disallowed template argument type", depending on the failure mode.
Given that most users will never use this function directly, and
probably won't use invalid types anyway, the inferior diagnostic seems
acceptable.

libstdc++-v3/ChangeLog:

* include/std/format (basic_format_parse_context::__once): New
variable template.
(basic_format_parse_context::__valid_types_for_check_dynamic_spec):
New function template for checking argument types.
(basic_format_parse_context::__check_dynamic_spec): New function
template to implement the common check_dynamic_spec logic.
(basic_format_parse_context::check_dynamic_spec_integral): Call
__check_dynamic_spec instead of check_dynamic_spec.
(basic_format_parse_context::check_dynamic_spec_string):
Likewise. Use _CharT instead of char_type consistently.
(basic_format_parse_context::check_dynamic_spec): Use
__valid_types_for_check_dynamic_spec for precondition checks and
call __check_dynamic_spec for checking the arg id.
* testsuite/std/format/parse_ctx_neg.cc: Adjust expected errors.

Reviewed-by: Tomasz Kamiński 

Diff:
---
 libstdc++-v3/include/std/format| 110 +++--
 libstdc++-v3/testsuite/std/format/parse_ctx_neg.cc |   6 +-
 2 files changed, 62 insertions(+), 54 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 6cfc84cd01b7..bc26599b9f97 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -294,55 +294,73 @@ namespace __format
 #if __cpp_lib_format >= 202305L
   template
constexpr void
-   check_dynamic_spec(size_t __id) noexcept;
+   check_dynamic_spec(size_t __id) noexcept
+   {
+ static_assert(__valid_types_for_check_dynamic_spec<_Ts...>(),
+   "template arguments for check_dynamic_spec(id) "
+   "must be unique and must be one of the allowed types");
+ if consteval {
+   __check_dynamic_spec<_Ts...>(__id);
+ }
+   }
 
   constexpr void
   check_dynamic_spec_integral(size_t __id) noexcept
   {
-   check_dynamic_spec(__id);
+   if consteval {
+ __check_dynamic_spec(__id);
+   }
   }
 
   constexpr void
   check_dynamic_spec_string(size_t __id) noexcept
   {
-   check_dynamic_spec>(__id);
+   if consteval {
+ __check_dynamic_spec>(__id);
+   }
   }
 
 private:
-  // Check the Mandates: condition for check_dynamic_spec(n)
+  // True if _Tp occurs exactly once in _Ts.
+  template
+   static constexpr bool __once = (is_same_v<_Tp, _Ts> + ...) == 1;
+
   template
-   static consteval bool
-   __check_dynamic_spec_types()
+   consteval bool
+   __valid_types_for_check_dynamic_spec()
{
- if constexpr (sizeof...(_Ts))
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4142. check_dynamic_spec should require at least one type
+ if constexpr (sizeof...(_Ts) == 0)
+   return false;
+ else
{
- int __counts[] = {
-   (is_same_v + ...),
-   (is_same_v<_CharT, _Ts> + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v + ...),
-   (is_same_v, _Ts> + ...),
-   (is_same_v + ...)
- };
- int __sum = 0;
- for (int __c : __counts)
-   {
- __sum += __c;
- if (__c > 1)
-   __invalid_dynamic_spec("non-unique template argument type");
-   }
- if (__sum != sizeof...(_Ts))
- 

[gcc r15-8007] libstdc++: Use new header in

2025-03-12 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:d8a3944b440777d2d6fb4a9f456189a0dc439ec8

commit r15-8007-gd8a3944b440777d2d6fb4a9f456189a0dc439ec8
Author: Jonathan Wakely 
Date:   Wed Mar 12 17:43:08 2025 +

libstdc++: Use new  header in 

In r15-5832-g91f4550e1700b7 std::monostate was moved to its own header,
which means that  no longer needs to include all of .

libstdc++-v3/ChangeLog:

* include/std/format: Include  instead of
.

Diff:
---
 libstdc++-v3/include/std/format | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index bc26599b9f97..f52645a3ac75 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -51,7 +51,7 @@
 #include 
 #include 
 #include 
-#include // monostate (TODO: move to bits/utility.h?)
+#include 
 #include   // input_range, range_reference_t
 #include   // subrange
 #include  // ranges::copy


[gcc r15-7981] builtins: Fix up strspn/strcspn folding [PR119219]

2025-03-12 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:da967f0ff324053304b350fdb18384607a346ebd

commit r15-7981-gda967f0ff324053304b350fdb18384607a346ebd
Author: Jakub Jelinek 
Date:   Wed Mar 12 08:27:17 2025 +0100

builtins: Fix up strspn/strcspn folding [PR119219]

The PR119204 r15-7955 fix caused some regressions.
The problem is that the fold_builtin* APIs document that expr is
either a CALL_EXPR of the call or NULL, so using TREE_TYPE (expr)
can crash e.g. during constexpr evaluation etc.

As can be seen in the surrounding patch, for the neighbouring builtins
(both modf and strpbrk) fold_builtin_2 passes down type, which is the
result type, TREE_TYPE (TREE_TYPE (fndecl)) and those builtins use it
to build the return value, while strspn was always building size_type_node
and strcspn had this change from that to TREE_TYPE (expr).
The patch passes type to these two and uses it there as well.

The patch keeps passing expr because it is used in the
check_nul_terminated_array calls done for both strspn and strcspn,
those calls clearly can deal with NULL expr but prefer if it is non-NULL
for some warning.

2025-03-12  Jakub Jelinek  

PR middle-end/119204
PR middle-end/119219
* builtins.cc (fold_builtin_2): Pass type as another argument
to fold_builtin_strspn and fold_builtin_strcspn.
(fold_builtin_strspn): Add type argument, use it instead of
size_type_node.
(fold_builtin_strcspn): Add type argument, use it instead of
TREE_TYPE (expr).

Diff:
---
 gcc/builtins.cc | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 02556e6615ad..956d3cc4d350 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -176,8 +176,8 @@ static tree fold_builtin_iseqsig (location_t, tree, tree);
 static tree fold_builtin_varargs (location_t, tree, tree*, int);
 
 static tree fold_builtin_strpbrk (location_t, tree, tree, tree, tree);
-static tree fold_builtin_strspn (location_t, tree, tree, tree);
-static tree fold_builtin_strcspn (location_t, tree, tree, tree);
+static tree fold_builtin_strspn (location_t, tree, tree, tree, tree);
+static tree fold_builtin_strcspn (location_t, tree, tree, tree, tree);
 
 static rtx expand_builtin_object_size (tree);
 static rtx expand_builtin_memory_chk (tree, rtx, machine_mode,
@@ -10800,10 +10800,10 @@ fold_builtin_2 (location_t loc, tree expr, tree 
fndecl, tree arg0, tree arg1)
   return fold_builtin_modf (loc, arg0, arg1, type);
 
 case BUILT_IN_STRSPN:
-  return fold_builtin_strspn (loc, expr, arg0, arg1);
+  return fold_builtin_strspn (loc, expr, arg0, arg1, type);
 
 case BUILT_IN_STRCSPN:
-  return fold_builtin_strcspn (loc, expr, arg0, arg1);
+  return fold_builtin_strcspn (loc, expr, arg0, arg1, type);
 
 case BUILT_IN_STRPBRK:
   return fold_builtin_strpbrk (loc, expr, arg0, arg1, type);
@@ -11304,7 +11304,7 @@ fold_builtin_strpbrk (location_t loc, tree, tree s1, 
tree s2, tree type)
form of the builtin function call.  */
 
 static tree
-fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2)
+fold_builtin_strspn (location_t loc, tree expr, tree s1, tree s2, tree type)
 {
   if (!validate_arg (s1, POINTER_TYPE)
   || !validate_arg (s2, POINTER_TYPE))
@@ -11320,8 +11320,7 @@ fold_builtin_strspn (location_t loc, tree expr, tree 
s1, tree s2)
   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
 /* Evaluate and ignore both arguments in case either one has
side-effects.  */
-return omit_two_operands_loc (loc, size_type_node, size_zero_node,
- s1, s2);
+return omit_two_operands_loc (loc, type, size_zero_node, s1, s2);
   return NULL_TREE;
 }
 
@@ -11344,7 +11343,7 @@ fold_builtin_strspn (location_t loc, tree expr, tree 
s1, tree s2)
form of the builtin function call.  */
 
 static tree
-fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2)
+fold_builtin_strcspn (location_t loc, tree expr, tree s1, tree s2, tree type)
 {
   if (!validate_arg (s1, POINTER_TYPE)
   || !validate_arg (s2, POINTER_TYPE))
@@ -11360,8 +11359,7 @@ fold_builtin_strcspn (location_t loc, tree expr, tree 
s1, tree s2)
 {
   /* Evaluate and ignore argument s2 in case it has
 side-effects.  */
-  return omit_one_operand_loc (loc, TREE_TYPE (expr),
-  size_zero_node, s2);
+  return omit_one_operand_loc (loc, type, size_zero_node, s2);
 }
 
   /* If the second argument is "", return __builtin_strlen(s1).  */
@@ -11375,7 +11373,7 @@ fold_builtin_strcspn (location_t loc, tree expr, tree 
s1, tree s2)
   if (!fn)
return NULL_TREE;
 
-  return fold_convert_loc (loc, TREE_TYPE (expr),
+  return fold_convert_loc (loc, type,
   build_call_expr_loc (loc, fn, 1, s1));
 }
   return N

[gcc r15-7987] testsuite: Add testcase for already fixed PR [PR119226]

2025-03-12 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:bb83e83cada180cce650539ab6042aa57fed1caf

commit r15-7987-gbb83e83cada180cce650539ab6042aa57fed1caf
Author: Jakub Jelinek 
Date:   Wed Mar 12 10:48:31 2025 +0100

testsuite: Add testcase for already fixed PR [PR119226]

This was fixed in PR119219 r15-7981 commit.

2025-03-12  Jakub Jelinek  

PR middle-end/119226
* gcc.c-torture/compile/pr119226.c: New test.

Diff:
---
 gcc/testsuite/gcc.c-torture/compile/pr119226.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/testsuite/gcc.c-torture/compile/pr119226.c 
b/gcc/testsuite/gcc.c-torture/compile/pr119226.c
new file mode 100644
index ..8eb98578e008
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr119226.c
@@ -0,0 +1,12 @@
+/* PR middle-end/119226 */
+
+char a[64];
+void bar (void);
+
+void
+foo (int x)
+{
+  char *b = a + __builtin_strcspn (a, x ? "" : "ab");
+  if (b[0])
+bar ();
+}


[gcc r15-8010] libstdc++: Implement P3137R3 views::to_input for C++26

2025-03-12 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:cfb20f17bd17e1cd98ccd8a4517ff3e925cf731c

commit r15-8010-gcfb20f17bd17e1cd98ccd8a4517ff3e925cf731c
Author: Patrick Palka 
Date:   Wed Mar 12 16:09:42 2025 -0400

libstdc++: Implement P3137R3 views::to_input for C++26

libstdc++-v3/ChangeLog:

* include/bits/version.def (ranges_to_input): Define.
* include/bits/version.h: Regenerate.
* include/std/ranges (ranges::to_input_view): Define for C++26.
(views::__detail::__can_to_input): Likewise.
(views::_ToInput, views::to_input): Likewise.
* testsuite/std/ranges/adaptors/to_input/1.cc: New test.

Reviewed-by: Tomasz Kamiński 
Reviewed-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/bits/version.def  |   8 +
 libstdc++-v3/include/bits/version.h|  10 ++
 libstdc++-v3/include/std/ranges| 170 +
 .../testsuite/std/ranges/adaptors/to_input/1.cc|  59 +++
 4 files changed, 247 insertions(+)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 56638759539b..1468c0491b71 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1911,6 +1911,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = ranges_to_input;
+  values = {
+v = 202502;
+cxxmin = 26;
+  };
+};
+
 ftms = {
   name = to_string;
   values = {
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 29e1535298cb..f7c9849893da 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2120,6 +2120,16 @@
 #endif /* !defined(__cpp_lib_text_encoding) && 
defined(__glibcxx_want_text_encoding) */
 #undef __glibcxx_want_text_encoding
 
+#if !defined(__cpp_lib_ranges_to_input)
+# if (__cplusplus >  202302L)
+#  define __glibcxx_ranges_to_input 202502L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_to_input)
+#   define __cpp_lib_ranges_to_input 202502L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_ranges_to_input) && 
defined(__glibcxx_want_ranges_to_input) */
+#undef __glibcxx_want_ranges_to_input
+
 #if !defined(__cpp_lib_to_string)
 # if (__cplusplus >  202302L) && _GLIBCXX_HOSTED && (__glibcxx_to_chars)
 #  define __glibcxx_to_string 202306L
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index e21f5284b46d..c2a2d6f4e05e 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -69,6 +69,7 @@
 #define __glibcxx_want_ranges_slide
 #define __glibcxx_want_ranges_stride
 #define __glibcxx_want_ranges_to_container
+#define __glibcxx_want_ranges_to_input
 #define __glibcxx_want_ranges_zip
 #include 
 
@@ -10390,6 +10391,175 @@ namespace ranges
 } // namespace ranges
 #endif // __cpp_lib_ranges_cache_latest
 
+#if __cpp_lib_ranges_to_input // C++ >= 26
+namespace ranges
+{
+  template
+requires view<_Vp>
+  class to_input_view : public view_interface>
+  {
+_Vp _M_base = _Vp();
+
+template
+class _Iterator;
+
+  public:
+to_input_view() requires default_initializable<_Vp> = default;
+
+constexpr explicit
+to_input_view(_Vp __base)
+: _M_base(std::move(__base))
+{ }
+
+constexpr _Vp
+base() const & requires copy_constructible<_Vp>
+{ return _M_base; }
+
+constexpr _Vp
+base() &&
+{ return std::move(_M_base); }
+
+constexpr auto
+begin() requires (!__detail::__simple_view<_Vp>)
+{ return _Iterator(ranges::begin(_M_base)); }
+
+constexpr auto
+begin() const requires range
+{ return _Iterator(ranges::begin(_M_base)); }
+
+constexpr auto
+end() requires (!__detail::__simple_view<_Vp>)
+{ return ranges::end(_M_base); }
+
+constexpr auto
+end() const requires range
+{ return ranges::end(_M_base); }
+
+constexpr auto
+size() requires sized_range<_Vp>
+{ return ranges::size(_M_base); }
+
+constexpr auto
+size() const requires sized_range
+{ return ranges::size(_M_base); }
+  };
+
+  template
+to_input_view(_Range&&) -> to_input_view>;
+
+  template
+requires view<_Vp>
+  template
+  class to_input_view<_Vp>::_Iterator
+  {
+using _Base = __maybe_const_t<_Const, _Vp>;
+
+iterator_t<_Base> _M_current = iterator_t<_Base>();
+
+constexpr explicit
+_Iterator(iterator_t<_Base> __current)
+: _M_current(std::move(__current))
+{ }
+
+friend to_input_view;
+friend _Iterator;
+
+  public:
+using difference_type = range_difference_t<_Base>;
+using value_type = range_value_t<_Base>;
+using iterator_concept = input_iterator_tag;
+
+_Iterator() requires default_initializable> = default;
+
+_Iterator(_Iterator&&) = default;
+_Iterator& operator=(_Iterator&&) = default;
+
+constexpr
+_Iterator(_Iterator __i)
+  requires _Const && convertible_to, iterator_t<_Base>>
+: _M_current(std::move(__i._M_c

[gcc r15-8018] Allow to build libgccjit with a soname bound to the GCC major version

2025-03-12 Thread Matthias Klose via Gcc-cvs
https://gcc.gnu.org/g:f1baee38ffe044ab0a7ecbacad965bbeafae7fc4

commit r15-8018-gf1baee38ffe044ab0a7ecbacad965bbeafae7fc4
Author: Matthias Klose 
Date:   Thu Mar 13 07:22:02 2025 +0100

Allow to build libgccjit with a soname bound to the GCC major version

When configuring GCC with --program-suffix=-$(BASE_VERSION) to allow
installation multiple GCC versions in parallel, the executable of the
driver (gcc-$(BASE_VERSION)) gets recorded in the libgccjit.so.0
library.  Assuming, that you only install the libgccjit.so.0 library
from the newest GCC, you have a libgccjit installed, which always calls
back to the newest installed version of GCC.  I'm not saying that the
ABI is changing, but I'd like to see the libgccjit calling out to the
corresponding compiler, and therefore installing a libgccjit with a
soname that matches the GCC major version.

The downside is having to rebuild packages built against libgccjit with
each major GCC version, but looking at the reverse dependencies, at
least for package builds, only emacs is using libgccjit.

My plan to use this feature is to build a libgccjit0 using the default
GCC (e.g. gcc-14), and a libgccjit15, when building a newer GCC. When
changing the GCC default to 15, building a libgccjit0 from gcc-15, and a
libgccjit14 from gcc-14.

When configuring without --enable-versioned-jit, the behavior is unchanged.

2025-03-13  Matthias Klose  

gcc/
* configure.ac: Add option --enable-versioned-jit.
* configure: Regenerate.
* Makefile.in: Move from jit/Make-lang.in, setting value from
configure.ac.
* doc/install.texi: Document option --enable-versioned-jit.

gcc/jit/
* Make-lang.in (LIBGCCJIT_VERSION_NUM): Move to ../Makefile.in.

Diff:
---
 gcc/Makefile.in  |  1 +
 gcc/configure| 24 ++--
 gcc/configure.ac | 15 +++
 gcc/doc/install.texi |  4 
 gcc/jit/Make-lang.in |  2 +-
 5 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5477aea882ab..9ca389a9c619 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1218,6 +1218,7 @@ LANG_CONFIGUREFRAGS  = @all_lang_configurefrags@
 LANG_MAKEFRAGS = @all_lang_makefrags@
 
 # Used by gcc/jit/Make-lang.in
+LIBGCCJIT_VERSION_NUM = @libgccjit_version@
 LD_VERSION_SCRIPT_OPTION = @ld_version_script_option@
 LD_SONAME_OPTION = @ld_soname_option@
 @ENABLE_DARWIN_AT_RPATH_TRUE@DARWIN_RPATH = @rpath
diff --git a/gcc/configure b/gcc/configure
index 86a5c75a146b..a34ae586d908 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -636,6 +636,7 @@ CET_HOST_FLAGS
 LD_PICFLAG
 PICFLAG
 enable_default_pie
+libgccjit_version
 enable_host_bind_now
 LIBGDIAGNOSTICS
 enable_libgdiagnostics
@@ -1059,6 +1060,7 @@ enable_libquadmath_support
 with_linker_hash_style
 with_diagnostics_color
 with_diagnostics_urls
+enable_versioned_jit
 enable_default_pie
 enable_cet
 enable_s390_excess_float_precision
@@ -1834,6 +1836,7 @@ Optional Features:
   --enable-host-bind-now  link host code as BIND_NOW
   --disable-libquadmath-support
   disable libquadmath support for Fortran
+  --enable-versioned-jit  enable versioned libgccjit build
   --enable-default-pieenable Position Independent Executable as default
   --enable-cetenable Intel CET in host libraries [default=auto]
   --enable-s390-excess-float-precision
@@ -21477,7 +21480,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 21480 "configure"
+#line 21483 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -21583,7 +21586,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 21586 "configure"
+#line 21589 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -34428,6 +34431,23 @@ cat > gcc-driver-name.h < gcc-driver-name.h <

[gcc r15-8019] Remove extra argument from subst macro

2025-03-12 Thread Matthias Klose via Gcc-cvs
https://gcc.gnu.org/g:6fe63cc1958d15c28916dc0324da254cd843d8a3

commit r15-8019-g6fe63cc1958d15c28916dc0324da254cd843d8a3
Author: Matthias Klose 
Date:   Thu Mar 13 07:26:04 2025 +0100

Remove extra argument from subst macro

2025-03-13  Matthias Klose  

* config-ml.in (multi-do): Remove extra argument from subst macro.

Diff:
---
 config-ml.in | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/config-ml.in b/config-ml.in
index 645cac822fdc..7934a1ddf4bd 100644
--- a/config-ml.in
+++ b/config-ml.in
@@ -517,8 +517,7 @@ multi-do:
libsuffix_=`$${compiler} $${flags} --print-multi-os-directory`; 
\
if (cd ../$${dir}/$${lib}; $(MAKE) $(subst \
-B$(build_tooldir)/lib/, \
-   -B$(build_tooldir)/lib/$${libsuffix_}/ \
-   -B$(build_tooldir)/lib/, \
+   -B$(build_tooldir)/lib/$${libsuffix_}/, \
$(FLAGS_TO_PASS)) \
CFLAGS="$(CFLAGS) $${flags}" \
CCASFLAGS="$(CCASFLAGS) $${flags}" \


[gcc r15-8017] LoongArch: Don't use C++17 feature [PR119238]

2025-03-12 Thread Xi Ruoyao via Gcc-cvs
https://gcc.gnu.org/g:4e6967aba1aaa9dfc362ce59b3d9358a6a15603c

commit r15-8017-g4e6967aba1aaa9dfc362ce59b3d9358a6a15603c
Author: Xi Ruoyao 
Date:   Wed Mar 12 21:02:38 2025 +0800

LoongArch: Don't use C++17 feature [PR119238]

Structured binding is a C++17 feature but the GCC code base is in C++14.

gcc/ChangeLog:

PR target/119238
* config/loongarch/simd.md (dot_prod):
Stop using structured binding.

Diff:
---
 gcc/config/loongarch/simd.md | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index 8f7e912982eb..dd17cd13fc52 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -809,18 +809,20 @@
(any_extend (const_int 0))]
   ""
 {
-  auto [op0, op1, op2, op3] = operands;
+  rtx *op = operands;
 
-  if (op3 == CONST0_RTX (mode))
+  if (op[3] == CONST0_RTX (mode))
 emit_insn (
-  gen__vmulwev__ (op0, op1, op2));
+  gen__vmulwev__ (op[0], op[1],
+ op[2]));
   else
 emit_insn (
-  gen__vmaddwev__ (op0, op3, op1,
-  op2));
+  gen__vmaddwev__ (op[0], op[3],
+  op[1], op[2]));
 
   emit_insn (
-gen__vmaddwod__ (op0, op0, op1, op2));
+gen__vmaddwod__ (op[0], op[0],
+op[1], op[2]));
   DONE;
 })


[gcc r15-8016] analyzer: support RAW_DATA_CST [PR117262]

2025-03-12 Thread David Malcolm via Gcc-cvs
https://gcc.gnu.org/g:8015a72ae496401e05942f4d33c94aa45174f841

commit r15-8016-g8015a72ae496401e05942f4d33c94aa45174f841
Author: David Malcolm 
Date:   Wed Mar 12 20:51:06 2025 -0400

analyzer: support RAW_DATA_CST [PR117262]

gcc/analyzer/ChangeLog:
PR analyzer/117262
* region-model-manager.cc
(region_model_manager::get_or_create_constant_svalue): Use
NULL_TREE for the types of constant_svalue for RAW_DATA_CST.
(region_model_manager::maybe_fold_sub_svalue): Generalize
STRING_CST logic to also handle RAW_DATA_CST.
(region_model_manager::maybe_get_char_from_cst): New.
(region_model_manager::maybe_get_char_from_raw_data_cst): New.
* region-model-manager.h
(region_model_manager::maybe_get_char_from_cst): New decl.
(region_model_manager::maybe_get_char_from_raw_data_cst): New decl.
* region-model.cc (region_model::get_rvalue_1): Handle
RAW_DATA_CST.
* store.cc (get_subregion_within_ctor_for_ctor_pair): New.
(binding_map::apply_ctor_pair_to_child_region): Call
get_subregion_within_ctor_for_ctor_pair so that we handle
RAW_DATA_CST.

gcc/testsuite/ChangeLog:
PR analyzer/117262
* c-c++-common/analyzer/raw-data-cst-pr117262-1.c: New test.
* c-c++-common/analyzer/raw-data-cst-pr117262-2.c: New test.

Signed-off-by: David Malcolm 

Diff:
---
 gcc/analyzer/region-model-manager.cc   | 53 --
 gcc/analyzer/region-model-manager.h|  4 ++
 gcc/analyzer/region-model.cc   |  1 +
 gcc/analyzer/store.cc  | 35 +-
 .../analyzer/raw-data-cst-pr117262-1.c | 17 +++
 .../analyzer/raw-data-cst-pr117262-2.c | 36 +++
 6 files changed, 140 insertions(+), 6 deletions(-)

diff --git a/gcc/analyzer/region-model-manager.cc 
b/gcc/analyzer/region-model-manager.cc
index 1fcf46aa619e..dfce420065d4 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -242,7 +242,12 @@ region_model_manager::get_or_create_constant_svalue (tree 
type, tree cst_expr)
 const svalue *
 region_model_manager::get_or_create_constant_svalue (tree cst_expr)
 {
-  return get_or_create_constant_svalue (TREE_TYPE (cst_expr), cst_expr);
+  tree type = TREE_TYPE (cst_expr);
+  if (TREE_CODE (cst_expr) == RAW_DATA_CST)
+/* The type of a RAW_DATA_CST is the type of each element, rather than
+   that of the constant as a whole, so use NULL_TREE for simplicity.  */
+type = NULL_TREE;
+  return get_or_create_constant_svalue (type, cst_expr);
 }
 
 /* Return the svalue * for a constant_svalue for the INTEGER_CST
@@ -972,9 +977,10 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
}
 }
 
-  /* Handle getting individual chars from a STRING_CST.  */
+  /* Handle getting individual chars from a STRING_CST or RAW_DATA_CST.  */
   if (tree cst = parent_svalue->maybe_get_constant ())
-if (TREE_CODE (cst) == STRING_CST)
+if (TREE_CODE (cst) == STRING_CST
+   || TREE_CODE (cst) == RAW_DATA_CST)
   {
/* If we have a concrete 1-byte access within the parent region... */
byte_range subregion_bytes (0, 0);
@@ -982,13 +988,13 @@ region_model_manager::maybe_fold_sub_svalue (tree type,
&& subregion_bytes.m_size_in_bytes == 1
&& type)
  {
-   /* ...then attempt to get that char from the STRING_CST.  */
+   /* ...then attempt to get that char from the constant.  */
HOST_WIDE_INT hwi_start_byte
  = subregion_bytes.m_start_byte_offset.to_shwi ();
tree cst_idx
  = build_int_cst_type (size_type_node, hwi_start_byte);
if (const svalue *char_sval
-   = maybe_get_char_from_string_cst (cst, cst_idx))
+ = maybe_get_char_from_cst (cst, cst_idx))
  return get_or_create_cast (type, char_sval);
  }
   }
@@ -1505,6 +1511,24 @@ get_or_create_const_fn_result_svalue (tree type,
   return const_fn_result_sval;
 }
 
+/* Given DATA_CST (a STRING_CST or RAW_DATA_CST) and BYTE_OFFSET_CST a 
constant,
+   attempt to get the character at that offset, returning either
+   the svalue for the character constant, or NULL if unsuccessful.  */
+
+const svalue *
+region_model_manager::maybe_get_char_from_cst (tree data_cst,
+  tree byte_offset_cst)
+{
+  switch (TREE_CODE (data_cst))
+{
+default: gcc_unreachable ();
+case STRING_CST:
+  return maybe_get_char_from_string_cst (data_cst, byte_offset_cst);
+case RAW_DATA_CST:
+  return maybe_get_char_from_raw_data_cst (data_cst, byte_offset_cst);
+}
+}
+
 /* Get a tree for the size of STRING_CST, or NULL_TREE.
Note that this may be larg

[gcc r15-8009] c++: Look through capture proxy from outer lambda instead of erroring out [PR110584]

2025-03-12 Thread Simon Martin via Gcc-cvs
https://gcc.gnu.org/g:90e53ecdbfcc482ad3d0090658427de6d44a5d49

commit r15-8009-g90e53ecdbfcc482ad3d0090658427de6d44a5d49
Author: Simon Martin 
Date:   Wed Mar 12 20:15:39 2025 +0100

c++: Look through capture proxy from outer lambda instead of erroring out 
[PR110584]

We've been rejecting this valid code since r8-4571:

=== cut here ===
void foo (float);
int main () {
  constexpr float x = 0;
  (void) [&] () {
foo (x);
(void) [] () {
  foo (x);
};
  };
}
=== cut here ===

The problem is that when processing X in the inner lambda,
process_outer_var_ref errors out even though it does find the constant
capture from the enclosing lambda.

This patch makes sure that process_outer_var_ref properly looks through
normal capture proxies, if any.

PR c++/110584

gcc/cp/ChangeLog:

* cp-tree.h (strip_normal_capture_proxy): Declare.
* lambda.cc (strip_normal_capture_proxy): New function to look
through normal capture proxies.
(build_capture_proxy): Use it.
* semantics.cc (process_outer_var_ref): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/lambda/lambda-nested10.C: New test.

Diff:
---
 gcc/cp/cp-tree.h   |  1 +
 gcc/cp/lambda.cc   | 14 ++-
 gcc/cp/semantics.cc|  8 ++--
 .../g++.dg/cpp0x/lambda/lambda-nested10.C  | 46 ++
 4 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a839ad6d28ac..07500fa2b21a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8114,6 +8114,7 @@ extern void insert_capture_proxy  (tree);
 extern void insert_pending_capture_proxies (void);
 extern bool is_capture_proxy   (tree);
 extern bool is_normal_capture_proxy (tree);
+extern tree strip_normal_capture_proxy (tree);
 extern bool is_constant_capture_proxy   (tree);
 extern void register_capture_members   (tree);
 extern tree lambda_expr_this_capture(tree, int);
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index da075b988059..ed70bb0ba8e0 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -295,6 +295,17 @@ is_normal_capture_proxy (tree decl)
  && DECL_CAPTURED_VARIABLE (decl));
 }
 
+/* If DECL is a normal capture proxy, return the variable it captures.
+   Otherwise, just return DECL.  */
+
+tree
+strip_normal_capture_proxy (tree decl)
+{
+  while (is_normal_capture_proxy (decl))
+decl = DECL_CAPTURED_VARIABLE (decl);
+  return decl;
+}
+
 /* Returns true iff DECL is a capture proxy for a normal capture
of a constant variable.  */
 
@@ -469,8 +480,7 @@ build_capture_proxy (tree member, tree init)
   STRIP_NOPS (init);
 
   gcc_assert (VAR_P (init) || TREE_CODE (init) == PARM_DECL);
-  while (is_normal_capture_proxy (init))
-   init = DECL_CAPTURED_VARIABLE (init);
+  init = strip_normal_capture_proxy (init);
   retrofit_lang_decl (var);
   DECL_CAPTURED_VARIABLE (var) = init;
 }
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 7c7d3e3c4326..6e10893262dd 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -4528,6 +4528,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t 
complain, bool odr_use)
   tree lambda_stack = NULL_TREE;
   tree lambda_expr = NULL_TREE;
   tree initializer = convert_from_reference (decl);
+  tree var = strip_normal_capture_proxy (decl);
 
   /* Mark it as used now even if the use is ill-formed.  */
   if (!mark_used (decl, complain))
@@ -4539,9 +4540,6 @@ process_outer_var_ref (tree decl, tsubst_flags_t 
complain, bool odr_use)
   if (containing_function && LAMBDA_FUNCTION_P (containing_function))
 {
   /* Check whether we've already built a proxy.  */
-  tree var = decl;
-  while (is_normal_capture_proxy (var))
-   var = DECL_CAPTURED_VARIABLE (var);
   tree d = retrieve_local_specialization (var);
 
   if (d && d != decl && is_capture_proxy (d))
@@ -4601,8 +4599,8 @@ process_outer_var_ref (tree decl, tsubst_flags_t 
complain, bool odr_use)
   /* Only an odr-use of an outer automatic variable causes an
  error, and a constant variable can decay to a prvalue
  constant without odr-use.  So don't complain yet.  */
-  else if (!odr_use && decl_constant_var_p (decl))
-return decl;
+  else if (!odr_use && decl_constant_var_p (var))
+return var;
   else if (lambda_expr)
 {
   if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested10.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested10.C
new file mode 100644
index ..aced567c153b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nested10.C
@@ -0,0 +1,46 @@
+// PR c++/110584
+// { dg-do "run" { target c++11 } }
+

[gcc r15-8013] c++/modules: Better handle no-linkage decls in unnamed namespaces [PR118799]

2025-03-12 Thread Nathaniel Shead via Gcc-cvs
https://gcc.gnu.org/g:2eb3d7454ee578335b7719aadfb9e37a8456f1f1

commit r15-8013-g2eb3d7454ee578335b7719aadfb9e37a8456f1f1
Author: Nathaniel Shead 
Date:   Sun Feb 9 00:37:48 2025 +1100

c++/modules: Better handle no-linkage decls in unnamed namespaces [PR118799]

There are two issues with no-linkage decls (e.g. explicit type aliases)
in unnamed namespaces that this patch fixes.

Firstly, we don't currently handle exporting no-linkage decls in unnamed
namespaces.  This should be ill-formed in [module.export], since having
an exported declaration within a namespace-definition makes the
namespace definition exported (p2), but an unnamed namespace has
internal linkage thus violating p3.

Secondly, by the standard it appears to be possible to emit unnamed
namespaces from named modules in certain scenarios, for instance when
they contain a type alias (which is not itself an entity).  This patch
makes the adjustments needed to ensure we don't error in this scenario.

PR c++/118799

gcc/cp/ChangeLog:

* module.cc (depset::hash::is_tu_local_entity): Only types,
functions, variables, and template (specialisations) can be
TU-local.  Explicit type aliases are TU-local iff the type they
refer to are.
(module_state::write_namespaces): Allow unnamed namespaces in
named modules.
(check_module_decl_linkage): Error for all exported declarations
in an unnamed namespace.

gcc/testsuite/ChangeLog:

* g++.dg/modules/export-6.C: Adjust error message, add check for
no-linkage decls in namespace.
* g++.dg/modules/internal-4_b.C: Allow exposing a namespace with
internal linkage.  Type aliases are not entities and so never
exposures.
* g++.dg/modules/using-30_a.C: New test.
* g++.dg/modules/using-30_b.C: New test.
* g++.dg/modules/using-30_c.C: New test.

Signed-off-by: Nathaniel Shead 
Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/module.cc| 58 ++---
 gcc/testsuite/g++.dg/modules/export-6.C | 33 +---
 gcc/testsuite/g++.dg/modules/internal-4_b.C | 19 ++
 gcc/testsuite/g++.dg/modules/using-30_a.C   | 13 +++
 gcc/testsuite/g++.dg/modules/using-30_b.C   | 10 +
 gcc/testsuite/g++.dg/modules/using-30_c.C   | 17 +
 6 files changed, 116 insertions(+), 34 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index a17d8433e34c..0d9e50bba7f9 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13478,16 +13478,35 @@ bool
 depset::hash::is_tu_local_entity (tree decl, bool explain/*=false*/)
 {
   gcc_checking_assert (DECL_P (decl));
+  location_t loc = DECL_SOURCE_LOCATION (decl);
+  tree type = TREE_TYPE (decl);
+
+  /* Only types, functions, variables, and template (specialisations)
+ can be TU-local.  */
+  if (TREE_CODE (decl) != TYPE_DECL
+  && TREE_CODE (decl) != FUNCTION_DECL
+  && TREE_CODE (decl) != VAR_DECL
+  && TREE_CODE (decl) != TEMPLATE_DECL)
+return false;
 
-  /* An explicit type alias is not an entity, and so is never TU-local.
- Neither are the built-in declarations of 'int' and such.  */
+  /* An explicit type alias is not an entity; we don't want to stream
+ such aliases if they refer to TU-local entities, so propagate this
+ from the original type. The built-in declarations of 'int' and such
+ are never TU-local.  */
   if (TREE_CODE (decl) == TYPE_DECL
   && !DECL_SELF_REFERENCE_P (decl)
   && !DECL_IMPLICIT_TYPEDEF_P (decl))
-return false;
-
-  location_t loc = DECL_SOURCE_LOCATION (decl);
-  tree type = TREE_TYPE (decl);
+{
+  tree orig = DECL_ORIGINAL_TYPE (decl);
+  if (orig && TYPE_NAME (orig))
+   {
+ if (explain)
+   inform (loc, "%qD is an alias of TU-local type %qT", decl, orig);
+ return is_tu_local_entity (TYPE_NAME (orig), explain);
+   }
+  else
+   return false;
+}
 
   /* Check specializations first for slightly better explanations.  */
   int use_tpl = -1;
@@ -16623,8 +16642,9 @@ module_state::write_namespaces (elf_out *to, vec spaces,
   depset *b = spaces[ix];
   tree ns = b->get_entity ();
 
+  /* This could be an anonymous namespace even for a named module,
+since we can still emit no-linkage decls.  */
   gcc_checking_assert (TREE_CODE (ns) == NAMESPACE_DECL);
-  gcc_checking_assert (TREE_PUBLIC (ns) || header_module_p ());
 
   unsigned flags = 0;
   if (TREE_PUBLIC (ns))
@@ -20579,13 +20599,25 @@ check_module_decl_linkage (tree decl)
   /* An internal-linkage declaration cannot be generally be exported.
  But it's OK to export any declaration from a header unit, including
  internal linkage declarations.  */
-  if (!header_module_p ()
-  && DECL_M

[gcc r15-8011] c++: ICE with aligned member and trivial assign op [PR117512]

2025-03-12 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:3dd7b598065ea0280fc65ce656c575c5142fa4fc

commit r15-8011-g3dd7b598065ea0280fc65ce656c575c5142fa4fc
Author: Marek Polacek 
Date:   Wed Mar 12 14:49:53 2025 -0400

c++: ICE with aligned member and trivial assign op [PR117512]

build_over_call has:

  t = build2 (MODIFY_EXPR, void_type_node,
  build2 (MEM_REF, array_type, arg0, alias_set),
  build2 (MEM_REF, array_type, arg, alias_set));
  val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);

which creates an expression that can look like:

  d = MEM  [(struct A *)&TARGET_EXPR  [(struct A *)(const struct A &) &e],
  TARGET_EXPR 

that is, a COMPOUND_EXPR where a TARGET_EXPR is used twice, and its
address is taken in the left-hand side operand, so it can't be elided.
But set_target_expr_eliding simply recurses on the second operand of
a COMPOUND_EXPR and marks the TARGET_EXPR as eliding.  This then causes
a crash.

cp_build_indirect_ref_1 should not be changing the value category.
While *&TARGET_EXPR is an lvalue, folding it into TARGET_EXPR would
render is a prvalue of class type.

PR c++/117512

gcc/cp/ChangeLog:

* typeck.cc (cp_build_indirect_ref_1): Only do the *&e -> e
folding if the result would be an lvalue.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alignas23.C: New test.
* g++.dg/ext/align3.C: New test.
* g++.dg/ext/align4.C: New test.
* g++.dg/ext/align5.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/typeck.cc   |  6 +-
 gcc/testsuite/g++.dg/cpp0x/alignas23.C | 15 +++
 gcc/testsuite/g++.dg/ext/align3.C  | 14 ++
 gcc/testsuite/g++.dg/ext/align4.C  | 14 ++
 gcc/testsuite/g++.dg/ext/align5.C  | 18 ++
 5 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index fe8aceddffa1..4b382b95de17 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3870,7 +3870,11 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, 
ref_operator errorstring,
  return error_mark_node;
}
   else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
-  && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0
+  && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))
+  /* Don't let this change the value category.  '*&TARGET_EXPR'
+ is an lvalue, but folding it into 'TARGET_EXPR' would turn
+ it into a prvalue of class type.  */
+  && lvalue_p (TREE_OPERAND (pointer, 0)))
/* The POINTER was something like `&x'.  We simplify `*&x' to
   `x'.  */
return TREE_OPERAND (pointer, 0);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas23.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas23.C
new file mode 100644
index ..3c218a3542c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas23.C
@@ -0,0 +1,15 @@
+// PR c++/117512
+// { dg-do compile { target c++11 } }
+
+struct A {
+  alignas(sizeof (long long)) int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align3.C 
b/gcc/testsuite/g++.dg/ext/align3.C
new file mode 100644
index ..6a20dfc57b13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align3.C
@@ -0,0 +1,14 @@
+// PR c++/117512
+
+struct A {
+  __attribute__((aligned)) int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align4.C 
b/gcc/testsuite/g++.dg/ext/align4.C
new file mode 100644
index ..b0d83e302373
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align4.C
@@ -0,0 +1,14 @@
+// PR c++/117512
+
+struct __attribute__((aligned (2 * sizeof (int A {
+  int b;
+  ~A ();
+};
+A foo (int);
+
+void
+bar ()
+{
+  A e = { 0 };
+  A d = foo (0) = e;
+}
diff --git a/gcc/testsuite/g++.dg/ext/align5.C 
b/gcc/testsuite/g++.dg/ext/align5.C
new file mode 100644
index ..7e8212743520
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/align5.C
@@ -0,0 +1,18 @@
+// PR c++/117512
+// { dg-do run }
+
+struct A {
+  __attribute__((aligned(2 * sizeof (int int i;
+  ~A() {}
+};
+
+A foo () { A a = { 19 }; return a; }
+
+int
+main ()
+{
+  A a = { 42 };
+  A r = foo () = a;
+  if (r.i != 42)
+__builtin_abort ();
+}