[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement fonction

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:e8d300a99c04a71f4d418cb2461363f29c30b602

commit e8d300a99c04a71f4d418cb2461363f29c30b602
Author: Mikael Morin 
Date:   Fri Feb 14 09:34:02 2025 +0100

Déplacement fonction

Diff:
---
 gcc/fortran/trans-array.cc | 53 ++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  | 41 ++-
 3 files changed, 47 insertions(+), 48 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 3bfe41c64013..8981a420c97a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2225,6 +2225,44 @@ gfc_conv_shift_descriptor_subarray (stmtblock_t *block, 
tree desc,
 }
 
 
+void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+  tree lbound[GFC_MAX_DIMENSIONS],
+  tree ubound[GFC_MAX_DIMENSIONS])
+{
+  tree size = gfc_index_one_node;
+  tree offset = gfc_index_zero_node;
+  for (int n = 0; n < rank; n++)
+{
+  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, tmp,
+gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ tmp);
+  gfc_conv_descriptor_lbound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ gfc_index_one_node);
+  size = gfc_evaluate_now (size, block);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type,
+   offset, size);
+  offset = gfc_evaluate_now (offset, block);
+  tmp = gfc_conv_array_extent_dim (lbound[n], ubound[n], nullptr);
+  size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, size, tmp);
+}
+
+  gfc_conv_descriptor_offset_set (block, desc,
+ offset);
+}
+
+
+
+
 int
 gfc_descriptor_rank (tree descriptor)
 {
@@ -8392,15 +8430,12 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 start at zero, but when allocating it, the standard expects
 the array to start at one.  Therefore fix the upper bound to be
 (desc.ubound - desc.lbound) + 1.  */
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-gfc_conv_descriptor_ubound_get (
-  expr3_desc, gfc_rank_cst[n]),
-gfc_conv_descriptor_lbound_get (
-  expr3_desc, gfc_rank_cst[n]));
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type, tmp,
-gfc_index_one_node);
+ tmp = gfc_conv_array_extent_dim (
+ gfc_conv_descriptor_lbound_get (expr3_desc,
+ gfc_rank_cst[n]),
+ gfc_conv_descriptor_ubound_get (expr3_desc,
+ gfc_rank_cst[n]),
+ nullptr);
  se.expr = gfc_evaluate_now (tmp, pblock);
}
  else
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 836a177da014..f37f09c21cff 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -237,6 +237,7 @@ void gfc_conv_shift_descriptor (stmtblock_t*, tree, const 
gfc_array_ref &);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, int);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree);
 void gfc_conv_shift_descriptor_subarray (stmtblock_t*, tree, gfc_expr *, 
gfc_expr *);
+void gfc_conv_shift_descriptor (stmtblock_t *, tree, int, tree *, tree *);
 
 /* Add pre-loop scalarization code for intrinsic functions which require
special handling.  */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 016ac2ee944c..13cb7f9fd8fa 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5207,43 +5207,6 @@ gfc_apply_interface_mapping (gfc_interface_mapping * 
mapping,
 }
 
 
-static void
-shift_descriptor (stmtblock_t *block, tree desc, int rank,
- tree lbound[GFC_MAX_DIMENSIONS],
- tree ubound[GFC_MAX_DIMENSIONS])
-
-{
-  tree size = gfc_index_one_node;
-  tree offset = gfc_index_zero_node;
-  for (int n = 0; n < rank; n++)
-{
-  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gf

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation shift_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:cbb7977daa02944d45d569246e354b5c24fab722

commit cbb7977daa02944d45d569246e354b5c24fab722
Author: Mikael Morin 
Date:   Thu Feb 13 21:03:54 2025 +0100

Factorisation shift_descriptor

Diff:
---
 gcc/fortran/trans-expr.cc | 76 ---
 1 file changed, 39 insertions(+), 37 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6ed87fc63a9b..016ac2ee944c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5207,6 +5207,43 @@ gfc_apply_interface_mapping (gfc_interface_mapping * 
mapping,
 }
 
 
+static void
+shift_descriptor (stmtblock_t *block, tree desc, int rank,
+ tree lbound[GFC_MAX_DIMENSIONS],
+ tree ubound[GFC_MAX_DIMENSIONS])
+
+{
+  tree size = gfc_index_one_node;
+  tree offset = gfc_index_zero_node;
+  for (int n = 0; n < rank; n++)
+{
+  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, tmp,
+gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ tmp);
+  gfc_conv_descriptor_lbound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ gfc_index_one_node);
+  size = gfc_evaluate_now (size, block);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type,
+   offset, size);
+  offset = gfc_evaluate_now (offset, block);
+  tmp = gfc_conv_array_extent_dim (lbound[n], ubound[n], nullptr);
+  size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, size, tmp);
+}
+
+  gfc_conv_descriptor_offset_set (block, desc,
+ offset);
+}
+
+
 /* Returns a reference to a temporary array into which a component of
an actual argument derived type array is copied and then returned
after the function call.  */
@@ -5227,7 +5264,6 @@ gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, 
int g77,
   tree tmp_index;
   tree tmp;
   tree base_type;
-  tree size;
   stmtblock_t body;
   int n;
   int dimen;
@@ -5471,42 +5507,8 @@ class_array_fcn:
   /* Determine the offset for pointer formal arguments and set the
  lbounds to one.  */
   if (formal_ptr)
-{
-  size = gfc_index_one_node;
-  offset = gfc_index_zero_node;
-  for (n = 0; n < dimen; n++)
-   {
- tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
-   gfc_rank_cst[n]);
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type, tmp,
-gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&parmse->pre,
- parmse->expr,
- gfc_rank_cst[n],
- tmp);
- gfc_conv_descriptor_lbound_set (&parmse->pre,
- parmse->expr,
- gfc_rank_cst[n],
- gfc_index_one_node);
- size = gfc_evaluate_now (size, &parmse->pre);
- offset = fold_build2_loc (input_location, MINUS_EXPR,
-   gfc_array_index_type,
-   offset, size);
- offset = gfc_evaluate_now (offset, &parmse->pre);
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-rse.loop->to[n], rse.loop->from[n]);
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type,
-tmp, gfc_index_one_node);
- size = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, size, tmp);
-   }
-
-  gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
- offset);
-}
+shift_descriptor (&parmse->pre, parmse->expr, dimen,
+ rse.loop->from, rse.loop->to);
 
   /* We want either the address for the data or the address of the descriptor,
  depending on the mode of passing array arguments.  */


[gcc r15-7529] libstdc++: Fix use of make_pair that used ADL

2025-02-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:d5fb86cbec48af24d3ec56519fdf8b0c4133b801

commit r15-7529-gd5fb86cbec48af24d3ec56519fdf8b0c4133b801
Author: Jonathan Wakely 
Date:   Wed Feb 12 18:30:21 2025 +

libstdc++: Fix use of make_pair that used ADL

_Rb_tree::_M_equal_range calls make_pair unqualified, which means it
uses ADL. As the new testcase shows, this can find something other than
std::make_pair. Rather than just changing it to use a qualified call,
remove the use of make_pair entirely. We don't need to deduce any types
here, we know exactly what type of std::pair we want to construct, so do
that explicitly.

libstdc++-v3/ChangeLog:

* include/bits/stl_tree.h (_Rb_tree::_M_equal_range): Replace
unqualified call to make_pair with explicit construction of
std::pair.
* testsuite/23_containers/set/operations/equal_range_adl.cc:
New test.

Diff:
---
 libstdc++-v3/include/bits/stl_tree.h   | 18 ---
 .../set/operations/equal_range_adl.cc  | 26 ++
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_tree.h 
b/libstdc++-v3/include/bits/stl_tree.h
index 7285676f427f..6b35f99a25a3 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -2633,6 +2633,8 @@ namespace __rb_tree
 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
 equal_range(const _Key& __k)
 {
+  typedef pair _Ret;
+
   _Base_ptr __x = _M_begin();
   _Base_ptr __y = _M_end();
   while (__x)
@@ -2647,12 +2649,11 @@ namespace __rb_tree
  _Base_ptr __yu(__y);
  __y = __x, __x = _S_left(__x);
  __xu = _S_right(__xu);
- return make_pair(iterator(_M_lower_bound(__x, __y, __k)),
-  iterator(_M_upper_bound(__xu, __yu, __k)));
+ return _Ret(iterator(_M_lower_bound(__x, __y, __k)),
+ iterator(_M_upper_bound(__xu, __yu, __k)));
}
}
-  return pair(iterator(__y),
- iterator(__y));
+  return _Ret(iterator(__y), iterator(__y));
 }
 
   template::
 equal_range(const _Key& __k) const
 {
+  typedef pair _Ret;
+
   _Base_ptr __x = _M_begin();
   _Base_ptr __y = _M_end();
   while (__x)
@@ -2678,12 +2681,11 @@ namespace __rb_tree
  _Base_ptr __yu(__y);
  __y = __x, __x = _S_left(__x);
  __xu = _S_right(__xu);
- return make_pair(const_iterator(_M_lower_bound(__x, __y, __k)),
-  const_iterator(_M_upper_bound(__xu, __yu, __k)));
+ return _Ret(const_iterator(_M_lower_bound(__x, __y, __k)),
+ const_iterator(_M_upper_bound(__xu, __yu, __k)));
}
}
-  return pair(const_iterator(__y),
- const_iterator(__y));
+  return _Ret(const_iterator(__y), const_iterator(__y));
 }
 
   template
+
+namespace adl
+{
+#if __cplusplus < 201103L
+  template void make_pair(const T&, const T&) { }
+#else
+  template void make_pair(T&&, T&&) { }
+#endif
+
+  struct X { bool operator<(const X&) const { return false; } };
+}
+
+typedef std::set Set;
+
+void
+test_equal_range(Set& s, const adl::X& x)
+{
+  // _Rb_tree::_M_equal_range was using make_pair unqualified.
+  (void) s.equal_range(x);
+  const Set& cs = s;
+  // Similarly for the const overload.
+  (void) cs.equal_range(x);
+}


[gcc r15-7530] libstdc++: Fix more unqualified uses of make_pair

2025-02-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:06724b6079b5ad983f7d29b39b4cc38cde0f37b3

commit r15-7530-g06724b6079b5ad983f7d29b39b4cc38cde0f37b3
Author: Jonathan Wakely 
Date:   Wed Feb 12 18:33:46 2025 +

libstdc++: Fix more unqualified uses of make_pair

There are some unqualified calls to make_pair in Parallel Mode. Fix
these by just using a qualified call, because it's simpler and I don't
care about this code much.

libstdc++-v3/ChangeLog:

* include/parallel/algobase.h (__mismatch_switch): Qualify calls
to make_pair to avoid ADL.

Diff:
---
 libstdc++-v3/include/parallel/algobase.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/parallel/algobase.h 
b/libstdc++-v3/include/parallel/algobase.h
index a47230c8b937..0f3b979a8f20 100644
--- a/libstdc++-v3/include/parallel/algobase.h
+++ b/libstdc++-v3/include/parallel/algobase.h
@@ -84,7 +84,7 @@ namespace __parallel
 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
 __gnu_parallel::
 __mismatch_selector()).first;
-  return make_pair(__res , __begin2 + (__res - __begin1));
+  return std::make_pair(__res , __begin2 + (__res - __begin1));
 }
   else
 return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
@@ -165,7 +165,7 @@ namespace __parallel
 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
 __gnu_parallel::
 __mismatch_selector()).first;
-  return make_pair(__res , __begin2 + (__res - __begin1));
+  return std::make_pair(__res , __begin2 + (__res - __begin1));
 }
   else
 return _GLIBCXX_STD_A::mismatch(__begin1, __end1,


[gcc r15-7537] c++: add fixed test [PR82794]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:77ba1ab85d3a45005bfff90b2fd262e102e5383a

commit r15-7537-g77ba1ab85d3a45005bfff90b2fd262e102e5383a
Author: Marek Polacek 
Date:   Fri Feb 14 16:04:41 2025 -0500

c++: add fixed test [PR82794]

Fixed by r10-3735.

PR c++/82794

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-pr82794.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp2a/concepts-pr82794.C | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr82794.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82794.C
new file mode 100644
index ..b84e9ec45f6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82794.C
@@ -0,0 +1,8 @@
+// PR c++/82794
+// { dg-do compile { target c++20 } }
+
+template
+concept Foo = true;
+
+template
+using foo = void;


[gcc r15-7536] c++: add fixed test [PR70037]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:9fd4e414830bb84b1cf1a7df4945d26c078729c9

commit r15-7536-g9fd4e414830bb84b1cf1a7df4945d26c078729c9
Author: Marek Polacek 
Date:   Fri Feb 14 15:50:09 2025 -0500

c++: add fixed test [PR70037]

Fixed by r11-735 + r11-2417.

PR c++/70037

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-pr70037.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp2a/concepts-pr70037.C | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr70037.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr70037.C
new file mode 100644
index ..7382764ea01b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr70037.C
@@ -0,0 +1,18 @@
+// PR c++/70037
+// { dg-do compile { target c++20 } }
+
+namespace std {
+  template
+  struct F {
+static constexpr bool value = false;
+  };
+
+  template
+  struct tuple {
+constexpr tuple() requires (F::value)  {}
+explicit constexpr tuple() requires (F::value) && (true) {}
+  };
+}
+
+using std::tuple;
+template struct std::tuple>;


[gcc r15-7538] c++: add fixed test [PR82936]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:dfd1b1abab9d3159e6f43e234ab78638f92d613e

commit r15-7538-gdfd1b1abab9d3159e6f43e234ab78638f92d613e
Author: Marek Polacek 
Date:   Fri Feb 14 16:18:25 2025 -0500

c++: add fixed test [PR82936]

Fixed by r8-6829-gaaec81f10fa314; before that:

Segmentation fault (core dumped)

PR c++/82936

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/vt-82936.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp0x/vt-82936.C | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-82936.C 
b/gcc/testsuite/g++.dg/cpp0x/vt-82936.C
new file mode 100644
index ..3c489686204b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-82936.C
@@ -0,0 +1,18 @@
+// PR c++/82936
+// { dg-do compile { target c++11 } }
+
+int fun(int i)
+{
+return 0;
+}
+template 
+struct outer;
+template 
+struct outer
+{
+template 
+struct callable
+{
+};
+};
+outer::callable f;


[gcc r15-7547] libstdc++: Improve list assumption after constructor [PR118865]

2025-02-14 Thread Andrew Pinski via Gcc-cvs
https://gcc.gnu.org/g:0c3cc57f0e71a7a945fb10c817260dd8a7894e7f

commit r15-7547-g0c3cc57f0e71a7a945fb10c817260dd8a7894e7f
Author: Andrew Pinski 
Date:   Thu Feb 13 14:10:06 2025 -0800

libstdc++: Improve list assumption after constructor [PR118865]

The code example here does:
```
if (begin == end) __builtin_unreachable();
std::list nl(begin, end);

for (auto it = nl.begin(); it != nl.end(); it++)
{
...
}
/* Remove the first element of the list. */
nl.erase(nl.begin());
```

And we get a warning because because we jump threaded the case were we
think the list was empty from the for loop BUT we populated it without
an empty array. So can help the compiler here by adding that after 
initializing
the list with non empty array, that the list will not be empty either.

This is able to remove the -Wfree-nonheap-object warning in the first 
reduced
testcase (with the fix for `begin == end` case added) in the PR 118865; the 
second
reduced testcase has been filed off as PR 118867.

Bootstrapped and tested on x86_64-linux-gnu.

libstdc++-v3/ChangeLog:

PR libstdc++/118865
* include/bits/stl_list.h (_M_initialize_dispatch): Add an
unreachable if the iterator was not empty that the list will
now be not empty.

Signed-off-by: Andrew Pinski 

Diff:
---
 libstdc++-v3/include/bits/stl_list.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_list.h 
b/libstdc++-v3/include/bits/stl_list.h
index be33eeb03d44..f987d8b9d0a3 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -2384,12 +2384,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
_M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
   __false_type)
{
+ bool __notempty = __first != __last;
  for (; __first != __last; ++__first)
 #if __cplusplus >= 201103L
emplace_back(*__first);
 #else
push_back(*__first);
 #endif
+if (__notempty)
+  {
+if (begin() == end())
+  __builtin_unreachable();
+  }
}
 
   // Called by list(n,v,a), and the range constructor when it turns out


[gcc r15-7539] c++: add fixed test [PR86933]

2025-02-14 Thread Patrick Palka via Gcc-cvs
https://gcc.gnu.org/g:80b9c9c844458779556995a5be7c08a8894d0f96

commit r15-7539-g80b9c9c844458779556995a5be7c08a8894d0f96
Author: Patrick Palka 
Date:   Fri Feb 14 16:28:42 2025 -0500

c++: add fixed test [PR86933]

Fixed by the PR118265 fix r15-7339-g26d3424ca5d9f4.

PR c++/86933

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/variadic-nontype1.C: Mention PR number.
* g++.dg/cpp1z/variadic-nontype2.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C |  2 ++
 gcc/testsuite/g++.dg/cpp1z/variadic-nontype2.C | 12 
 2 files changed, 14 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C 
b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
index ad2af623b139..594857a99841 100644
--- a/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype1.C
@@ -1,4 +1,6 @@
+// PR c++/118265
 // { dg-do compile { target c++17 } }
+
 struct Class1
 {
 void apply_bool(bool){}
diff --git a/gcc/testsuite/g++.dg/cpp1z/variadic-nontype2.C 
b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype2.C
new file mode 100644
index ..4c112eaf3ac9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/variadic-nontype2.C
@@ -0,0 +1,12 @@
+// PR c++/86933
+// { dg-do compile { target c++17 } }
+
+template  struct TT;
+template  struct TT {};
+
+struct X {
+int x;
+double y;
+};
+
+TT<&X::x, &X::y> t;


[gcc r15-7544] AVR: target/118878 - Don't ICE on result from paradoxical reg's alloc.

2025-02-14 Thread Georg-Johann Lay via Gcc-cvs
https://gcc.gnu.org/g:1dc4e220ca2272d668ddb3041ccd9e69b968e532

commit r15-7544-g1dc4e220ca2272d668ddb3041ccd9e69b968e532
Author: Georg-Johann Lay 
Date:   Fri Feb 14 18:53:29 2025 +0100

AVR: target/118878 - Don't ICE on result from paradoxical reg's alloc.

After register allocation, paradoxical subregs may become something
like  r20:SI += r22:SI  which doesn't make much sense as assembly code.
Hence avr_out_plus_1() used to ICE on such code.  However, paradoxical
subregs appear to be a common optimization device (instead of proper
mode demotion).

PR target/118878
gcc/
* config/avr/avr.cc (avr_out_plus_1): Don't ICE on result of
paradoxical reg's register allocation.
gcc/testsuite/
* gcc.target/avr/torture/pr118878.c: New test.

Diff:
---
 gcc/config/avr/avr.cc   | 20 ---
 gcc/testsuite/gcc.target/avr/torture/pr118878.c | 78 +
 2 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index bb00e3347206..e358a2e8b8da 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -8782,6 +8782,16 @@ avr_out_plus_1 (rtx insn, rtx *xop, int *plen, rtx_code 
code,
 
   if (REG_P (xop[2]))
 {
+  if (REGNO (xop[0]) != REGNO (xop[2])
+ && reg_overlap_mentioned_p (xop[0], xop[2]))
+   {
+ /* PR118878: Paradoxical SUBREGs may result in overlapping
+registers.  The assumption is that the overlapping part
+is unused garbage.  */
+ gcc_assert (n_bytes <= 4);
+ n_bytes = std::abs ((int) REGNO (xop[0]) - (int) REGNO (xop[2]));
+   }
+
   for (int i = 0; i < n_bytes; i++)
{
  /* We operate byte-wise on the destination.  */
@@ -8796,13 +8806,9 @@ avr_out_plus_1 (rtx insn, rtx *xop, int *plen, rtx_code 
code,
 op, plen, 1);
}
 
-  if (reg_overlap_mentioned_p (xop[0], xop[2]))
-   {
- gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
-
- if (MINUS == code)
-   return;
-   }
+  if (MINUS == code
+ && REGNO (xop[0]) == REGNO (xop[2]))
+   return;
 
   goto saturate;
 }
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr118878.c 
b/gcc/testsuite/gcc.target/avr/torture/pr118878.c
new file mode 100644
index ..d2d8a22fbda7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr118878.c
@@ -0,0 +1,78 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options { -std=c99 } } */
+
+#ifdef __AVR_HAVE_LPMX__
+
+/* From include  */
+
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef uint32_t uint_farptr_t;
+
+#define pgm_read_dword_far(__addr) __ELPM_dword (__addr)
+
+#define __ELPM_dword(addr)\
+  (__extension__({\
+  uint_farptr_t __addr32 = (addr);\
+  uint32_t __result;  \
+  __ELPM__4 (__result, __addr32, uint32_t);   \
+  __result; }))
+
+/* Has no ELPM: Fallback to LPM. */
+#define __ELPM__4(r,a,T) const T *__a = (const T*)(uint16_t) a; __LPM__4(r,__a)
+
+#define __LPM__4(res,addr)  \
+  __asm volatile ("lpm %A0,%a1+" "\n\t" \
+  "lpm %B0,%a1+" "\n\t" \
+  "lpm %C0,%a1+" "\n\t" \
+  "lpm %D0,%a1+" : "=r" (res), "+z" (addr))
+
+#define PROGMEM __attribute__((__progmem__))
+
+#define pgm_get_far_address(var)  \
+  (__extension__({ uint_farptr_t __tmp;   \
+  __asm__ ("ldi%A0, lo8(%1)" "\n\t"   \
+   "ldi%B0, hi8(%1)" "\n\t"   \
+   "ldi%C0, hh8(%1)" "\n\t"   \
+   "clr%D0" : "=d" (__tmp) : "i" (&(var)) ); __tmp; }))
+
+/*/
+
+#define VAL 0x01050711
+
+PROGMEM
+const uint32_t data[] = { VAL, 2 * VAL, 7 * VAL };
+
+uint32_t get_val (uint8_t i)
+{
+  uint32_t v = VAL;
+  if (i == 1) v *= 2;
+  if (i == 2) v *= 7;
+  return v;
+}
+
+__attribute__((noinline,noclone))
+void test (uint8_t i)
+{
+  if (pgm_read_dword_far (pgm_get_far_address (data[0])) != get_val (0))
+__builtin_exit (__LINE__);
+
+  uint_farptr_t pf = pgm_get_far_address (data[0]) + i * sizeof (uint32_t);
+  if (pgm_read_dword_far (pf) != get_val (i))
+__builtin_exit (__LINE__);
+}
+
+int main (void)
+{
+  test (1);
+  test (2);
+  return 0;
+}
+
+#else
+int main (void)
+{
+  return 0;
+}
+#endif


[gcc r15-7542] nvptx: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR86660]

2025-02-14 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:9611ce687904a22da2febbc97acba2ae0f0c3780

commit r15-7542-g9611ce687904a22da2febbc97acba2ae0f0c3780
Author: Thomas Schwinge 
Date:   Tue Feb 11 17:23:28 2025 +0100

nvptx: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR86660]

Subversion r263265 (Git commit 77e0a97acf7b00c1e68e4738fdf275a4cffc2e50)
"[nvptx] Ignore c++ exceptions", originally had set 'UI_TARGET', but as 
part of
Subversion r263287 (Git commit d989dba8ef02c2406b7c9e62b352197dffc6b880)
"[c++] Don't emit exception tables for UI_NONE", then switched to 'UI_NONE'.

I understand the intention of using 'UI_NONE' like this, and it happens to 
work
in a lot of cases, but there are ICEs elsewhere: code paths where we run 
into
'internal compiler error: in get_personality_function, at expr.cc:13512':

13494 /* Extracts the personality function of DECL and returns the 
corresponding
13495libfunc.  */
13496
13497 rtx
13498 get_personality_function (tree decl)
13499 {
13500   tree personality = DECL_FUNCTION_PERSONALITY (decl);
13501   enum eh_personality_kind pk;
13502
13503   pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION 
(decl));
13504   if (pk == eh_personality_none)
13505 return NULL;
13506
13507   if (!personality
13508   && pk == eh_personality_any)
13509 personality = lang_hooks.eh_personality ();
13510
13511   if (pk == eh_personality_lang)
13512 gcc_assert (personality != NULL_TREE);
13513
13514   return XEXP (DECL_RTL (personality), 0);
13515 }

..., where 'lang_hooks.eh_personality ()' ends up calling
'gcc/expr.cc:build_personality_function', and we 'return NULL;' for 
'UI_NONE':

13448 /* Build a decl for a personality function given a language 
prefix.  */
13449
13450 tree
13451 build_personality_function (const char *lang)
13452 {
13453   const char *unwind_and_version;
13454   tree decl, type;
13455   char *name;
13456
13457   switch (targetm_common.except_unwind_info (&global_options))
13458 {
13459 case UI_NONE:
13460   return NULL;
[...]

(Comparing to nvptx' current use of 'UI_NONE', this problem (ICEs mentioned
above) is way more prevalent for GCN.)

The GCC internals documentation indeed states, 'gcc/doc/tm.texi':

@deftypefn {Common Target Hook} {enum unwind_info_type} 
TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *@var{opts})
This hook defines the mechanism that will be used for exception handling
by the target.  If the target has ABI specified unwind tables, the hook
should return @code{UI_TARGET}.  If the target is to use the
@code{setjmp}/@code{longjmp}-based exception handling scheme, the hook
should return @code{UI_SJLJ}.  If the target supports DWARF 2 frame 
unwind
information, the hook should return @code{UI_DWARF2}.

A target may, if exceptions are disabled, choose to return 
@code{UI_NONE}.
This may end up simplifying other parts of target-specific code.  [...]

Here, note: "if exceptions are disabled" (meaning: '-fno-exceptions' etc.) 
may
"return @code{UI_NONE}".  That's what other back ends do with code like:

/* For simplicity elsewhere in this file, indicate that all unwind
   info is disabled if we're not emitting unwind tables.  */
if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables)
  return UI_NONE;
else
  return UI_TARGET;

The corresponding "simplifying other parts of target-specific code"/
"simplicity elsewhere" would then be the early returns from
'TARGET_ASM_UNWIND_EMIT', 'ARM_OUTPUT_FN_UNWIND', etc. for
'TARGET_EXCEPT_UNWIND_INFO != UI_TARGET' (that is, for 'UI_NONE').

From the documentation (and implementation), however, it does *not* follow 
that
if a target doesn't implement support for exception handling, it may just 
set
'UI_NONE' for 'TARGET_EXCEPT_UNWIND_INFO'.

Therefore, switch (back) to 'UI_TARGET', implementing some basic support for
'exception_section': discard (via a PTX comment block) whatever GCC writes 
into
it.

With that, all these 'internal compiler error: in get_personality_function'
test cases turn into PASS, or UNSUPPORTED ('exception handling not 
supported'),
or re-classify into a few other, already known issues.

(In case that use of 'UI_NONE' like originally intended really makes sense, 
and
is preferable over this 'UI_TARGET' solution, then more work will be 
necessary
for implementing the missing parts, where 'UI_NONE' currently isn't 
handled.)

PR target/86660
gcc/
* common/c

[gcc r15-7541] nvptx: Sanity-check 'init_frag' state

2025-02-14 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:79cb26298c76f1360f1aada26863f011c4decc34

commit r15-7541-g79cb26298c76f1360f1aada26863f011c4decc34
Author: Thomas Schwinge 
Date:   Thu Feb 13 00:35:31 2025 +0100

nvptx: Sanity-check 'init_frag' state

The 'init_frag' machinery is used by 'nvptx_assemble_integer' (via
'TARGET_ASM_INTEGER'), 'nvptx_output_skip' (via 'ASM_OUTPUT_SKIP'),
'nvptx_output_ascii' (via 'ASM_OUTPUT_ASCII').  But, it's not obvious that
these are called only when that machinery is active (and in a consistent
state), which it only is in 'nvptx_output_aligned_decl' (via
'ASM_OUTPUT_ALIGNED_DECL_COMMON', or 'ASM_OUTPUT_ALIGNED_DECL_LOCAL'), or in
'nvptx_assemble_undefined_decl' (via 'TARGET_ASM_ASSEMBLE_UNDEFINED_DECL'), 
or
within a region started by 'nvptx_assemble_decl_begin' (via
'nvptx_asm_declare_constant_name' (via 'TARGET_ASM_DECLARE_CONSTANT_NAME'), 
or
via 'nvptx_declare_object_name' (via 'ASM_DECLARE_OBJECT_NAME')) and ended 
by
'nvptx_assemble_decl_end' (via 'TARGET_ASM_DECL_END').

And indeed, in a GCC/nvptx offloading configuration, we then find that
'nvptx_output_skip' (via 'ASM_OUTPUT_SKIP') is getting called in 
inconsistent
'init_frag' state, in 'gcc/varasm.cc', via 'assemble_zeros', from
'output_object_block', to "Move to the object's offset, padding with zeros".
Supposedly, this didn't cause any damage, but we now handle it explicitly.
(..., and the question remains whether such "padding" etc. shouldn't 
actually
be attempted for targets like nvptx.)

gcc/
* config/nvptx/nvptx.cc (init_frag): New 'bool active' member.
(output_init_frag, nvptx_assemble_value, nvptx_assemble_integer)
(nvptx_output_skip, nvptx_assemble_decl_begin)
(nvptx_assemble_decl_end): Sanity-check its state.

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

diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 6f3646192056..96f258c5573d 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -2255,6 +2255,7 @@ static struct
out.  */
   unsigned size;  /* Fragment size to accumulate.  */
   unsigned offset;  /* Offset within current fragment.  */
+  bool active; /* Whether this machinery is active.  */
   bool started;   /* Whether we've output any initializer.  */
 } init_frag;
 
@@ -2265,6 +2266,8 @@ static struct
 static void
 output_init_frag (rtx sym)
 {
+  gcc_checking_assert (init_frag.active);
+
   fprintf (asm_out_file, init_frag.started ? ", " : " = { ");
   unsigned HOST_WIDE_INT val = init_frag.val;
 
@@ -2296,6 +2299,8 @@ output_init_frag (rtx sym)
 static void
 nvptx_assemble_value (unsigned HOST_WIDE_INT val, unsigned size)
 {
+  gcc_checking_assert (init_frag.active);
+
   bool negative_p
 = val & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1));
 
@@ -2328,6 +2333,8 @@ nvptx_assemble_value (unsigned HOST_WIDE_INT val, 
unsigned size)
 static bool
 nvptx_assemble_integer (rtx x, unsigned int size, int ARG_UNUSED (aligned_p))
 {
+  gcc_checking_assert (init_frag.active);
+
   HOST_WIDE_INT val = 0;
 
   switch (GET_CODE (x))
@@ -2370,6 +2377,17 @@ nvptx_assemble_integer (rtx x, unsigned int size, int 
ARG_UNUSED (aligned_p))
 void
 nvptx_output_skip (FILE *, unsigned HOST_WIDE_INT size)
 {
+  gcc_checking_assert (in_section == data_section
+  || in_section == text_section);
+
+  if (!init_frag.active)
+/* We're in the 'data_section' or 'text_section', outside of an
+   initializer context ('init_frag').  There's nothing to do here:
+   in PTX, there's no concept of an assembler's "location counter",
+   "current address", "dot symbol" ('.') that might need padding or
+   aligning.  */
+return;
+
   /* Finish the current fragment, if it's started.  */
   if (init_frag.offset)
 {
@@ -2446,6 +2464,8 @@ nvptx_assemble_decl_begin (FILE *file, const char *name, 
const char *section,
   const_tree type, HOST_WIDE_INT size, unsigned align,
   bool undefined = false)
 {
+  gcc_checking_assert (!init_frag.active);
+
   bool atype = (TREE_CODE (type) == ARRAY_TYPE)
 && (TYPE_DOMAIN (type) == NULL_TREE);
 
@@ -2473,6 +2493,8 @@ nvptx_assemble_decl_begin (FILE *file, const char *name, 
const char *section,
   elt_size |= GET_MODE_SIZE (elt_mode);
   elt_size &= -elt_size; /* Extract LSB set.  */
 
+  init_frag.active = true;
+
   init_frag.size = elt_size;
   /* Avoid undefined shift behavior by using '2'.  */
   init_frag.mask = ((unsigned HOST_WIDE_INT)2
@@ -2504,10 +2526,14 @@ nvptx_assemble_decl_begin (FILE *file, const char 
*name, const char *section,
 static void
 nvptx_assemble_decl_end (void)
 {
+  gcc_checking_assert (init_frag.active);
+
   if (init_frag.offset)
 /* This can happen with a packed struct with trailing array member. 

[gcc r15-7540] nvptx: Clarify 'nvptx_output_skip' case of no or incomplete initializer

2025-02-14 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:09b207bf26b9c79a43e1a346a4493d4b202b4ac5

commit r15-7540-g09b207bf26b9c79a43e1a346a4493d4b202b4ac5
Author: Thomas Schwinge 
Date:   Thu Feb 13 22:58:21 2025 +0100

nvptx: Clarify 'nvptx_output_skip' case of no or incomplete initializer

I was getting confused about 'nvptx_output_skip' in certain cases not doing
anything at all; write down and 'assert' what I found.

gcc/
* config/nvptx/nvptx.cc (nvptx_output_skip): Clarify case of
no or incomplete initializer.

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

diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 060f45318f45..6f3646192056 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -2391,6 +2391,12 @@ nvptx_output_skip (FILE *, unsigned HOST_WIDE_INT size)
   if (size)
nvptx_assemble_value (0, size);
 }
+  else
+/* Otherwise, we don't have to do anything: this skip terminates the
+   initializer; we skip either the full ('!init_frag.started' case) or the
+   remainder ('init_frag.started' case) of the initializer (that is, either
+   no or incomplete initializer).  */
+gcc_checking_assert (size == init_frag.remaining * init_frag.size);
 }
 
 /* Output a string STR with length SIZE.  As in nvptx_output_skip we


[gcc r15-7543] GCN: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282, PR113331]

2025-02-14 Thread Thomas Schwinge via Gcc-cvs
https://gcc.gnu.org/g:2b9bdb2d286e6872f4195ba2e710130cf6b2805d

commit r15-7543-g2b9bdb2d286e6872f4195ba2e710130cf6b2805d
Author: Thomas Schwinge 
Date:   Tue Feb 11 17:23:28 2025 +0100

GCN: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282, PR113331]

In commit 7f1989249e25af6fc0f124452efa24b3796b767a
"[gcn] Set 'UI_NONE' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282]", we've 
copied
the 'UI_NONE' idea from nvptx to GCN.

I understand the intention of using 'UI_NONE' like this, and it happens to 
work
in a lot of cases, but there are ICEs elsewhere: code paths where we run 
into
'internal compiler error: in get_personality_function, at expr.cc:13512':

13494 /* Extracts the personality function of DECL and returns the 
corresponding
13495libfunc.  */
13496
13497 rtx
13498 get_personality_function (tree decl)
13499 {
13500   tree personality = DECL_FUNCTION_PERSONALITY (decl);
13501   enum eh_personality_kind pk;
13502
13503   pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION 
(decl));
13504   if (pk == eh_personality_none)
13505 return NULL;
13506
13507   if (!personality
13508   && pk == eh_personality_any)
13509 personality = lang_hooks.eh_personality ();
13510
13511   if (pk == eh_personality_lang)
13512 gcc_assert (personality != NULL_TREE);
13513
13514   return XEXP (DECL_RTL (personality), 0);
13515 }

..., where 'lang_hooks.eh_personality ()' ends up calling
'gcc/expr.cc:build_personality_function', and we 'return NULL;' for 
'UI_NONE':

13448 /* Build a decl for a personality function given a language 
prefix.  */
13449
13450 tree
13451 build_personality_function (const char *lang)
13452 {
13453   const char *unwind_and_version;
13454   tree decl, type;
13455   char *name;
13456
13457   switch (targetm_common.except_unwind_info (&global_options))
13458 {
13459 case UI_NONE:
13460   return NULL;
[...]

(Comparing to nvptx' current use of 'UI_NONE', this problem (ICEs mentioned
above) is way more prevalent for GCN.)

The GCC internals documentation indeed states, 'gcc/doc/tm.texi':

@deftypefn {Common Target Hook} {enum unwind_info_type} 
TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *@var{opts})
This hook defines the mechanism that will be used for exception handling
by the target.  If the target has ABI specified unwind tables, the hook
should return @code{UI_TARGET}.  If the target is to use the
@code{setjmp}/@code{longjmp}-based exception handling scheme, the hook
should return @code{UI_SJLJ}.  If the target supports DWARF 2 frame 
unwind
information, the hook should return @code{UI_DWARF2}.

A target may, if exceptions are disabled, choose to return 
@code{UI_NONE}.
This may end up simplifying other parts of target-specific code.  [...]

Here, note: "if exceptions are disabled" (meaning: '-fno-exceptions' etc.) 
may
"return @code{UI_NONE}".  That's what other back ends do with code like:

/* For simplicity elsewhere in this file, indicate that all unwind
   info is disabled if we're not emitting unwind tables.  */
if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables)
  return UI_NONE;
else
  return UI_TARGET;

The corresponding "simplifying other parts of target-specific code"/
"simplicity elsewhere" would then be the early returns from
'TARGET_ASM_UNWIND_EMIT', 'ARM_OUTPUT_FN_UNWIND', etc. for
'TARGET_EXCEPT_UNWIND_INFO != UI_TARGET' (that is, for 'UI_NONE').

From the documentation (and implementation), however, it does *not* follow 
that
if a target doesn't implement support for exception handling, it may just 
set
'UI_NONE' for 'TARGET_EXCEPT_UNWIND_INFO'.

Therefore, switch to 'UI_TARGET', allocating a "fake" 'exception_section'.

With that, all these 'internal compiler error: in get_personality_function'
test cases turn into PASS, or UNSUPPORTED ('exception handling not 
supported'),
or re-classify into a few other, already known issues.  And, this change 
also
happens to resolve the class of errors identified in GCC PR113331
"AMDGCN: Compilation failure due to duplicate .LEHB/.LEHE symbols".

(In case that use of 'UI_NONE' like originally intended really makes sense, 
and
is preferable over this 'UI_TARGET' solution, then more work will be 
necessary
for implementing the missing parts, where 'UI_NONE' currently isn't 
handled.)

PR target/94282
PR target/113331
gcc/
* common/config/gcn/gcn-common.cc (gcn_exc

[gcc r15-7546] c++: add fixed test [PR83144]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:8e44f7ecb7b9ad6893f7784b1a303a5463b46cd5

commit r15-7546-g8e44f7ecb7b9ad6893f7784b1a303a5463b46cd5
Author: Marek Polacek 
Date:   Fri Feb 14 17:29:27 2025 -0500

c++: add fixed test [PR83144]

Fixed by r12-4425 and it seemed worth adding.

PR c++/83144

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/constexpr-83144.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp0x/constexpr-83144.C | 21 +
 1 file changed, 21 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-83144.C 
b/gcc/testsuite/g++.dg/cpp0x/constexpr-83144.C
new file mode 100644
index ..858fec13a2c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-83144.C
@@ -0,0 +1,21 @@
+// PR c++/83144
+// { dg-do compile { target c++11 } }
+
+template  class tuple;
+struct _Head_base {
+  int _M_head_impl;
+};
+template  struct _Tuple_impl;
+template 
+struct _Tuple_impl<_Idx, _Head, _Tail...> : _Head_base {};
+template 
+struct tuple<_T1, _T2> : _Tuple_impl<0, _T2> {
+  template  tuple(_U1, _U2);
+};
+template  void get(tuple<_Elements...>);
+template  struct interval_t : tuple {
+  using tuple::tuple;
+  constexpr T last() { get<1>(*this); }
+  auto size() -> decltype(last() - 0);
+};
+int main(int argc, char **) { interval_t{2, argc}; }


[gcc r15-7545] c++: assign the result of force_paren_expr

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:e4c9e1094405612feae410e133025e3267331c2d

commit r15-7545-ge4c9e1094405612feae410e133025e3267331c2d
Author: Marek Polacek 
Date:   Fri Feb 14 17:21:31 2025 -0500

c++: assign the result of force_paren_expr

gcc/cp/ChangeLog:

* pt.cc (tsubst_expr) : Assign the result of
force_paren_expr.

Diff:
---
 gcc/cp/pt.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 5706a3987c34..62d91a2dd159 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21713,7 +21713,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
r = finish_non_static_data_member (member, object, NULL_TREE,
   complain);
if (REF_PARENTHESIZED_P (t))
- force_paren_expr (r);
+ r = force_paren_expr (r);
RETURN (r);
  }
else if (type_dependent_expression_p (object))


[gcc] Created branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users'

2025-02-14 Thread Mikael Morin via Gcc-cvs
The branch 'mikael/heads/refactor_descriptor_v01' was created in namespace 
'refs/users' pointing to:

 a7d30957412c... Déplacement fonction


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Appel méthode shift descriptor dans gfc_trans_pointer_assignment

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ecdc8da68c9d5419d4c0e6ec9b1b3278076cbdf0

commit ecdc8da68c9d5419d4c0e6ec9b1b3278076cbdf0
Author: Mikael Morin 
Date:   Tue Dec 17 22:37:18 2024 +0100

Appel méthode shift descriptor dans gfc_trans_pointer_assignment

Diff:
---
 gcc/fortran/trans-array.cc | 129 +++--
 gcc/fortran/trans-array.h  |   1 +
 gcc/fortran/trans-expr.cc  |  28 +-
 3 files changed, 129 insertions(+), 29 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 2fdd15962e49..cdbff27d82ca 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1151,13 +1151,136 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, 
tree desc,
 }
 
 
+class lb_info
+{
+public:
+  virtual gfc_expr *lower_bound (int dim) const = 0;
+};
+
+
+class unset_lb : public lb_info
+{
+public:
+  virtual gfc_expr *lower_bound (int) const { return nullptr; }
+};
+
+
+class defined_lb : public lb_info
+{
+  int rank;
+  gfc_expr * const * lower_bounds;
+
+public:
+  defined_lb (int arg_rank, gfc_expr * const 
arg_lower_bounds[GFC_MAX_DIMENSIONS])
+: rank(arg_rank), lower_bounds(arg_lower_bounds) { }
+  virtual gfc_expr *lower_bound (int dim) const { return lower_bounds[dim]; }
+};
+
+
 static void
-conv_shift_descriptor (stmtblock_t* block, tree desc, int rank)
+conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+  const lb_info &info)
 {
   /* Apply a shift of the lbound when supplied.  */
   for (int dim = 0; dim < rank; ++dim)
-gfc_conv_shift_descriptor_lbound (block, desc, dim,
- gfc_index_one_node);
+{
+  gfc_expr *lb_expr = info.lower_bound(dim);
+
+  tree lower_bound;
+  if (lb_expr == nullptr)
+   lower_bound = gfc_index_one_node;
+  else
+   {
+ gfc_se lb_se;
+
+ gfc_init_se (&lb_se, nullptr);
+ gfc_conv_expr (&lb_se, lb_expr);
+
+ gfc_add_block_to_block (block, &lb_se.pre);
+ tree lb_var = gfc_create_var (TREE_TYPE (lb_se.expr), "lower_bound");
+ gfc_add_modify (block, lb_var, lb_se.expr);
+ gfc_add_block_to_block (block, &lb_se.post);
+
+ lower_bound = lb_var;
+   }
+
+  gfc_conv_shift_descriptor_lbound (block, desc, dim, lower_bound);
+}
+}
+
+
+static void
+conv_shift_descriptor (stmtblock_t* block, tree desc, int rank)
+{
+  conv_shift_descriptor (block, desc, rank, unset_lb ());
+}
+
+
+static void
+conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+  gfc_expr * const lower_bounds[GFC_MAX_DIMENSIONS])
+{
+  conv_shift_descriptor (block, desc, rank, defined_lb (rank, lower_bounds));
+}
+
+
+static void
+conv_shift_descriptor (stmtblock_t *block, tree desc,
+  const gfc_array_spec &as)
+{
+  conv_shift_descriptor (block, desc, as.rank, as.lower);
+}
+
+
+static void
+set_type (array_type &type, array_type value)
+{
+  gcc_assert (type == AS_UNKNOWN || type == value);
+  type = value;
+}
+
+
+static void
+array_ref_to_array_spec (const gfc_array_ref &ref, gfc_array_spec &spec)
+{
+  spec.rank = ref.dimen;
+  spec.corank = ref.codimen;
+
+  spec.type = AS_UNKNOWN;
+  spec.cotype = AS_ASSUMED_SIZE;
+
+  for (int dim = 0; dim < spec.rank + spec.corank; dim++)
+switch (ref.dimen_type[dim])
+  {
+  case DIMEN_ELEMENT:
+   spec.upper[dim] = ref.start[dim];
+   set_type (spec.type, AS_EXPLICIT);
+   break;
+
+  case DIMEN_RANGE:
+   spec.lower[dim] = ref.start[dim];
+   spec.upper[dim] = ref.end[dim];
+   if (spec.upper[dim] == nullptr)
+ set_type (spec.type, AS_DEFERRED);
+   else
+ set_type (spec.type, AS_EXPLICIT);
+   break;
+
+  default:
+   break;
+  }
+}
+
+
+void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree desc,
+  const gfc_array_ref &ar)
+{
+  gfc_array_spec as;
+
+  array_ref_to_array_spec (ar, as);
+
+  conv_shift_descriptor (block, desc, as);
 }
 
 
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 17e3d08fdba0..3b05a2eb197a 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -214,6 +214,7 @@ tree gfc_get_cfi_dim_sm (tree, tree);
 
 /* Shift lower bound of descriptor, updating ubound and offset.  */
 void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree);
+void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &);
 
 /* Add pre-loop scalarization code for intrinsic functions which require
special handling.  */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index e8b229d853e3..1de4a73974d6 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -11180,32 +11180,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, 
gfc_expr * expr2)
}
}
  else
-   {
- /* Bounds remapping.  Just shift the lower bounds.  */
-
- 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Utilisation de la méthode de nullification pour nullifier un pointeur

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b68e4d2ef22d8fe82d628a320c6577d1d0a946dd

commit b68e4d2ef22d8fe82d628a320c6577d1d0a946dd
Author: Mikael Morin 
Date:   Wed Dec 18 19:04:41 2024 +0100

Utilisation de la méthode de nullification pour nullifier un pointeur

Correction régression modifiable_p

Correction dump

Ajout assertion

Correction assertion même type

Diff:
---
 gcc/fortran/trans-array.cc  | 96 ++---
 gcc/fortran/trans-array.h   |  1 +
 gcc/fortran/trans-expr.cc   | 35 -
 gcc/testsuite/gfortran.dg/class_allocate_14.f90 |  2 +-
 4 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index cdbff27d82ca..4c237b561aa6 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -545,9 +545,9 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree 
desc,
 
 
 static int
-get_type_info (const gfc_typespec &ts)
+get_type_info (const bt &type)
 {
-  switch (ts.type)
+  switch (type)
 {
 case BT_INTEGER:
 case BT_LOGICAL:
@@ -558,7 +558,7 @@ get_type_info (const gfc_typespec &ts)
 case BT_CLASS:
 case BT_VOID:
 case BT_UNSIGNED:
-  return ts.type;
+  return type;
 
 case BT_PROCEDURE:
 case BT_ASSUMED:
@@ -613,11 +613,34 @@ get_size_info (gfc_typespec &ts)
 }
 
 
-class init_info
+class modify_info
 {
 public:
+  virtual bool is_initialization () const { return false; }
   virtual bool initialize_data () const { return false; }
   virtual tree get_data_value () const { return NULL_TREE; }
+};
+
+class nullification : public modify_info
+{
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return null_pointer_node; }
+  /*
+private:
+  gfc_typespec &ts;
+
+public:
+  null_init(gfc_typespec &arg_ts) : ts(arg_ts) { }
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return null_pointer_node; }
+  virtual gfc_typespec *get_type () const { return &ts; }
+  */
+};
+
+class init_info : public modify_info
+{
+public:
+  virtual bool is_initialization () const { return true; }
   virtual gfc_typespec *get_type () const { return nullptr; }
 };
 
@@ -638,13 +661,13 @@ public:
   }
 };
 
-class nullification : public init_info
+class null_init : public init_info
 {
 private:
   gfc_typespec &ts;
 
 public:
-  nullification(gfc_typespec &arg_ts) : ts(arg_ts) { }
+  null_init(gfc_typespec &arg_ts) : ts(arg_ts) { }
   virtual bool initialize_data () const { return true; }
   virtual tree get_data_value () const { return null_pointer_node; }
   virtual gfc_typespec *get_type () const { return &ts; }
@@ -700,13 +723,12 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &,
   CONSTRUCTOR_APPEND_ELT (v, rank_field, rank_val);
 }
 
-  if (type_info->type != BT_CLASS)
-{
-  tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
-  tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
- get_type_info (*type_info));
-  CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
-}
+  tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
+  tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
+ get_type_info (type_info->type == BT_CLASS
+? BT_DERIVED
+: type_info->type));
+  CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
 
   return build_constructor (type, v);
 }
@@ -715,8 +737,8 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &,
 /* Build a null array descriptor constructor.  */
 
 vec *
-get_descriptor_init (tree type, gfc_typespec &ts, int rank,
-const symbol_attribute &attr, const init_info &init)
+get_descriptor_init (tree type, gfc_typespec *ts, int rank,
+const symbol_attribute *attr, const modify_info &init)
 {
   vec *v = nullptr;
 
@@ -732,11 +754,15 @@ get_descriptor_init (tree type, gfc_typespec &ts, int 
rank,
   CONSTRUCTOR_APPEND_ELT (v, data_field, data_value);
 }
 
-  tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
-  tree dtype_value = build_dtype (ts, rank, attr, init);
-  CONSTRUCTOR_APPEND_ELT (v, dtype_field, dtype_value);
+  if (init.is_initialization ())
+{
+  tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
+  tree dtype_value = build_dtype (*ts, rank, *attr,
+ static_cast (init));
+  CONSTRUCTOR_APPEND_ELT (v, dtype_field, dtype_value);
+}
 
-  if (flag_coarray == GFC_FCOARRAY_LIB && attr.codimension)
+  if (flag_coarray == GFC_FCOARRAY_LIB && attr->codimension)
 {
   /* Declare the variable static so its array descriptor stays present

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:db8dddefb7b3659f1307058b98421fc9edf2e6de

commit db8dddefb7b3659f1307058b98421fc9edf2e6de
Author: Mikael Morin 
Date:   Wed Dec 11 16:03:10 2024 +0100

Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class

essai suppression

Suppression fonction inutilisée

Sauvegarde compilation OK

Correction régression

Sauvegarde correction null_actual_6

Commentage fonction inutilisée

Correction bornes descripteur null

Diff:
---
 gcc/fortran/trans-array.cc | 339 +++--
 gcc/fortran/trans-array.h  |   4 +-
 gcc/fortran/trans-expr.cc  |  87 ++--
 3 files changed, 373 insertions(+), 57 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index d15576adde10..0370d10d9ebd 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -592,10 +592,10 @@ get_size_info (gfc_typespec &ts)
if (POINTER_TYPE_P (type))
  type = TREE_TYPE (type);
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
-   tree elt_type = TREE_TYPE (type);
+   tree char_type = TREE_TYPE (type);
tree len = ts.u.cl->backend_decl;
return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
-   size_in_bytes (elt_type),
+   size_in_bytes (char_type),
fold_convert (size_type_node, len));
   }
 
@@ -613,8 +613,61 @@ get_size_info (gfc_typespec &ts)
 }
 
 
+class init_info
+{
+public:
+  virtual bool initialize_data () const { return false; }
+  virtual tree get_data_value () const { return NULL_TREE; }
+  virtual gfc_typespec *get_type () const { return nullptr; }
+};
+
+
+class default_init : public init_info
+{
+private:
+  const symbol_attribute &attr; 
+
+public:
+  default_init (const symbol_attribute &arg_attr) : attr(arg_attr) { }
+  virtual bool initialize_data () const { return !attr.pointer; }
+  virtual tree get_data_value () const {
+if (!initialize_data ())
+  return NULL_TREE;
+
+return null_pointer_node;
+  }
+};
+
+class nullification : public init_info
+{
+private:
+  gfc_typespec &ts;
+
+public:
+  nullification(gfc_typespec &arg_ts) : ts(arg_ts) { }
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return null_pointer_node; }
+  virtual gfc_typespec *get_type () const { return &ts; }
+};
+
+class scalar_value : public init_info
+{
+private:
+  gfc_typespec &ts;
+  tree value;
+
+public:
+  scalar_value(gfc_typespec &arg_ts, tree arg_value)
+: ts(arg_ts), value(arg_value) { }
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return value; }
+  virtual gfc_typespec *get_type () const { return &ts; }
+};
+
+
 static tree
-build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
+build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &,
+const init_info &init)
 {
   vec *v = nullptr;
 
@@ -622,11 +675,17 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &)
 
   tree fields = TYPE_FIELDS (type);
 
-  if (ts.type != BT_CLASS)
+  gfc_typespec *type_info = init.get_type ();
+  if (type_info == nullptr)
+type_info = &ts;
+
+  if (!(type_info->type == BT_CLASS
+   || (type_info->type == BT_CHARACTER
+   && type_info->deferred)))
 {
   tree elem_len_field = gfc_advance_chain (fields, GFC_DTYPE_ELEM_LEN);
   tree elem_len_val = fold_convert (TREE_TYPE (elem_len_field),
-   get_size_info (ts));
+   get_size_info (*type_info));
   CONSTRUCTOR_APPEND_ELT (v, elem_len_field, elem_len_val);
 }
 
@@ -641,11 +700,11 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &)
   CONSTRUCTOR_APPEND_ELT (v, rank_field, rank_val);
 }
 
-  if (ts.type != BT_CLASS)
+  if (type_info->type != BT_CLASS)
 {
   tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
   tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
- get_type_info (ts));
+ get_type_info (*type_info));
   CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
 }
 
@@ -656,8 +715,8 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &)
 /* Build a null array descriptor constructor.  */
 
 vec *
-get_default_descriptor_init (tree type, gfc_typespec &ts, int rank,
-const symbol_attribute &attr)
+get_descriptor_init (tree type, gfc_typespec &ts, int rank,
+const symbol_attribute &attr, const init_info &init)
 {
   vec *v = nullptr;
 
@@ -666,15 +725,15 @@ get_default_descriptor_init (tree type, gfc_typespec &ts, 
int rank,
   tree fields = TYPE_FIELDS (type);
 
   /* Don't init pointers by default.  */
-  if 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Extraction fonction fcncall_realloc_result

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ed6fee22d9c29ebee21ce323726fb14cfb8d6ed1

commit ed6fee22d9c29ebee21ce323726fb14cfb8d6ed1
Author: Mikael Morin 
Date:   Thu Jan 9 21:38:39 2025 +0100

Extraction fonction fcncall_realloc_result

Correction variable inutilisée

Correction régression coarray dummy_3

Correction régression dummy_3

Diff:
---
 gcc/fortran/trans-array.cc | 64 ++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  | 52 +++--
 3 files changed, 80 insertions(+), 37 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 898930634ad1..7d43a8c000d3 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1451,6 +1451,70 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, tree src,
 }
 
 
+class conditional_lb
+{
+  tree cond;
+public:
+  conditional_lb (tree arg_cond)
+: cond (arg_cond) { }
+
+  tree lower_bound (tree src, int n) const {
+tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[n]);
+lbound = fold_build3_loc (input_location, COND_EXPR,
+ gfc_array_index_type, cond,
+ gfc_index_one_node, lbound);
+return lbound;
+  }
+};
+
+
+static void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src,
+  int rank, const conditional_lb &lb)
+{
+  tree tmp = gfc_conv_descriptor_data_get (src);
+  gfc_conv_descriptor_data_set (block, dest, tmp);
+
+  tree offset = gfc_index_zero_node;
+  for (int n = 0 ; n < rank; n++)
+{
+  tree lbound;
+
+  lbound = lb.lower_bound (dest, n);
+  lbound = gfc_evaluate_now (lbound, block);
+
+  tmp = gfc_conv_descriptor_ubound_get (src, gfc_rank_cst[n]);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, tmp, lbound);
+  gfc_conv_descriptor_lbound_set (block, dest,
+ gfc_rank_cst[n], lbound);
+  gfc_conv_descriptor_ubound_set (block, dest,
+ gfc_rank_cst[n], tmp);
+
+  /* Set stride and accumulate the offset.  */
+  tmp = gfc_conv_descriptor_stride_get (src, gfc_rank_cst[n]);
+  gfc_conv_descriptor_stride_set (block, dest,
+ gfc_rank_cst[n], tmp);
+  tmp = fold_build2_loc (input_location, MULT_EXPR,
+gfc_array_index_type, lbound, tmp);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type, offset, tmp);
+  offset = gfc_evaluate_now (offset, block);
+}
+
+  gfc_conv_descriptor_offset_set (block, dest, offset);
+}
+
+
+void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree dest, tree src,
+  int rank, tree zero_cond)
+{
+  gfc_conv_shift_descriptor (block, dest, src, rank,
+conditional_lb (zero_cond));
+}
+
+
 static bool
 keep_descriptor_lower_bound (gfc_expr *e)
 {
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 8df55c2c00a5..571322ae11ff 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -216,6 +216,7 @@ tree gfc_get_cfi_dim_sm (tree, tree);
 /* Shift lower bound of descriptor, updating ubound and offset.  */
 void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &);
+void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree);
 
 /* Add pre-loop scalarization code for intrinsic functions which require
special handling.  */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index c50b1e05cdbd..77e8a55af457 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -832,6 +832,9 @@ gfc_get_vptr_from_expr (tree expr)
 int
 gfc_descriptor_rank (tree descriptor)
 {
+  if (TREE_TYPE (descriptor) != NULL_TREE)
+return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
+
   tree dim = gfc_get_descriptor_dimension (descriptor);
   tree dim_type = TREE_TYPE (dim);
   gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
@@ -916,8 +919,17 @@ gfc_class_array_data_assign (stmtblock_t *block, tree 
lhs_desc, tree rhs_desc,
 type = TREE_TYPE (tmp);
   else
 {
-  gcc_assert (TREE_TYPE (tmp) == TREE_TYPE (tmp2));
-  type = TREE_TYPE (tmp);
+  int corank = GFC_TYPE_ARRAY_CORANK (TREE_TYPE (lhs_desc));
+  int corank2 = GFC_TYPE_ARRAY_CORANK (TREE_TYPE (rhs_desc));
+  if (corank > 0 && corank2 == 0)
+   type = TREE_TYPE (tmp2);
+  else if (corank2 > 0 && corank == 0)
+   type = TREE_TYPE (tmp);
+  else
+   {
+ gcc_assert (TREE_TYPE (tmp) == TREE_TYPE (tmp2));
+ type = TREE_TYPE (tmp);
+   }
 }
 
   tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
@@ -11595,7 +11607,6 @@ fcncall_realloc_result (g

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Creation méthode initialisation descripteur

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:3c45ca6ee9cb09354b7ede90cf410c13adeec82c

commit 3c45ca6ee9cb09354b7ede90cf410c13adeec82c
Author: Mikael Morin 
Date:   Thu Dec 5 20:30:08 2024 +0100

Creation méthode initialisation descripteur

Utilisation méthode initialisation descripteur gfc_trans_deferred_array

Correction variable inutilisée

Correction segmentation fault

Correction regression allocatable attribute

Ajout conversion elem_len

conversion type longueur chaine

Initialisation descripteur champ par champ

Silence uninitialized warning.

Diff:
---
 gcc/fortran/expr.cc|  25 +++-
 gcc/fortran/gfortran.h |   1 +
 gcc/fortran/primary.cc |  84 +++-
 gcc/fortran/trans-array.cc | 286 +
 gcc/fortran/trans-intrinsic.cc |   2 +-
 5 files changed, 333 insertions(+), 65 deletions(-)

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index 7f3f6c52fb54..e4829448f710 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -5411,27 +5411,38 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
   gfc_ref *ref;
 
   if (expr->rank == 0)
-return NULL;
+return nullptr;
 
   /* Follow any component references.  */
   if (expr->expr_type == EXPR_VARIABLE
   || expr->expr_type == EXPR_CONSTANT)
 {
-  if (expr->symtree)
-   as = expr->symtree->n.sym->as;
+  gfc_symbol *sym = expr->symtree ? expr->symtree->n.sym : nullptr;
+  if (sym
+ && sym->ts.type == BT_CLASS)
+   as = CLASS_DATA (sym)->as;
+  else if (sym)
+   as = sym->as;
   else
-   as = NULL;
+   as = nullptr;
 
   for (ref = expr->ref; ref; ref = ref->next)
{
  switch (ref->type)
{
case REF_COMPONENT:
- as = ref->u.c.component->as;
+ {
+   gfc_component *comp = ref->u.c.component;
+   if (comp->ts.type == BT_CLASS)
+ as = CLASS_DATA (comp)->as;
+   else
+ as = comp->as;
+ }
  continue;
 
case REF_SUBSTRING:
case REF_INQUIRY:
+ as = nullptr;
  continue;
 
case REF_ARRAY:
@@ -5441,7 +5452,7 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
  case AR_ELEMENT:
  case AR_SECTION:
  case AR_UNKNOWN:
-   as = NULL;
+   as = nullptr;
continue;
 
  case AR_FULL:
@@ -5453,7 +5464,7 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
}
 }
   else
-as = NULL;
+as = nullptr;
 
   return as;
 }
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 7367db8853c6..b14857132ed7 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -4049,6 +4049,7 @@ const char *gfc_dt_lower_string (const char *);
 const char *gfc_dt_upper_string (const char *);
 
 /* primary.cc */
+symbol_attribute gfc_symbol_attr (gfc_symbol *);
 symbol_attribute gfc_variable_attr (gfc_expr *, gfc_typespec *);
 symbol_attribute gfc_expr_attr (gfc_expr *);
 symbol_attribute gfc_caf_attr (gfc_expr *, bool i = false, bool *r = NULL);
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 8a38720422ec..c934841f4795 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2867,42 +2867,14 @@ check_substring:
 }
 
 
-/* Given an expression that is a variable, figure out what the
-   ultimate variable's type and attribute is, traversing the reference
-   structures if necessary.
-
-   This subroutine is trickier than it looks.  We start at the base
-   symbol and store the attribute.  Component references load a
-   completely new attribute.
-
-   A couple of rules come into play.  Subobjects of targets are always
-   targets themselves.  If we see a component that goes through a
-   pointer, then the expression must also be a target, since the
-   pointer is associated with something (if it isn't core will soon be
-   dumped).  If we see a full part or section of an array, the
-   expression is also an array.
-
-   We can have at most one full array reference.  */
-
 symbol_attribute
-gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
+gfc_symbol_attr (gfc_symbol *sym)
 {
-  int dimension, codimension, pointer, allocatable, target, optional;
+  int dimension, codimension, pointer, allocatable, target;
   symbol_attribute attr;
-  gfc_ref *ref;
-  gfc_symbol *sym;
-  gfc_component *comp;
-  bool has_inquiry_part;
-
-  if (expr->expr_type != EXPR_VARIABLE
-  && expr->expr_type != EXPR_FUNCTION
-  && !(expr->expr_type == EXPR_NULL && expr->ts.type != BT_UNKNOWN))
-gfc_internal_error ("gfc_variable_attr(): Expression isn't a variable");
 
-  sym = expr->symtree->n.sym;
   attr = sym->attr;
 
-  optional = attr.optional;
   if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived)
 {
 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement shift descriptor vers gfc_conv_array_parameter

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:063c0014407236e53fa5c3734cab2f3fec5fa03f

commit 063c0014407236e53fa5c3734cab2f3fec5fa03f
Author: Mikael Morin 
Date:   Tue Dec 17 17:27:24 2024 +0100

Déplacement shift descriptor vers gfc_conv_array_parameter

Suppression variables inutilisées

Diff:
---
 gcc/fortran/trans-array.cc | 49 ++
 gcc/fortran/trans-array.h  |  2 +-
 gcc/fortran/trans-expr.cc  | 20 +--
 3 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 0370d10d9ebd..2fdd15962e49 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1151,6 +1151,43 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, 
tree desc,
 }
 
 
+static void
+conv_shift_descriptor (stmtblock_t* block, tree desc, int rank)
+{
+  /* Apply a shift of the lbound when supplied.  */
+  for (int dim = 0; dim < rank; ++dim)
+gfc_conv_shift_descriptor_lbound (block, desc, dim,
+ gfc_index_one_node);
+}
+
+
+static bool
+keep_descriptor_lower_bound (gfc_expr *e)
+{
+  gfc_ref *ref;
+
+  /* Detect any array references with vector subscripts.  */
+  for (ref = e->ref; ref; ref = ref->next)
+if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT
+   && ref->u.ar.type != AR_FULL)
+  {
+   int dim;
+   for (dim = 0; dim < ref->u.ar.dimen; dim++)
+ if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
+   break;
+   if (dim < ref->u.ar.dimen)
+ break;
+  }
+
+  /* Array references with vector subscripts and non-variable
+ expressions need be converted to a one-based descriptor.  */
+  if (ref || e->expr_type != EXPR_VARIABLE)
+return false;
+
+  return true;
+}
+
+
 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
 
 void
@@ -9454,7 +9491,7 @@ is_pointer (gfc_expr *e)
 void
 gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, bool g77,
  const gfc_symbol *fsym, const char *proc_name,
- tree *size, tree *lbshift, tree *packed)
+ tree *size, bool maybe_shift, tree *packed)
 {
   tree ptr;
   tree desc;
@@ -9690,13 +9727,9 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
  stmtblock_t block;
 
  gfc_init_block (&block);
- if (lbshift && *lbshift)
-   {
- /* Apply a shift of the lbound when supplied.  */
- for (int dim = 0; dim < expr->rank; ++dim)
-   gfc_conv_shift_descriptor_lbound (&block, se->expr, dim,
- *lbshift);
-   }
+ if (maybe_shift && !keep_descriptor_lower_bound (expr))
+   conv_shift_descriptor (&block, se->expr, expr->rank);
+
  tmp = gfc_class_data_get (ctree);
  if (expr->rank > 1 && CLASS_DATA (fsym)->as->rank != expr->rank
  && CLASS_DATA (fsym)->as->type == AS_EXPLICIT && !no_pack)
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 78646275b4ec..17e3d08fdba0 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -158,7 +158,7 @@ tree gfc_get_array_span (tree, gfc_expr *);
 void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *);
 /* Convert an array for passing as an actual function parameter.  */
 void gfc_conv_array_parameter (gfc_se *, gfc_expr *, bool, const gfc_symbol *,
-  const char *, tree *, tree * = nullptr,
+  const char *, tree *, bool = false,
   tree * = nullptr);
 
 /* These work with both descriptors and descriptorless arrays.  */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6978f83cdc8c..e8b229d853e3 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -991,8 +991,6 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
  stmtblock_t block;
  gfc_init_block (&block);
  gfc_ref *ref;
- int dim;
- tree lbshift = NULL_TREE;
 
  /* Array refs with sections indicate, that a for a formal argument
 expecting contiguous repacking needs to be done.  */
@@ -1005,25 +1003,9 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
  && (ref || e->rank != fsym->ts.u.derived->components->as->rank))
fsym->attr.contiguous = 1;
 
- /* Detect any array references with vector subscripts.  */
- for (ref = e->ref; ref; ref = ref->next)
-   if (ref->type == REF_ARRAY && ref->u.ar.type != AR_ELEMENT
-   && ref->u.ar.type != AR_FULL)
- {
-   for (dim = 0; dim < ref->u.ar.dimen; dim++)
- if (ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)
-   break;
-   if (dim < ref->u.ar.dimen)
- break;
- }
-

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Sauvegarde modifs

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:e3de44455296f04e014dad8c9efaef858384cfac

commit e3de44455296f04e014dad8c9efaef858384cfac
Author: Mikael Morin 
Date:   Sat Dec 7 22:22:10 2024 +0100

Sauvegarde modifs

Annulation suppression else

Correction assertions

Initialisation vptr

Non initialisation elem_len pour les conteneurs de classe

Mise à jour class_allocatable_14

Diff:
---
 gcc/fortran/trans-array.cc  | 52 ++
 gcc/fortran/trans-array.h   |  2 +
 gcc/fortran/trans-decl.cc   | 58 +
 gcc/testsuite/gfortran.dg/class_allocate_14.f90 |  2 +-
 4 files changed, 66 insertions(+), 48 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 268de211cd66..d15576adde10 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -734,6 +734,58 @@ gfc_build_null_descriptor (tree type, gfc_typespec &ts,
 }
 
 
+tree
+gfc_build_default_class_descriptor (tree type, gfc_typespec &ts)
+{
+  vec *v = nullptr;
+
+  tree fields = TYPE_FIELDS (type);
+
+#define CLASS_DATA_FIELD 0
+#define CLASS_VPTR_FIELD 1
+
+  tree data_field = gfc_advance_chain (fields, CLASS_DATA_FIELD);
+  tree data_type = TREE_TYPE (data_field);
+
+  gcc_assert (ts.type == BT_CLASS);
+  tree data_value;
+  if (ts.u.derived->components->attr.dimension
+  || (ts.u.derived->components->attr.codimension
+ && flag_coarray != GFC_FCOARRAY_LIB))
+{
+  gcc_assert (GFC_DESCRIPTOR_TYPE_P (data_type));
+  data_value = gfc_build_null_descriptor (data_type,
+ ts,
+ 
ts.u.derived->components->as->rank,
+ ts.u.derived->components->attr);
+}
+  else
+{
+  gcc_assert (POINTER_TYPE_P (data_type));
+  data_value = fold_convert (data_type, null_pointer_node);
+}
+  CONSTRUCTOR_APPEND_ELT (v, data_field, data_value);
+
+  tree vptr_field = gfc_advance_chain (fields, CLASS_VPTR_FIELD);
+
+  tree vptr_value;
+  if (ts.u.derived->attr.unlimited_polymorphic)
+vptr_value = fold_convert (TREE_TYPE (vptr_field), null_pointer_node);
+  else
+{
+  gfc_symbol *vsym = gfc_find_derived_vtab (ts.u.derived);
+  tree vsym_decl = gfc_get_symbol_decl (vsym);
+  vptr_value = gfc_build_addr_expr (nullptr, vsym_decl);
+}
+  CONSTRUCTOR_APPEND_ELT (v, vptr_field, vptr_value);
+
+#undef CLASS_DATA_FIELD
+#undef CLASS_VPTR_FIELD
+  
+  return build_constructor (type, v);
+}
+
+
 void
 gfc_clear_descriptor (gfc_expr *var_ref, gfc_se &var)
 {
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 1bb3294b0749..63a77d562a7b 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -140,6 +140,8 @@ void gfc_set_delta (gfc_loopinfo *);
 void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss *, gfc_ss *);
 /* Build a null array descriptor constructor.  */
 tree gfc_build_null_descriptor (tree);
+tree gfc_build_default_class_descriptor (tree, gfc_typespec &);
+void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym, tree 
descriptor);
 
 /* Get a single array element.  */
 void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *);
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 4ae22a5584d0..dad15858fa6a 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -4780,16 +4780,14 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, 
gfc_wrapped_block * block)
   else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
 {
   /* Nullify explicit return class arrays on entry.  */
-  tree type;
   tmp = get_proc_result (proc_sym);
-   if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
- {
-   gfc_start_block (&init);
-   tmp = gfc_class_data_get (tmp);
-   type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
-   gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
-   gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
- }
+  if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
+   {
+ gfc_start_block (&init);
+ tmp = gfc_class_data_get (tmp);
+ gfc_clear_descriptor (&init, proc_sym, tmp);
+ gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
+   }
 }
 
 
@@ -4931,48 +4929,13 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, 
gfc_wrapped_block * block)
}
}
 
-  if (sym->attr.pointer && sym->attr.dimension
- && sym->attr.save == SAVE_NONE
- && !sym->attr.use_assoc
- && !sym->attr.host_assoc
- && !sym->attr.dummy
- && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
-   {
- gfc_init_block (&tmpblock);
- gfc_conv_descriptor_span_set (&tmpblock, sym->backend_decl,
-   

[gcc] Deleted branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users'

2025-02-14 Thread Mikael Morin via Gcc-cvs
The branch 'mikael/heads/refactor_descriptor_v01' in namespace 'refs/users' was 
deleted.
It previously pointed to:

 e8d300a99c04... Déplacement fonction

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  e8d300a... Déplacement fonction
  cbb7977... Factorisation shift_descriptor
  2e7ed30... Correction typo
  305e39d... Factorisation set_descriptor_dimension
  cf483b5... Correction régression class_transformational_2
  d8e509d... Réduction différences
  61b45d5... Suppression code redondant initialisation descriptor tempor
  bcdea6a... Factorisation set temporary descriptor
  e10f619... Correction erreurs non-lvalue lhs pr113363.f90
  18adfe8... Ajout surcharge gfc_conv_descriptor_type_set
  0533730... Correction non_lvalue PR97046.f90
  0f4d403... git commit correction erreur gimplify
  6a9e70e... Interdiction non-lvalue as lhs
  ca55548... Mise à jour dump contiguous_3.f90
  d130e5d... Mise à jour dump coarray_lib_token_2.f90
  19c7720... Mise à jour dump coarray_lib_token_3.f90
  4c58f11... Mise à jour dump coarray_lib_token_4.f90
  79013ea... Mise à jour dump coarray_lib_alloc_1.f90
  3e36fe8... Mise à jour dump coarray_lib_alloc_3.f90
  6ec... Mise à jour dump coarray_lib_alloc_2.f90
  37a7e66... Mise à jour dump coarray_lib_alloc_4.f90
  c490d4b... Correction dump coarray_allocate_7.f08
  35716cd... Mise à jour dump coarray_lock_7.f90
  93cb38c... Mise à jour dumps coarray_poly_*.f90
  5565aa2... Mise à jour dump bind-c-contiguous-2.f90
  278b414... match: Unwrap non-lvalue as unary or binary operand
  f22fec6... match: Simplify double not and double negate to a non_lvalu
  4a81633... Correction ICE coarray_42.f90
  ef90284... Correction régression assumed_rank_7.f90
  ac595ff... Correction régression realloc on assign (associate_61, ...
  3938b37... Introduction getters et setters descriptor compil' OK
  ad8f09d... Correction régression realloc_on_assign_12.f90
  3fa2826... Factorisation initialisation dimension descripteur
  89ff0d9... Factorisation set_descriptor_dimension
  b253d45... Factorisation gfc_conv_shift_descriptor
  96c395b... Renseignement token par gfc_set_descriptor_from_scalar.
  cd99fad... Séparation motifs dump assumed_rank_12.f90
  ac8ccbd... Annulation modif dump assumed_rank_12.f90
  34baff5... Sauvegarde factorisation set_descriptor_from_scalar
  47b6338... Déplacement gfc_set_gfc_from_cfi
  d292794... Déplacement gfc_copy_sequence_descriptor
  da0f060... Déplacement méthode set_descriptor_from_scalar
  0aef327... Suppression code redondant
  0838449... Update dump match count
  01b40a5... Factorisation set_descriptor_from_scalar dans gfc_conv_scal
  c3d8cf0... Factorisation set_descriptor_from_scalar conv_derived_to_cl
  60fb6b7... Factorisation set_descriptor_from_scalar dans conv_class_to
  1392f13... Factorisation initialisation depuis cfi
  84be5a4... utilisation booléen allocatable
  57a9d25... Factorisation initialisation gfc depuis cfi
  7d9a5b7... Refactoring gfc_conv_descriptor_sm_get.
  55a2a10... Introduction gfc_conv_descriptor_extent_get
  c2ce739... Factorisation shift descriptor
  41e3834... Factorisation initialisation subarray_descriptor
  c3a50c1... Factorisation set descriptor with shape
  b5834ef... Factorisation set_contiguous_array
  ccb2dcc... Factorisation set_contiguous_array
  bd3573d... Essai suppression unlimited_polymorphic
  a6d12d1... Refactor conv_shift_descriptor
  7818e31... Factorisation shift descriptor
  7421792... Factorisation shift descriptor
  d607595... Factorisation gfc_conv_expr_descriptor
  82413c9... Factorisation copie gfc_conv_expr_descriptor
  ed6fee2... Extraction fonction fcncall_realloc_result
  7ed0026... Factorisation gfc_conv_remap_descriptor
  6d1a550... Introduction gfc_copy_sequence_descriptor
  b68e4d2... Utilisation de la méthode de nullification pour nullifier 
  ecdc8da... Appel méthode shift descriptor dans gfc_trans_pointer_assi
  063c001... Déplacement shift descriptor vers gfc_conv_array_parameter
  db8ddde... Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_c
  e3de444... Sauvegarde modifs
  3c45ca6... Creation méthode initialisation descripteur


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_contiguous_array

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ccb2dcc879e6c3debbd0e010cfc394cfde504fbc

commit ccb2dcc879e6c3debbd0e010cfc394cfde504fbc
Author: Mikael Morin 
Date:   Fri Jan 17 17:25:59 2025 +0100

Factorisation set_contiguous_array

Diff:
---
 gcc/fortran/trans-array.cc | 57 +++---
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4f066680dff0..76668d8a3ef1 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10685,6 +10685,23 @@ gfc_caf_is_dealloc_only (int caf_mode)
 }
 
 
+static void
+set_contiguous_array (stmtblock_t *block, tree desc, tree size, tree data_ptr)
+{
+  gfc_add_modify (block, gfc_conv_descriptor_dtype (desc),
+ gfc_get_dtype_rank_type (1, TREE_TYPE (desc)));
+  gfc_conv_descriptor_lbound_set (block, desc,
+ gfc_index_zero_node,
+ gfc_index_one_node);
+  gfc_conv_descriptor_stride_set (block, desc,
+ gfc_index_zero_node,
+ gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block, desc,
+ gfc_index_zero_node, size);
+  gfc_conv_descriptor_data_set (block, desc, data_ptr);
+}
+
+
 /* Recursively traverse an object of derived type, generating code to
deallocate, nullify or copy allocatable components.  This is the work horse
function for the functions named in this enum.  */
@@ -10945,32 +10962,6 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  ubound = build_int_cst (gfc_array_index_type, 1);
}
 
- /* Treat strings like arrays.  Or the other way around, do not
-  * generate an additional array layer for scalar components.  */
- if (attr->dimension || c->ts.type == BT_CHARACTER)
-   {
- cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
-&ubound, 1,
-GFC_ARRAY_ALLOCATABLE, false);
-
- cdesc = gfc_create_var (cdesc, "cdesc");
- DECL_ARTIFICIAL (cdesc) = 1;
-
- gfc_add_modify (&tmpblock, gfc_conv_descriptor_dtype (cdesc),
- gfc_get_dtype_rank_type (1, tmp));
- gfc_conv_descriptor_lbound_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_stride_set (&tmpblock, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&tmpblock, cdesc,
- gfc_index_zero_node, ubound);
-   }
- else
-   /* Prevent warning.  */
-   cdesc = NULL_TREE;
-
  if (attr->dimension)
{
  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (comp)))
@@ -10993,13 +10984,23 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  gfc_add_block_to_block (&tmpblock, &se.pre);
}
 
+ /* Treat strings like arrays.  Or the other way around, do not
+  * generate an additional array layer for scalar components.  */
  if (attr->dimension || c->ts.type == BT_CHARACTER)
-   gfc_conv_descriptor_data_set (&tmpblock, cdesc, comp);
+   {
+ cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
+&ubound, 1,
+GFC_ARRAY_ALLOCATABLE, false);
+
+ cdesc = gfc_create_var (cdesc, "cdesc");
+ DECL_ARTIFICIAL (cdesc) = 1;
+
+ set_contiguous_array (&tmpblock, cdesc, ubound, comp);
+   }
  else
cdesc = comp;
 
  tree fndecl;
-
  fndecl = build_call_expr_loc (input_location,
gfor_fndecl_co_broadcast, 5,
gfc_build_addr_expr 
(pvoid_type_node,cdesc),


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation gfc_conv_remap_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7ed00263a569c00bf6bf52ea343e677b873e0e2f

commit 7ed00263a569c00bf6bf52ea343e677b873e0e2f
Author: Mikael Morin 
Date:   Sat Jan 4 21:36:13 2025 +0100

Factorisation gfc_conv_remap_descriptor

Correction régression pointer_remapping_5

Diff:
---
 gcc/fortran/trans-array.cc | 119 +++
 gcc/fortran/trans-expr.cc  | 124 +++--
 gcc/fortran/trans.h|   2 +
 3 files changed, 129 insertions(+), 116 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 5d56a12ebf71..898930634ad1 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1332,6 +1332,125 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree 
desc,
 }
 
 
+void
+gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src,
+  int src_rank, const gfc_array_spec &as)
+{
+  int dest_rank = gfc_descriptor_rank (dest);
+
+  /* Set dtype.  */
+  tree dtype = gfc_conv_descriptor_dtype (dest);
+  tree tmp = gfc_get_dtype (TREE_TYPE (src));
+  gfc_add_modify (block, dtype, tmp);
+
+  /* Copy data pointer.  */
+  tree data = gfc_conv_descriptor_data_get (src);
+  gfc_conv_descriptor_data_set (block, dest, data);
+
+  /* Copy the span.  */
+  tree span;
+  if (VAR_P (src)
+  && GFC_DECL_PTR_ARRAY_P (src))
+span = gfc_conv_descriptor_span_get (src);
+  else
+{
+  tmp = TREE_TYPE (src);
+  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (tmp));
+  span = fold_convert (gfc_array_index_type, tmp);
+}
+  gfc_conv_descriptor_span_set (block, dest, span);
+
+  /* Copy offset but adjust it such that it would correspond
+ to a lbound of zero.  */
+  if (src_rank == -1)
+gfc_conv_descriptor_offset_set (block, dest,
+   gfc_index_zero_node);
+  else
+{
+  tree offs = gfc_conv_descriptor_offset_get (src);
+  for (int dim = 0; dim < src_rank; ++dim)
+   {
+ tree stride = gfc_conv_descriptor_stride_get (src,
+   gfc_rank_cst[dim]);
+ tree lbound = gfc_conv_descriptor_lbound_get (src,
+   gfc_rank_cst[dim]);
+ tmp = fold_build2_loc (input_location, MULT_EXPR,
+gfc_array_index_type, stride,
+lbound);
+ offs = fold_build2_loc (input_location, PLUS_EXPR,
+ gfc_array_index_type, offs, tmp);
+   }
+  gfc_conv_descriptor_offset_set (block, dest, offs);
+}
+  /* Set the bounds as declared for the LHS and calculate strides as
+ well as another offset update accordingly.  */
+  tree stride = gfc_conv_descriptor_stride_get (src,
+  gfc_rank_cst[0]);
+  for (int dim = 0; dim < dest_rank; ++dim)
+{
+  gfc_se lower_se;
+  gfc_se upper_se;
+
+  gcc_assert (as.lower[dim] && as.upper[dim]);
+
+  /* Convert declared bounds.  */
+  gfc_init_se (&lower_se, NULL);
+  gfc_init_se (&upper_se, NULL);
+  gfc_conv_expr (&lower_se, as.lower[dim]);
+  gfc_conv_expr (&upper_se, as.upper[dim]);
+
+  gfc_add_block_to_block (block, &lower_se.pre);
+  gfc_add_block_to_block (block, &upper_se.pre);
+
+  tree lbound = fold_convert (gfc_array_index_type, lower_se.expr);
+  tree ubound = fold_convert (gfc_array_index_type, upper_se.expr);
+
+  lbound = gfc_evaluate_now (lbound, block);
+  ubound = gfc_evaluate_now (ubound, block);
+
+  gfc_add_block_to_block (block, &lower_se.post);
+  gfc_add_block_to_block (block, &upper_se.post);
+
+  /* Set bounds in descriptor.  */
+  gfc_conv_descriptor_lbound_set (block, dest,
+ gfc_rank_cst[dim], lbound);
+  gfc_conv_descriptor_ubound_set (block, dest,
+ gfc_rank_cst[dim], ubound);
+
+  /* Set stride.  */
+  stride = gfc_evaluate_now (stride, block);
+  gfc_conv_descriptor_stride_set (block, dest,
+ gfc_rank_cst[dim], stride);
+
+  /* Update offset.  */
+  tree offs = gfc_conv_descriptor_offset_get (dest);
+  tmp = fold_build2_loc (input_location, MULT_EXPR,
+gfc_array_index_type, lbound, stride);
+  offs = fold_build2_loc (input_location, MINUS_EXPR,
+ gfc_array_index_type, offs, tmp);
+  offs = gfc_evaluate_now (offs, block);
+  gfc_conv_descriptor_offset_set (block, dest, offs);
+
+  /* Update stride.  */
+  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+  stride = fold_build2_loc (input_location, MULT_EXPR,
+   gfc_array_index_type, stride, tmp);
+}
+}
+
+
+void
+gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src,
+  int src_rank, const gfc_array_ref &ar)
+{
+  g

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Essai suppression unlimited_polymorphic

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:bd3573d2425487de1c1d165e86d63ff83037c584

commit bd3573d2425487de1c1d165e86d63ff83037c584
Author: Mikael Morin 
Date:   Thu Jan 16 20:45:34 2025 +0100

Essai suppression unlimited_polymorphic

Diff:
---
 gcc/fortran/trans-array.cc | 13 -
 gcc/fortran/trans.h|  3 ---
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index bf11689cf3dd..4f066680dff0 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9019,7 +9019,7 @@ set_descriptor (stmtblock_t *block, tree dest, tree src, 
gfc_expr *src_expr,
int rank, int corank, gfc_ss *ss, gfc_array_info *info,
tree lowers[GFC_MAX_DIMENSIONS],
tree uppers[GFC_MAX_DIMENSIONS],
-   bool unlimited_polymorphic, bool data_needed, bool subref)
+   bool data_needed, bool subref)
 {
   int ndim = info->ref ? info->ref->u.ar.dimen : rank;
 
@@ -9044,9 +9044,7 @@ set_descriptor (stmtblock_t *block, tree dest, tree src, 
gfc_expr *src_expr,
   /* Set the dtype.  */
   tmp = gfc_conv_descriptor_dtype (dest);
   tree dtype;
-  if (unlimited_polymorphic)
-dtype = gfc_get_dtype (TREE_TYPE (src), &rank);
-  else if (src_expr->ts.type == BT_ASSUMED)
+  if (src_expr->ts.type == BT_ASSUMED)
 {
   tree tmp2 = src;
   if (DECL_LANG_SPECIFIC (tmp2) && GFC_DECL_SAVED_DESCRIPTOR (tmp2))
@@ -9056,7 +9054,7 @@ set_descriptor (stmtblock_t *block, tree dest, tree src, 
gfc_expr *src_expr,
   dtype = gfc_conv_descriptor_dtype (tmp2);
 }
   else
-dtype = gfc_get_dtype (TREE_TYPE (dest));
+dtype = gfc_get_dtype (TREE_TYPE (src), &rank);
   gfc_add_modify (block, tmp, dtype);
 
   /* The 1st element in the section.  */
@@ -9254,9 +9252,6 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
   expr = expr->value.function.actual->expr;
 }
 
-  if (!se->direct_byref)
-se->unlimited_polymorphic = UNLIMITED_POLY (expr);
-
   /* Special case things we know we can pass easily.  */
   switch (expr->expr_type)
 {
@@ -9660,7 +9655,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
}
 
   set_descriptor (&loop.pre, parm, desc, expr, loop.dimen, codim,
- ss, info, loop.from, loop.to, se->unlimited_polymorphic,
+ ss, info, loop.from, loop.to,
  !se->data_not_needed, subref_array_target);
 
   desc = parm;
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 098fb07c1483..197dea0a18a6 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -61,9 +61,6 @@ typedef struct gfc_se
  the reference to the class object here.  */
   tree class_container;
 
-  /* Whether expr is a reference to an unlimited polymorphic object.  */
-  unsigned unlimited_polymorphic:1;
-
   /* If set gfc_conv_variable will return an expression for the array
  descriptor. When set, want_pointer should also be set.
  If not set scalarizing variables will be substituted.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation shift descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7818e31b1ca1ea4796040325332a850765ef9fdd

commit 7818e31b1ca1ea4796040325332a850765ef9fdd
Author: Mikael Morin 
Date:   Thu Jan 16 14:51:42 2025 +0100

Factorisation shift descriptor

Diff:
---
 gcc/fortran/trans-expr.cc | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 77e8a55af457..b7d1e3df0613 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -1219,7 +1219,6 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
   tree ctree;
   tree var;
   tree tmp;
-  int dim;
   bool unlimited_poly;
 
   unlimited_poly = class_ts.type == BT_CLASS
@@ -1287,11 +1286,7 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e,
  /* Array references with vector subscripts and non-variable 
expressions
 need be converted to a one-based descriptor.  */
  if (e->expr_type != EXPR_VARIABLE)
-   {
- for (dim = 0; dim < e->rank; ++dim)
-   gfc_conv_shift_descriptor_lbound (&parmse->pre, parmse->expr,
- dim, gfc_index_one_node);
-   }
+   gfc_conv_shift_descriptor (&parmse->pre, parmse->expr, e->rank);
 
  if (class_ts.u.derived->components->as->rank != e->rank)
{


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Introduction gfc_copy_sequence_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6d1a550acfb35381deea5afbd424a7e79852f5b1

commit 6d1a550acfb35381deea5afbd424a7e79852f5b1
Author: Mikael Morin 
Date:   Tue Dec 31 15:27:35 2024 +0100

Introduction gfc_copy_sequence_descriptor

Correction régression sizeof_6

Diff:
---
 gcc/fortran/trans-array.cc | 39 ++-
 gcc/fortran/trans-expr.cc  | 44 
 gcc/fortran/trans.h|  1 +
 3 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4c237b561aa6..5d56a12ebf71 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -9901,32 +9901,21 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
  if (maybe_shift && !keep_descriptor_lower_bound (expr))
conv_shift_descriptor (&block, se->expr, expr->rank);
 
+ bool assumed_rank_fsym;
+ if (fsym
+ && ((fsym->ts.type == BT_CLASS
+  && CLASS_DATA (fsym)->as
+  && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK)
+ || (fsym->ts.type != BT_CLASS
+ && fsym->as
+ && fsym->as->type == AS_ASSUMED_RANK)))
+   assumed_rank_fsym = true;
+ else
+   assumed_rank_fsym = false;
+
  tmp = gfc_class_data_get (ctree);
- if (expr->rank > 1 && CLASS_DATA (fsym)->as->rank != expr->rank
- && CLASS_DATA (fsym)->as->type == AS_EXPLICIT && !no_pack)
-   {
- tree arr = gfc_create_var (TREE_TYPE (tmp), "parm");
- gfc_conv_descriptor_data_set (&block, arr,
-   gfc_conv_descriptor_data_get (
- se->expr));
- gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node,
- gfc_index_zero_node);
- gfc_conv_descriptor_ubound_set (
-   &block, arr, gfc_index_zero_node,
-   gfc_conv_descriptor_size (se->expr, expr->rank));
- gfc_conv_descriptor_stride_set (
-   &block, arr, gfc_index_zero_node,
-   gfc_conv_descriptor_stride_get (se->expr, gfc_index_zero_node));
- gfc_add_modify (&block, gfc_conv_descriptor_dtype (arr),
- gfc_conv_descriptor_dtype (se->expr));
- gfc_add_modify (&block, gfc_conv_descriptor_rank (arr),
- build_int_cst (signed_char_type_node, 1));
- gfc_conv_descriptor_span_set (&block, arr,
-   gfc_conv_descriptor_span_get (arr));
- gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node);
- se->expr = arr;
-   }
- gfc_class_array_data_assign (&block, tmp, se->expr, true);
+ gfc_copy_sequence_descriptor (block, tmp, se->expr,
+   assumed_rank_fsym);
 
  /* Handle optional.  */
  if (fsym && fsym->attr.optional && sym && sym->attr.optional)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 003754cdad6f..5dff9692f0ba 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -846,6 +846,50 @@ descriptor_rank (tree descriptor)
 }
 
 
+void
+gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc,
+ bool assumed_rank_lhs)
+{
+  int lhs_rank = descriptor_rank (lhs_desc);
+  int rhs_rank = descriptor_rank (rhs_desc);
+  tree desc;
+
+  if (assumed_rank_lhs || lhs_rank == rhs_rank)
+desc = rhs_desc;
+  else
+{
+  tree arr = gfc_create_var (TREE_TYPE (lhs_desc), "parm");
+  gfc_conv_descriptor_data_set (&block, arr,
+   gfc_conv_descriptor_data_get (rhs_desc));
+  gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node,
+ gfc_index_zero_node);
+  tree size = gfc_conv_descriptor_size (rhs_desc, rhs_rank);
+  gfc_conv_descriptor_ubound_set (&block, arr, gfc_index_zero_node, size);
+  gfc_conv_descriptor_stride_set (
+   &block, arr, gfc_index_zero_node,
+   gfc_conv_descriptor_stride_get (rhs_desc, gfc_index_zero_node));
+  for (int i = 1; i < lhs_rank; i++)
+   {
+ gfc_conv_descriptor_lbound_set (&block, arr, gfc_rank_cst[i],
+ gfc_index_zero_node);
+ gfc_conv_descriptor_ubound_set (&block, arr, gfc_rank_cst[i],
+ gfc_index_zero_node);
+ gfc_conv_descriptor_stride_set (&block, arr, gfc_rank_cst[i], size);
+   }
+  gfc_add_modify (&block, gfc_conv_descriptor_dtype (arr),
+ gfc_conv_descriptor_dtype (rhs_desc));
+  gfc_add_modify (&block, gfc_conv_descriptor_rank (arr),
+ build_int_cst (signed_cha

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation gfc_conv_expr_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d607595f1f4f4566776000aeedfd4d0bb3ce4b9b

commit d607595f1f4f4566776000aeedfd4d0bb3ce4b9b
Author: Mikael Morin 
Date:   Thu Jan 16 14:00:20 2025 +0100

Factorisation gfc_conv_expr_descriptor

Diff:
---
 gcc/fortran/trans-array.cc | 358 +++--
 1 file changed, 186 insertions(+), 172 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 097a9a0d860a..ec0badd0dc33 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1542,6 +1542,25 @@ keep_descriptor_lower_bound (gfc_expr *e)
 }
 
 
+static void
+copy_descriptor (stmtblock_t *block, tree dest, tree src,
+gfc_expr *src_expr, bool subref)
+{
+  /* Copy the descriptor for pointer assignments.  */
+  gfc_add_modify (block, dest, src);
+
+  /* Add any offsets from subreferences.  */
+  gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr);
+
+  /* and set the span field.  */
+  tree tmp;
+  if (src_expr->ts.type == BT_CHARACTER)
+tmp = gfc_conv_descriptor_span_get (src);
+  else
+tmp = gfc_get_array_span (src, src_expr);
+  gfc_conv_descriptor_span_set (block, dest, tmp);
+}
+
 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
 
 void
@@ -8991,24 +9010,175 @@ is_explicit_coarray (gfc_expr *expr)
 
 
 static void
-copy_descriptor (stmtblock_t *block, tree dest, tree src,
-gfc_expr *src_expr, bool subref)
+set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr,
+   int rank, int corank, gfc_ss *ss, gfc_array_info *info,
+   tree lowers[GFC_MAX_DIMENSIONS],
+   tree uppers[GFC_MAX_DIMENSIONS],
+   bool unlimited_polymorphic, bool data_needed, bool subref)
 {
-  /* Copy the descriptor for pointer assignments.  */
-  gfc_add_modify (block, dest, src);
+  int ndim = info->ref ? info->ref->u.ar.dimen : rank;
 
-  /* Add any offsets from subreferences.  */
-  gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr);
-
-  /* and set the span field.  */
-  tree tmp;
-  if (src_expr->ts.type == BT_CHARACTER)
+  /* Set the span field.  */
+  tree tmp = NULL_TREE;
+  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (src)))
 tmp = gfc_conv_descriptor_span_get (src);
   else
 tmp = gfc_get_array_span (src, src_expr);
-  gfc_conv_descriptor_span_set (block, dest, tmp);
+  if (tmp)
+gfc_conv_descriptor_span_set (block, dest, tmp);
+
+  /* The following can be somewhat confusing.  We have two
+ descriptors, a new one and the original array.
+ {dest, parmtype, dim} refer to the new one.
+ {src, type, n, loop} refer to the original, which maybe
+ a descriptorless array.
+ The bounds of the scalarization are the bounds of the section.
+ We don't have to worry about numeric overflows when calculating
+ the offsets because all elements are within the array data.  */
+
+  /* Set the dtype.  */
+  tmp = gfc_conv_descriptor_dtype (dest);
+  tree dtype;
+  if (unlimited_polymorphic)
+dtype = gfc_get_dtype (TREE_TYPE (src), &rank);
+  else if (src_expr->ts.type == BT_ASSUMED)
+{
+  tree tmp2 = src;
+  if (DECL_LANG_SPECIFIC (tmp2) && GFC_DECL_SAVED_DESCRIPTOR (tmp2))
+   tmp2 = GFC_DECL_SAVED_DESCRIPTOR (tmp2);
+  if (POINTER_TYPE_P (TREE_TYPE (tmp2)))
+   tmp2 = build_fold_indirect_ref_loc (input_location, tmp2);
+  dtype = gfc_conv_descriptor_dtype (tmp2);
+}
+  else
+dtype = gfc_get_dtype (TREE_TYPE (dest));
+  gfc_add_modify (block, tmp, dtype);
+
+  /* The 1st element in the section.  */
+  tree base = gfc_index_zero_node;
+  if (src_expr->ts.type == BT_CHARACTER && src_expr->rank == 0 && corank)
+base = gfc_index_one_node;
+
+  /* The offset from the 1st element in the section.  */
+  tree offset = gfc_index_zero_node;
+
+  for (int n = 0; n < ndim; n++)
+{
+  tree stride = gfc_conv_array_stride (src, n);
+
+  /* Work out the 1st element in the section.  */
+  tree start;
+  if (info->ref
+ && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
+   {
+ gcc_assert (info->subscript[n]
+ && info->subscript[n]->info->type == GFC_SS_SCALAR);
+ start = info->subscript[n]->info->data.scalar.value;
+   }
+  else
+   {
+ /* Evaluate and remember the start of the section.  */
+ start = info->start[n];
+ stride = gfc_evaluate_now (stride, block);
+   }
+
+  tmp = gfc_conv_array_lbound (src, n);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
+start, tmp);
+  tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
+tmp, stride);
+  base = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp),
+   base, tmp);
+
+  if (info->ref
+ && info->ref->u.ar.dimen_type[n] == DIMEN_ELEMENT)
+   {
+ 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set descriptor with shape

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c3a50c1a8cb83384345d3dc3530fbb9b830d6e85

commit c3a50c1a8cb83384345d3dc3530fbb9b830d6e85
Author: Mikael Morin 
Date:   Fri Jan 17 21:46:27 2025 +0100

Factorisation set descriptor with shape

Diff:
---
 gcc/fortran/trans-array.cc | 78 ++
 gcc/fortran/trans-array.h  |  2 ++
 gcc/fortran/trans-intrinsic.cc | 76 +++-
 3 files changed, 85 insertions(+), 71 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 88a2509a5246..b05f69fdd874 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1566,6 +1566,84 @@ copy_descriptor (stmtblock_t *block, tree dest, tree src,
   gfc_conv_descriptor_span_set (block, dest, tmp);
 }
 
+
+void
+gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc,
+  tree ptr, gfc_expr *shape,
+  locus *where)
+{
+  /* Set the span field.  */
+  tree tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
+  tmp = fold_convert (gfc_array_index_type, tmp);
+  gfc_conv_descriptor_span_set (block, desc, tmp);
+
+  /* Set data value, dtype, and offset.  */
+  tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
+  gfc_conv_descriptor_data_set (block, desc, fold_convert (tmp, ptr));
+  gfc_add_modify (block, gfc_conv_descriptor_dtype (desc),
+ gfc_get_dtype (TREE_TYPE (desc)));
+
+  /* Start scalarization of the bounds, using the shape argument.  */
+
+  gfc_ss *shape_ss = gfc_walk_expr (shape);
+  gcc_assert (shape_ss != gfc_ss_terminator);
+  gfc_se shapese;
+  gfc_init_se (&shapese, NULL);
+
+  gfc_loopinfo loop;
+  gfc_init_loopinfo (&loop);
+  gfc_add_ss_to_loop (&loop, shape_ss);
+  gfc_conv_ss_startstride (&loop);
+  gfc_conv_loop_setup (&loop, where);
+  gfc_mark_ss_chain_used (shape_ss, 1);
+
+  gfc_copy_loopinfo_to_se (&shapese, &loop);
+  shapese.ss = shape_ss;
+
+  tree stride = gfc_create_var (gfc_array_index_type, "stride");
+  tree offset = gfc_create_var (gfc_array_index_type, "offset");
+  gfc_add_modify (block, stride, gfc_index_one_node);
+  gfc_add_modify (block, offset, gfc_index_zero_node);
+
+  /* Loop body.  */
+  stmtblock_t body;
+  gfc_start_scalarized_body (&loop, &body);
+
+  tree dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ loop.loopvar[0], loop.from[0]);
+
+  /* Set bounds and stride.  */
+  gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node);
+  gfc_conv_descriptor_stride_set (&body, desc, dim, stride);
+
+  gfc_conv_expr (&shapese, shape);
+  gfc_add_block_to_block (&body, &shapese.pre);
+  gfc_conv_descriptor_ubound_set (&body, desc, dim, shapese.expr);
+  gfc_add_block_to_block (&body, &shapese.post);
+
+  /* Calculate offset.  */
+  gfc_add_modify (&body, offset,
+ fold_build2_loc (input_location, PLUS_EXPR,
+  gfc_array_index_type, offset, stride));
+  /* Update stride.  */
+  gfc_add_modify (&body, stride,
+ fold_build2_loc (input_location, MULT_EXPR,
+  gfc_array_index_type, stride,
+  fold_convert (gfc_array_index_type,
+shapese.expr)));
+  /* Finish scalarization loop.  */
+  gfc_trans_scalarizing_loops (&loop, &body);
+  gfc_add_block_to_block (block, &loop.pre);
+  gfc_add_block_to_block (block, &loop.post);
+  gfc_cleanup_loop (&loop);
+
+  gfc_add_modify (block, offset,
+ fold_build1_loc (input_location, NEGATE_EXPR,
+  gfc_array_index_type, offset));
+  gfc_conv_descriptor_offset_set (block, desc, offset);
+}
+
+
 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
 
 void
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 3f39845c898f..05ea68d531ac 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -145,6 +145,8 @@ void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol 
*, tree);
 void gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *, tree);
 void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, gfc_expr *, tree);
 void gfc_set_scalar_descriptor (stmtblock_t *block, tree, gfc_symbol *, 
gfc_expr *, tree);
+void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree,
+   gfc_expr *, locus *);
 
 /* Get a single array element.  */
 void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *);
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index b6900d734afd..5d77f3d768a6 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -10482,11 +10482,8 @@ conv_isocbinding_subroutine (gfc_code *code)
   gfc_se se;
   gfc_se cptrse;
   gfc_se fptrse;
-  gfc_se shapese;
-  gfc_ss *shape_ss;
-  tree desc, dim, tmp, stride, offset;
-  stmtbl

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation shift descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7421792ba1ee3c272b294ac19a85bc43ad73e3c7

commit 7421792ba1ee3c272b294ac19a85bc43ad73e3c7
Author: Mikael Morin 
Date:   Thu Jan 16 14:35:14 2025 +0100

Factorisation shift descriptor

Diff:
---
 gcc/fortran/trans-array.cc | 6 +++---
 gcc/fortran/trans-array.h  | 1 +
 gcc/fortran/trans-stmt.cc  | 6 +-
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ec0badd0dc33..ecdaad3f9575 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1257,8 +1257,8 @@ conv_shift_descriptor (stmtblock_t *block, tree desc, int 
rank,
 }
 
 
-static void
-conv_shift_descriptor (stmtblock_t* block, tree desc, int rank)
+void
+gfc_conv_shift_descriptor (stmtblock_t* block, tree desc, int rank)
 {
   conv_shift_descriptor (block, desc, rank, unset_lb ());
 }
@@ -10103,7 +10103,7 @@ gfc_conv_array_parameter (gfc_se *se, gfc_expr *expr, 
bool g77,
 
  gfc_init_block (&block);
  if (maybe_shift && !keep_descriptor_lower_bound (expr))
-   conv_shift_descriptor (&block, se->expr, expr->rank);
+   gfc_conv_shift_descriptor (&block, se->expr, expr->rank);
 
  bool assumed_rank_fsym;
  if (fsym
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 571322ae11ff..378afb9617a3 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -216,6 +216,7 @@ tree gfc_get_cfi_dim_sm (tree, tree);
 /* Shift lower bound of descriptor, updating ubound and offset.  */
 void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &);
+void gfc_conv_shift_descriptor (stmtblock_t*, tree, int);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree);
 
 /* Add pre-loop scalarization code for intrinsic functions which require
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index e7da8fea3b24..01fb8d91007f 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -2007,16 +2007,12 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block 
*block)
   if ((!sym->assoc->variable && !cst_array_ctor)
  || !whole_array)
{
- int dim;
-
  if (whole_array)
gfc_add_modify (&se.pre, desc, se.expr);
 
  /* The generated descriptor has lower bound zero (as array
 temporary), shift bounds so we get lower bounds of 1.  */
- for (dim = 0; dim < e->rank; ++dim)
-   gfc_conv_shift_descriptor_lbound (&se.pre, desc,
- dim, gfc_index_one_node);
+ gfc_conv_shift_descriptor (&se.pre, desc, e->rank);
}
 
   /* If this is a subreference array pointer associate name use the


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Refactor conv_shift_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a6d12d1f09654a5d3038b6042e645dd9da4c84a5

commit a6d12d1f09654a5d3038b6042e645dd9da4c84a5
Author: Mikael Morin 
Date:   Thu Jan 16 15:28:38 2025 +0100

Refactor conv_shift_descriptor

Correction régressions

Correction régression gfc_conv_expr_descriptor

Diff:
---
 gcc/fortran/trans-array.cc | 31 +--
 gcc/fortran/trans-array.h  |  1 -
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ecdaad3f9575..bf11689cf3dd 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1165,16 +1165,15 @@ gfc_build_null_descriptor (tree type)
 /* Modify a descriptor such that the lbound of a given dimension is the value
specified.  This also updates ubound and offset accordingly.  */
 
-void
-gfc_conv_shift_descriptor_lbound (stmtblock_t* block, tree desc,
- int dim, tree new_lbound)
+static void
+conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, int dim,
+ tree new_lbound, tree offset)
 {
-  tree offs, ubound, lbound, stride;
+  tree ubound, lbound, stride;
   tree diff, offs_diff;
 
   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
 
-  offs = gfc_conv_descriptor_offset_get (desc);
   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
   ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
   stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
@@ -1190,9 +1189,9 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* block, 
tree desc,
   gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
   offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
   diff, stride);
-  offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
- offs, offs_diff);
-  gfc_conv_descriptor_offset_set (block, desc, offs);
+  tree tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ offset, offs_diff);
+  gfc_add_modify (block, offset, tmp);
 
   /* Finally set lbound to value we want.  */
   gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
@@ -1229,6 +1228,10 @@ static void
 conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
   const lb_info &info)
 {
+  tree tmp = gfc_conv_descriptor_offset_get (desc);
+  tree offset_var = gfc_create_var (TREE_TYPE (tmp), "offset");
+  gfc_add_modify (block, offset_var, tmp);
+
   /* Apply a shift of the lbound when supplied.  */
   for (int dim = 0; dim < rank; ++dim)
 {
@@ -1252,8 +1255,10 @@ conv_shift_descriptor (stmtblock_t *block, tree desc, 
int rank,
  lower_bound = lb_var;
}
 
-  gfc_conv_shift_descriptor_lbound (block, desc, dim, lower_bound);
+  conv_shift_descriptor_lbound (block, desc, dim, lower_bound, offset_var);
 }
+
+  gfc_conv_descriptor_offset_set (block, desc, offset_var);
 }
 
 
@@ -9225,7 +9230,6 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
   bool subref_array_target = false;
   bool deferred_array_component = false;
   bool substr = false;
-  bool unlimited_polymorphic = false;
   gfc_expr *arg, *ss_expr;
 
   if (se->want_coarray || expr->rank == 0)
@@ -9251,7 +9255,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
 }
 
   if (!se->direct_byref)
-unlimited_polymorphic = UNLIMITED_POLY (expr);
+se->unlimited_polymorphic = UNLIMITED_POLY (expr);
 
   /* Special case things we know we can pass easily.  */
   switch (expr->expr_type)
@@ -9655,9 +9659,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
  gfc_get_array_span (desc, expr)));
}
 
-
-  set_descriptor (&se->pre, parm, desc, expr, loop.dimen, codim,
- ss, info, loop.from, loop.to, unlimited_polymorphic,
+  set_descriptor (&loop.pre, parm, desc, expr, loop.dimen, codim,
+ ss, info, loop.from, loop.to, se->unlimited_polymorphic,
  !se->data_not_needed, subref_array_target);
 
   desc = parm;
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 378afb9617a3..3f39845c898f 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -214,7 +214,6 @@ tree gfc_get_cfi_dim_sm (tree, tree);
 
 
 /* Shift lower bound of descriptor, updating ubound and offset.  */
-void gfc_conv_shift_descriptor_lbound (stmtblock_t*, tree, int, tree);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, int);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree);


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation copie gfc_conv_expr_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:82413c99dc41ba8b632e751540ba26d97ea67ceb

commit 82413c99dc41ba8b632e751540ba26d97ea67ceb
Author: Mikael Morin 
Date:   Wed Jan 15 17:51:21 2025 +0100

Factorisation copie gfc_conv_expr_descriptor

Diff:
---
 gcc/fortran/trans-array.cc | 37 ++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 7d43a8c000d3..097a9a0d860a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8989,6 +8989,26 @@ is_explicit_coarray (gfc_expr *expr)
   return cas && cas->cotype == AS_EXPLICIT;
 }
 
+
+static void
+copy_descriptor (stmtblock_t *block, tree dest, tree src,
+gfc_expr *src_expr, bool subref)
+{
+  /* Copy the descriptor for pointer assignments.  */
+  gfc_add_modify (block, dest, src);
+
+  /* Add any offsets from subreferences.  */
+  gfc_get_dataptr_offset (block, dest, src, NULL_TREE, subref, src_expr);
+
+  /* and set the span field.  */
+  tree tmp;
+  if (src_expr->ts.type == BT_CHARACTER)
+tmp = gfc_conv_descriptor_span_get (src);
+  else
+tmp = gfc_get_array_span (src, src_expr);
+  gfc_conv_descriptor_span_set (block, dest, tmp);
+}
+
 /* Convert an array for passing as an actual argument.  Expressions and
vector subscripts are evaluated and stored in a temporary, which is then
passed.  For whole arrays the descriptor is passed.  For array sections
@@ -9123,21 +9143,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
   if (full && !transposed_dims (ss))
{
  if (se->direct_byref && !se->byref_noassign)
-   {
- /* Copy the descriptor for pointer assignments.  */
- gfc_add_modify (&se->pre, se->expr, desc);
-
- /* Add any offsets from subreferences.  */
- gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
- subref_array_target, expr);
-
- /* and set the span field.  */
- if (ss_info->expr->ts.type == BT_CHARACTER)
-   tmp = gfc_conv_descriptor_span_get (desc);
- else
-   tmp = gfc_get_array_span (desc, expr);
- gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
-   }
+   copy_descriptor (&se->pre, se->expr, desc, expr,
+subref_array_target);
  else if (se->want_pointer)
{
  /* We pass full arrays directly.  This means that pointers and


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation shift descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c2ce7393ce79293896ae05dcfff402ffea2c9176

commit c2ce7393ce79293896ae05dcfff402ffea2c9176
Author: Mikael Morin 
Date:   Tue Jan 21 22:27:02 2025 +0100

Factorisation shift descriptor

Diff:
---
 gcc/fortran/trans-array.cc | 117 -
 gcc/fortran/trans-array.h  |   1 +
 gcc/fortran/trans-expr.cc  |  82 ++-
 3 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b05f69fdd874..7afa29746e08 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1198,16 +1198,52 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree 
desc, int dim,
 }
 
 
-class lb_info
+class lb_info_base
 {
 public:
+  virtual tree lower_bound (stmtblock_t *block, int dim) const = 0;
+};
+
+
+class lb_info : public lb_info_base
+{
+public:
+  using lb_info_base::lower_bound;
   virtual gfc_expr *lower_bound (int dim) const = 0;
+  virtual tree lower_bound (stmtblock_t *block, int dim) const;
 };
 
 
+tree
+lb_info::lower_bound (stmtblock_t *block, int dim) const
+{
+  gfc_expr *lb_expr = lower_bound(dim);
+
+  if (lb_expr == nullptr)
+return gfc_index_one_node;
+  else
+{
+  gfc_se lb_se;
+
+  gfc_init_se (&lb_se, nullptr);
+  gfc_conv_expr (&lb_se, lb_expr);
+
+  gfc_add_block_to_block (block, &lb_se.pre);
+  tree lb_var = gfc_create_var (gfc_array_index_type, "lower_bound");
+  gfc_add_modify (block, lb_var,
+ fold_convert (gfc_array_index_type, lb_se.expr));
+  gfc_add_block_to_block (block, &lb_se.post);
+
+  return lb_var;
+}
+}
+
+
+
 class unset_lb : public lb_info
 {
 public:
+  using lb_info::lower_bound;
   virtual gfc_expr *lower_bound (int) const { return nullptr; }
 };
 
@@ -1218,6 +1254,7 @@ class defined_lb : public lb_info
   gfc_expr * const * lower_bounds;
 
 public:
+  using lb_info::lower_bound;
   defined_lb (int arg_rank, gfc_expr * const 
arg_lower_bounds[GFC_MAX_DIMENSIONS])
 : rank(arg_rank), lower_bounds(arg_lower_bounds) { }
   virtual gfc_expr *lower_bound (int dim) const { return lower_bounds[dim]; }
@@ -1226,7 +1263,7 @@ public:
 
 static void
 conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
-  const lb_info &info)
+  const lb_info_base &info)
 {
   tree tmp = gfc_conv_descriptor_offset_get (desc);
   tree offset_var = gfc_create_var (TREE_TYPE (tmp), "offset");
@@ -1235,26 +1272,7 @@ conv_shift_descriptor (stmtblock_t *block, tree desc, 
int rank,
   /* Apply a shift of the lbound when supplied.  */
   for (int dim = 0; dim < rank; ++dim)
 {
-  gfc_expr *lb_expr = info.lower_bound(dim);
-
-  tree lower_bound;
-  if (lb_expr == nullptr)
-   lower_bound = gfc_index_one_node;
-  else
-   {
- gfc_se lb_se;
-
- gfc_init_se (&lb_se, nullptr);
- gfc_conv_expr (&lb_se, lb_expr);
-
- gfc_add_block_to_block (block, &lb_se.pre);
- tree lb_var = gfc_create_var (TREE_TYPE (lb_se.expr), "lower_bound");
- gfc_add_modify (block, lb_var, lb_se.expr);
- gfc_add_block_to_block (block, &lb_se.post);
-
- lower_bound = lb_var;
-   }
-
+  tree lower_bound = info.lower_bound (block, dim);
   conv_shift_descriptor_lbound (block, desc, dim, lower_bound, offset_var);
 }
 
@@ -1337,6 +1355,61 @@ gfc_conv_shift_descriptor (stmtblock_t *block, tree desc,
 }
 
 
+class dataref_lb : public lb_info_base
+{
+  gfc_array_spec *as;
+  gfc_expr *conv_arg;
+  tree desc;
+
+public:
+  dataref_lb (gfc_array_spec *arg_as, gfc_expr *arg_conv_arg, tree arg_desc)
+: as(arg_as), conv_arg (arg_conv_arg), desc (arg_desc)
+  {}
+  virtual tree lower_bound (stmtblock_t *block, int dim) const;
+};
+
+
+tree
+dataref_lb::lower_bound (stmtblock_t *block, int dim) const
+{
+  tree lbound;
+  if (as && as->lower[dim])
+{
+  gfc_se lbse;
+  gfc_init_se (&lbse, NULL);
+  gfc_conv_expr (&lbse, as->lower[dim]);
+  gfc_add_block_to_block (block, &lbse.pre);
+  lbound = gfc_evaluate_now (lbse.expr, block);
+}
+  else if (as && conv_arg)
+{
+  tree tmp = gfc_get_symbol_decl (conv_arg->symtree->n.sym);
+  lbound = gfc_conv_descriptor_lbound_get (tmp, gfc_rank_cst[dim]);
+}
+  else if (as)
+lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
+  else
+lbound = gfc_index_one_node;
+
+  return fold_convert (gfc_array_index_type, lbound);
+}
+
+
+void
+gfc_conv_shift_descriptor_subarray (stmtblock_t *block, tree desc,
+   gfc_expr *value_expr, gfc_expr *conv_arg)
+{
+  /* Obtain the array spec of full array references.  */
+  gfc_array_spec *as;
+  if (conv_arg)
+as = gfc_get_full_arrayspec_from_expr (conv_arg);
+  else
+as = gfc_get_full_arrayspec_from_expr (value_expr);
+
+  conv_shift_descriptor (block, desc, value_expr->rank, dataref_lb (as, 
conv

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_contiguous_array

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b5834effc49cacae162a35ff2deafe3a9bbc9d1c

commit b5834effc49cacae162a35ff2deafe3a9bbc9d1c
Author: Mikael Morin 
Date:   Fri Jan 17 17:48:42 2025 +0100

Factorisation set_contiguous_array

Diff:
---
 gcc/fortran/trans-array.cc | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 76668d8a3ef1..88a2509a5246 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -11148,21 +11148,10 @@ structure_alloc_comps (gfc_symbol * der_type, tree 
decl, tree dest,
  cdesc = gfc_create_var (cdesc, "cdesc");
  DECL_ARTIFICIAL (cdesc) = 1;
 
- gfc_add_modify (&dealloc_block, gfc_conv_descriptor_dtype (cdesc),
- gfc_get_dtype_rank_type (1, tmp));
- gfc_conv_descriptor_lbound_set (&dealloc_block, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_stride_set (&dealloc_block, cdesc,
- gfc_index_zero_node,
- gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&dealloc_block, cdesc,
- gfc_index_zero_node, ubound);
-
  if (attr->dimension)
comp = gfc_conv_descriptor_data_get (comp);
 
- gfc_conv_descriptor_data_set (&dealloc_block, cdesc, comp);
+ set_contiguous_array (&dealloc_block, cdesc, ubound, comp);
 
  /* Now call the deallocator.  */
  vtab = gfc_find_vtab (&c->ts);


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation initialisation depuis cfi

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:1392f13442685eacd23ee09a10daccbaf00481ec

commit 1392f13442685eacd23ee09a10daccbaf00481ec
Author: Mikael Morin 
Date:   Fri Jan 24 16:01:58 2025 +0100

Factorisation initialisation depuis cfi

Correction régression contiguous-2.f90

Correction regression contiguous-2.f90

Correction régression bind-c-contiguous-1.f90

Diff:
---
 gcc/fortran/trans-decl.cc | 220 --
 gcc/fortran/trans-expr.cc | 209 ---
 gcc/fortran/trans.h   |   2 +
 3 files changed, 194 insertions(+), 237 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index dad15858fa6a..baa36e88bf15 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -7009,7 +7009,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
   stmtblock_t block;
   gfc_init_block (&block);
   tree cfi = build_fold_indirect_ref_loc (input_location, cfi_desc);
-  tree idx, etype, tmp, tmp2, size_var = NULL_TREE, rank = NULL_TREE;
+  tree idx, tmp, tmp2, size_var = NULL_TREE, rank = NULL_TREE;
   bool do_copy_inout = false;
 
   /* When allocatable + intent out, free the cfi descriptor.  */
@@ -7201,106 +7201,10 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
goto done;
 }
 
-  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
-{
-  /* gfc->dtype = ... (from declaration, not from cfi).  */
-  etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
-  gfc_add_modify (&block, gfc_conv_descriptor_dtype (gfc_desc),
- gfc_get_dtype_rank_type (sym->as->rank, etype));
-  /* gfc->data = cfi->base_addr. */
-  gfc_conv_descriptor_data_set (&block, gfc_desc,
-   gfc_get_cfi_desc_base_addr (cfi));
-}
-
-  if (sym->ts.type == BT_ASSUMED)
-{
-  /* For type(*), take elem_len + dtype.type from the actual argument.  */
-  gfc_add_modify (&block, gfc_conv_descriptor_elem_len (gfc_desc),
- gfc_get_cfi_desc_elem_len (cfi));
-  tree cond;
-  tree ctype = gfc_get_cfi_desc_type (cfi);
-  ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
-  ctype, build_int_cst (TREE_TYPE (ctype),
-CFI_type_mask));
-  tree type = gfc_conv_descriptor_type (gfc_desc);
-
-  /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
-  /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
- build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_VOID));
-  tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
- type,
- build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
-  tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
-  /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
- build_int_cst (TREE_TYPE (ctype),
-CFI_type_struct));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_DERIVED));
-  tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
-  /* if (CFI_type_Character) BT_CHARACTER else  < tmp2 >  */
-  /* Note: this is kind=1, CFI_type_ucs4_char is handled in the 'else if'
-before (see below, as generated bottom up).  */
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
- build_int_cst (TREE_TYPE (ctype),
- CFI_type_Character));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_CHARACTER));
-  tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
-  /* if (CFI_type_ucs4_char) BT_CHARACTER else  < tmp2 >  */
-  /* Note: gfc->elem_len = cfi->elem_len/4.  */
-  /* However, assuming that CFI_type_ucs4_char cannot be recovered, leave
-gfc->elem_len == cfi->elem_len, which helps with operations which use
-sizeof() in Fortran and cfi->elem_len in C.  */
-  tmp = gfc_get_cfi_desc_type (cfi);
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
- build_int_cst (TREE_TYPE (tmp),
- 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_descriptor_from_scalar conv_derived_to_class

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c3d8cf0e081de45c9a2f5d2d80ff8675f5e4614a

commit c3d8cf0e081de45c9a2f5d2d80ff8675f5e4614a
Author: Mikael Morin 
Date:   Wed Jan 29 18:22:29 2025 +0100

Factorisation set_descriptor_from_scalar conv_derived_to_class

Diff:
---
 gcc/fortran/trans-expr.cc | 42 +++---
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6afb344245f2..091e1417faed 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -174,7 +174,8 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol 
*sym, gfc_expr *expr)
 
 void
 set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
-   gfc_expr *scalar_expr)
+   gfc_expr *scalar_expr, bool is_class,
+   tree cond_optional)
 {
   tree type = get_scalar_to_descriptor_type (scalar,
 gfc_expr_attr (scalar_expr));
@@ -185,9 +186,22 @@ set_descriptor_from_scalar (stmtblock_t *block, tree desc, 
tree scalar,
   tree dtype_ref = gfc_conv_descriptor_dtype (desc);
   gfc_add_modify (block, dtype_ref, dtype_val);
 
-  tree tmp = gfc_class_data_get (scalar);
-  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
-tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+  tree tmp;
+  if (is_class)
+{
+  tmp = gfc_class_data_get (scalar);
+  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
+   tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+}
+  else if (cond_optional)
+{
+  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (scalar),
+   cond_optional, scalar,
+   fold_convert (TREE_TYPE (scalar),
+ null_pointer_node));
+}
+  else
+tmp = scalar;
 
   gfc_conv_descriptor_data_set (block, desc, tmp);
 }
@@ -1067,20 +1081,9 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
 
  /* Scalar to an assumed-rank array.  */
  if (fsym->ts.u.derived->components->as)
-   {
- tree type;
- type = get_scalar_to_descriptor_type (parmse->expr,
-   gfc_expr_attr (e));
- gfc_add_modify (&parmse->pre, gfc_conv_descriptor_dtype (ctree),
- gfc_get_dtype (type));
- if (optional)
-   parmse->expr = build3_loc (input_location, COND_EXPR,
-  TREE_TYPE (parmse->expr),
-  cond_optional, parmse->expr,
-  fold_convert (TREE_TYPE 
(parmse->expr),
-null_pointer_node));
- gfc_conv_descriptor_data_set (&parmse->pre, ctree, parmse->expr);
-   }
+   set_descriptor_from_scalar (&parmse->pre, ctree,
+   parmse->expr, e, false,
+   cond_optional);
   else
{
  tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
@@ -1455,7 +1458,8 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_typespec class_ts,
   && e->rank != class_ts.u.derived->components->as->rank)
 {
   if (e->rank == 0)
-   set_descriptor_from_scalar (&block, ctree, parmse->expr, e);
+   set_descriptor_from_scalar (&block, ctree, parmse->expr, e,
+   true, NULL_TREE);
   else
gfc_class_array_data_assign (&block, ctree, parmse->expr, false);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation initialisation gfc depuis cfi

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:57a9d2504fe45acda17cd2b7efa99495c276f4df

commit 57a9d2504fe45acda17cd2b7efa99495c276f4df
Author: Mikael Morin 
Date:   Thu Jan 23 20:46:59 2025 +0100

Factorisation initialisation gfc depuis cfi

Correction régression scalar descriptor

Diff:
---
 gcc/fortran/trans-expr.cc | 132 +-
 1 file changed, 72 insertions(+), 60 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6daa4a727f12..95b168fe76a8 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5936,6 +5936,75 @@ set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
 #endif
 
 
+static void
+set_gfc_from_cfi (stmtblock_t *block, tree gfc, tree cfi, tree rank,
+ gfc_symbol *c_sym)
+{
+  tree tmp = gfc_get_cfi_desc_base_addr (cfi);
+  gfc_conv_descriptor_data_set (block, gfc, tmp);
+
+  if (c_sym->attr.allocatable)
+{
+  /* gfc->span = cfi->elem_len.  */
+  tmp = fold_convert (gfc_array_index_type,
+ gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
+}
+  else
+{
+  /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
+ ? cfi->dim[0].sm : cfi->elem_len).  */
+  tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
+  tree tmp2 = fold_convert (gfc_array_index_type,
+   gfc_get_cfi_desc_elem_len (cfi));
+  tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
+gfc_array_index_type, tmp, tmp2);
+  tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+tmp, gfc_index_zero_node);
+  tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp,
+   gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]), tmp2);
+}
+  gfc_conv_descriptor_span_set (block, gfc, tmp);
+
+  /* Calculate offset + set lbound, ubound and stride.  */
+  gfc_conv_descriptor_offset_set (block, gfc, gfc_index_zero_node);
+  /* Loop: for (i = 0; i < rank; ++i).  */
+  tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
+  /* Loop body.  */
+  stmtblock_t loop_body;
+  gfc_init_block (&loop_body);
+  /* gfc->dim[i].lbound = ... */
+  tmp = gfc_get_cfi_dim_lbound (cfi, idx);
+  gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_lbound_get (gfc, idx),
+gfc_index_one_node);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+gfc_get_cfi_dim_extent (cfi, idx), tmp);
+  gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
+  tmp = gfc_get_cfi_dim_sm (cfi, idx);
+  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+gfc_array_index_type, tmp,
+fold_convert (gfc_array_index_type,
+  gfc_get_cfi_desc_elem_len (cfi)));
+  gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
+
+  /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_stride_get (gfc, idx),
+gfc_conv_descriptor_lbound_get (gfc, idx));
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_offset_get (gfc), tmp);
+  gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
+  /* Generate loop.  */
+  gfc_simple_for_loop (block, idx, build_int_cst (TREE_TYPE (idx), 0),
+  rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
+  gfc_finish_block (&loop_body));
+}
+
 /* Provide an interface between gfortran array descriptors and the F2018:18.4
ISO_Fortran_binding array descriptors. */
 
@@ -6315,8 +6384,10 @@ done:
 goto post_call;
 
   gfc_init_block (&block2);
+
   if (e->rank == 0)
 {
+  gfc_init_block (&block2);
   tmp = gfc_get_cfi_desc_base_addr (cfi);
   gfc_add_modify (&block, gfc, fold_convert (TREE_TYPE (gfc), tmp));
 }
@@ -6325,66 +6396,7 @@ done:
   tmp = gfc_get_cfi_desc_base_addr (cfi);
   gfc_conv_descriptor_data_set (&block, gfc, tmp);
 
-  if (fsym->attr.allocatable)
-   {
- /* gfc->span = cfi->elem_len.  */
- tmp = fold_convert (gfc_array_index_type,
- gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]));
-   }
-  else
-   {
- /* gfc->span = ((cfi->dim[0].sm % cfi->elem_len)
- ? cfi->dim[0].sm : cfi->elem_len).  */
- tmp = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
- tmp2 = fold_convert (gfc_array_index_type,
-  gfc_get_cfi_desc_elem_len (cfi

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] utilisation booléen allocatable

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:84be5a435f2a78f8a9ab0bdf5b693a1e0c6b6fd5

commit 84be5a435f2a78f8a9ab0bdf5b693a1e0c6b6fd5
Author: Mikael Morin 
Date:   Thu Jan 23 21:38:24 2025 +0100

utilisation booléen allocatable

Diff:
---
 gcc/fortran/trans-expr.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 95b168fe76a8..518a5a127cf0 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5938,12 +5938,12 @@ set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
 
 static void
 set_gfc_from_cfi (stmtblock_t *block, tree gfc, tree cfi, tree rank,
- gfc_symbol *c_sym)
+ bool allocatable)
 {
   tree tmp = gfc_get_cfi_desc_base_addr (cfi);
   gfc_conv_descriptor_data_set (block, gfc, tmp);
 
-  if (c_sym->attr.allocatable)
+  if (allocatable)
 {
   /* gfc->span = cfi->elem_len.  */
   tmp = fold_convert (gfc_array_index_type,
@@ -6396,7 +6396,7 @@ done:
   tmp = gfc_get_cfi_desc_base_addr (cfi);
   gfc_conv_descriptor_data_set (&block, gfc, tmp);
 
-  set_gfc_from_cfi (&block2, gfc, cfi, rank, fsym);
+  set_gfc_from_cfi (&block2, gfc, cfi, rank, fsym->attr.allocatable);
 }
 
   if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation initialisation subarray_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:41e38348a930505eacdc9386c9fce31a40bdbdb2

commit 41e38348a930505eacdc9386c9fce31a40bdbdb2
Author: Mikael Morin 
Date:   Tue Jan 21 18:44:41 2025 +0100

Factorisation initialisation subarray_descriptor

Diff:
---
 gcc/fortran/trans-expr.cc | 151 --
 1 file changed, 78 insertions(+), 73 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index b7d1e3df0613..65b6cd8a4642 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9418,17 +9418,90 @@ gfc_trans_subarray_assign (tree dest, gfc_component * 
cm, gfc_expr * expr)
 }
 
 
+static void
+set_subarray_descriptor (stmtblock_t *block, tree desc, tree value,
+gfc_expr *value_expr, gfc_expr *conv_arg)
+{
+  if (value_expr->expr_type != EXPR_VARIABLE)
+gfc_conv_descriptor_data_set (block, value,
+ null_pointer_node);
+
+  /* Obtain the array spec of full array references.  */
+  gfc_array_spec *as;
+  if (conv_arg)
+as = gfc_get_full_arrayspec_from_expr (conv_arg);
+  else
+as = gfc_get_full_arrayspec_from_expr (value_expr);
+
+  /* Shift the lbound and ubound of temporaries to being unity,
+ rather than zero, based. Always calculate the offset.  */
+  tree offset = gfc_conv_descriptor_offset_get (desc);
+  gfc_add_modify (block, offset, gfc_index_zero_node);
+  tree tmp2 = gfc_create_var (gfc_array_index_type, NULL);
+
+  for (int n = 0; n < value_expr->rank; n++)
+{
+  tree span;
+  tree lbound;
+
+  /* Obtain the correct lbound - ISO/IEC TR 15581:2001 page 9.
+TODO It looks as if gfc_conv_expr_descriptor should return
+the correct bounds and that the following should not be
+necessary.  This would simplify gfc_conv_intrinsic_bound
+as well.  */
+  if (as && as->lower[n])
+   {
+ gfc_se lbse;
+ gfc_init_se (&lbse, NULL);
+ gfc_conv_expr (&lbse, as->lower[n]);
+ gfc_add_block_to_block (block, &lbse.pre);
+ lbound = gfc_evaluate_now (lbse.expr, block);
+   }
+  else if (as && conv_arg)
+   {
+ tree tmp = gfc_get_symbol_decl (conv_arg->symtree->n.sym);
+ lbound = gfc_conv_descriptor_lbound_get (tmp,
+   gfc_rank_cst[n]);
+   }
+  else if (as)
+   lbound = gfc_conv_descriptor_lbound_get (desc,
+   gfc_rank_cst[n]);
+  else
+   lbound = gfc_index_one_node;
+
+  lbound = fold_convert (gfc_array_index_type, lbound);
+
+  /* Shift the bounds and set the offset accordingly.  */
+  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
+  span = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+   tmp, gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]));
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+span, lbound);
+  gfc_conv_descriptor_ubound_set (block, desc,
+ gfc_rank_cst[n], tmp);
+  gfc_conv_descriptor_lbound_set (block, desc,
+ gfc_rank_cst[n], lbound);
+
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+gfc_conv_descriptor_lbound_get (desc,
+gfc_rank_cst[n]),
+gfc_conv_descriptor_stride_get (desc,
+gfc_rank_cst[n]));
+  gfc_add_modify (block, tmp2, tmp);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+offset, tmp2);
+  gfc_conv_descriptor_offset_set (block, desc, tmp);
+}
+}
+
+
 static tree
 gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
 gfc_expr * expr)
 {
   gfc_se se;
   stmtblock_t block;
-  tree offset;
-  int n;
   tree tmp;
-  tree tmp2;
-  gfc_array_spec *as;
   gfc_expr *arg = NULL;
 
   gfc_start_block (&block);
@@ -9489,10 +9562,6 @@ gfc_trans_alloc_subarray_assign (tree dest, 
gfc_component * cm,
   gfc_add_expr_to_block (&block, tmp);
   gfc_add_block_to_block (&block, &se.post);
 
-  if (expr->expr_type != EXPR_VARIABLE)
-gfc_conv_descriptor_data_set (&block, se.expr,
- null_pointer_node);
-
   /* We need to know if the argument of a conversion function is a
  variable, so that the correct lower bound can be used.  */
   if (expr->expr_type == EXPR_FUNCTION
@@ -9502,71 +9571,7 @@ gfc_trans_alloc_subarray_assign (tree dest, 
gfc_component * cm,
&& expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
 arg = expr->value.function.actual->expr;
 
-  /* Obtain the array spec of full array references.  */
-  if (arg)
-as = gfc_get_full_arrayspec_from_expr (arg);
-  else
-a

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Introduction gfc_conv_descriptor_extent_get

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:55a2a1029553f80b56f5a8c5ef8a5935c0dd1088

commit 55a2a1029553f80b56f5a8c5ef8a5935c0dd1088
Author: Mikael Morin 
Date:   Wed Jan 22 19:02:13 2025 +0100

Introduction gfc_conv_descriptor_extent_get

Diff:
---
 gcc/fortran/trans-array.cc | 84 ++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  |  6 +---
 3 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 7afa29746e08..7357626be9a5 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -544,6 +544,51 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree 
desc,
 }
 
 
+/* Calculate the size of a given array dimension from the bounds.  This
+   is simply (ubound - lbound + 1) if this expression is positive
+   or 0 if it is negative (pick either one if it is zero).  Optionally
+   (if or_expr is present) OR the (expression != 0) condition to it.  */
+
+static tree
+conv_array_extent_dim (tree lbound, tree ubound, bool maybe_negative, tree* 
or_expr)
+{
+  tree res;
+  tree cond;
+
+  /* Calculate (ubound - lbound + 1).  */
+  res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ubound, lbound);
+  res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
+gfc_index_one_node);
+
+  /* Check whether the size for this dimension is negative.  */
+  if (maybe_negative)
+{
+  cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res,
+ gfc_index_zero_node);
+  res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, 
cond,
+gfc_index_zero_node, res);
+}
+
+  /* Build OR expression.  */
+  if (maybe_negative && or_expr)
+*or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
+   logical_type_node, *or_expr, cond);
+
+  return res;
+}
+
+
+tree
+gfc_conv_descriptor_extent_get (tree desc, tree dim)
+{
+  tree ubound = gfc_conv_descriptor_ubound_get (desc, dim);
+  tree lbound = gfc_conv_descriptor_lbound_get (desc, dim);
+
+  return conv_array_extent_dim (lbound, ubound, false, NULL);
+}
+
+
 static int
 get_type_info (const bt &type)
 {
@@ -7111,30 +7156,9 @@ gfc_set_delta (gfc_loopinfo *loop)
 tree
 gfc_conv_array_extent_dim (tree lbound, tree ubound, tree* or_expr)
 {
-  tree res;
-  tree cond;
-
-  /* Calculate (ubound - lbound + 1).  */
-  res = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-ubound, lbound);
-  res = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, res,
-gfc_index_one_node);
-
-  /* Check whether the size for this dimension is negative.  */
-  cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node, res,
- gfc_index_zero_node);
-  res = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
-gfc_index_zero_node, res);
-
-  /* Build OR expression.  */
-  if (or_expr)
-*or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
-   logical_type_node, *or_expr, cond);
-
-  return res;
+  return conv_array_extent_dim (lbound, ubound, true, or_expr);
 }
 
-
 /* For an array descriptor, get the total number of elements.  This is just
the product of the extents along from_dim to to_dim.  */
 
@@ -7148,14 +7172,7 @@ gfc_conv_descriptor_size_1 (tree desc, int from_dim, int 
to_dim)
 
   for (dim = from_dim; dim < to_dim; ++dim)
 {
-  tree lbound;
-  tree ubound;
-  tree extent;
-
-  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
-  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
-
-  extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+  tree extent = gfc_conv_descriptor_extent_get (desc, gfc_rank_cst[dim]);
   res = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
 res, extent);
 }
@@ -10543,12 +10560,7 @@ gfc_full_array_size (stmtblock_t *block, tree decl, 
int rank)
   tree nelems;
   tree tmp;
   idx = gfc_rank_cst[rank - 1];
-  nelems = gfc_conv_descriptor_ubound_get (decl, idx);
-  tmp = gfc_conv_descriptor_lbound_get (decl, idx);
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-nelems, tmp);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-tmp, gfc_index_one_node);
+  tmp = gfc_conv_descriptor_extent_get (decl, idx);
   tmp = gfc_evaluate_now (tmp, block);
 
   nelems = gfc_conv_descriptor_stride_get (decl, idx);
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index f9988a5fd109..1d694989b4c3 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -194,6 +194,7 @@ tree gfc_get_descriptor_

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Refactoring gfc_conv_descriptor_sm_get.

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:7d9a5b709d1f2400ea62c334bff7c9d4436a687c

commit 7d9a5b709d1f2400ea62c334bff7c9d4436a687c
Author: Mikael Morin 
Date:   Wed Jan 22 21:59:46 2025 +0100

Refactoring gfc_conv_descriptor_sm_get.

Diff:
---
 gcc/fortran/trans-array.cc | 11 +++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  |  4 +---
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 7357626be9a5..4d08a862c5be 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -589,6 +589,17 @@ gfc_conv_descriptor_extent_get (tree desc, tree dim)
 }
 
 
+tree
+gfc_conv_descriptor_sm_get (tree desc, tree dim)
+{
+  tree stride = gfc_conv_descriptor_stride_get (desc, dim);
+  tree span = gfc_conv_descriptor_span_get (desc);
+
+  return fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+ stride, span);
+}
+
+
 static int
 get_type_info (const bt &type)
 {
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 1d694989b4c3..296a8052dd73 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -195,6 +195,7 @@ tree gfc_conv_descriptor_stride_get (tree, tree);
 tree gfc_conv_descriptor_lbound_get (tree, tree);
 tree gfc_conv_descriptor_ubound_get (tree, tree);
 tree gfc_conv_descriptor_extent_get (tree, tree);
+tree gfc_conv_descriptor_sm_get (tree, tree);
 tree gfc_conv_descriptor_token (tree);
 
 void gfc_conv_descriptor_data_set (stmtblock_t *, tree, tree);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 84111f5e3d3d..6daa4a727f12 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6262,9 +6262,7 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr 
*e, gfc_symbol *fsym)
   tmp = gfc_conv_descriptor_extent_get (gfc, idx);
   gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
   /* d->dim[n].sm = gfc->dim[i].stride  * gfc->span); */
-  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-gfc_conv_descriptor_stride_get (gfc, idx),
-gfc_conv_descriptor_span_get (gfc));
+  tmp = gfc_conv_descriptor_sm_get (gfc, idx);
   gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
 
   /* Generate loop.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Sauvegarde factorisation set_descriptor_from_scalar

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:3e14437bb7d46a96bc507cbb41bd91e44b34ee77

commit 3e14437bb7d46a96bc507cbb41bd91e44b34ee77
Author: Mikael Morin 
Date:   Tue Feb 4 11:16:32 2025 +0100

Sauvegarde factorisation set_descriptor_from_scalar

Correction régression allocate_with_source_15.f03

Nettoyage correction

Correction régression allocate_with_mold_3

Correction allocate_with_source_16.f90

Correction régression assumed_rank_21.f90

Correction coarray_allocate_8.f08

Correction régression pr86470.f90

Correction régression dummy_3.f90

Diff:
---
 gcc/fortran/trans-array.cc | 204 +++--
 gcc/fortran/trans-array.h  |   2 +-
 gcc/fortran/trans-expr.cc  |  67 +--
 gcc/fortran/trans-types.cc |  47 +++
 gcc/fortran/trans-types.h  |   1 +
 gcc/fortran/trans.h|   1 +
 6 files changed, 218 insertions(+), 104 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index d6e7c9829ff2..90eafe7ffe18 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -92,6 +92,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "trans-array.h"
 #include "trans-const.h"
 #include "dependency.h"
+#include "gimplify.h"
 
 static bool gfc_get_array_constructor_size (mpz_t *, gfc_constructor_base);
 
@@ -600,7 +601,7 @@ gfc_conv_descriptor_sm_get (tree desc, tree dim)
 }
 
 
-static int
+static bt
 get_type_info (const bt &type)
 {
   switch (type)
@@ -611,11 +612,13 @@ get_type_info (const bt &type)
 case BT_COMPLEX:
 case BT_DERIVED:
 case BT_CHARACTER:
-case BT_CLASS:
 case BT_VOID:
 case BT_UNSIGNED:
   return type;
 
+case BT_CLASS:
+  return BT_DERIVED;
+
 case BT_PROCEDURE:
 case BT_ASSUMED:
   return BT_VOID;
@@ -672,9 +675,15 @@ get_size_info (gfc_typespec &ts)
 class modify_info
 {
 public:
+  virtual bool set_dtype () const { return is_initialization (); }
+  virtual bool use_tree_type () const { return false; }
   virtual bool is_initialization () const { return false; }
   virtual bool initialize_data () const { return false; }
+  virtual bool set_span () const { return false; }
+  virtual bool set_token () const { return true; }
   virtual tree get_data_value () const { return NULL_TREE; }
+  virtual bt get_type_type (const gfc_typespec &) const { return BT_UNKNOWN; }
+  virtual tree get_length (gfc_typespec *ts) const { return get_size_info 
(*ts); }
 };
 
 class nullification : public modify_info
@@ -698,8 +707,14 @@ class init_info : public modify_info
 public:
   virtual bool is_initialization () const { return true; }
   virtual gfc_typespec *get_type () const { return nullptr; }
+  virtual bt get_type_type (const gfc_typespec &) const;
 };
 
+bt
+init_info::get_type_type (const gfc_typespec & type_info) const
+{
+  return get_type_info (type_info.type);
+}
 
 class default_init : public init_info
 {
@@ -729,23 +744,103 @@ public:
   virtual gfc_typespec *get_type () const { return &ts; }
 };
 
-class scalar_value : public init_info
+
+class scalar_value : public modify_info
 {
 private:
-  gfc_typespec &ts;
+  bool initialisation;
+  gfc_typespec *ts;
   tree value;
+  bool use_tree_type_;
+  bool clear_token;
+  tree get_elt_type () const;
 
 public:
   scalar_value(gfc_typespec &arg_ts, tree arg_value)
-: ts(arg_ts), value(arg_value) { }
+: initialisation(true), ts(&arg_ts), value(arg_value), use_tree_type_ 
(false), clear_token(true) { }
+  scalar_value(tree arg_value)
+: initialisation(true), ts(nullptr), value(arg_value), use_tree_type_ 
(true), clear_token(false) { }
+  virtual bool is_initialization () const { return initialisation; }
   virtual bool initialize_data () const { return true; }
-  virtual tree get_data_value () const { return value; }
-  virtual gfc_typespec *get_type () const { return &ts; }
+  virtual tree get_data_value () const;
+  virtual gfc_typespec *get_type () const { return ts; }
+  virtual bool set_span () const { return true; }
+  virtual bool use_tree_type () const { return use_tree_type_; }
+  virtual bool set_token () const { return clear_token; }
+  virtual bt get_type_type (const gfc_typespec &) const;
+  virtual tree get_length (gfc_typespec *ts) const;
 };
 
 
+tree
+scalar_value::get_data_value () const
+{
+  if (POINTER_TYPE_P (TREE_TYPE (value)))
+return value;
+  else
+return gfc_build_addr_expr (NULL_TREE, value);
+}
+
+tree
+scalar_value::get_elt_type () const
+{
+  tree tmp = value;
+
+  if (POINTER_TYPE_P (TREE_TYPE (tmp)))
+tmp = TREE_TYPE (tmp);
+
+  tree etype = TREE_TYPE (tmp);
+
+  /* For arrays, which are not scalar coarrays.  */
+  if (TREE_CODE (etype) == ARRAY_TYPE && !TYPE_STRING_FLAG (etype))
+etype = TREE_TYPE (etype);
+
+  return etype;
+}
+
+bt
+scalar_value::get_type_type (const gfc_typespec & type_info) const
+{
+  bt n;
+  if (use_tree_type ())
+{
+  tree etype = get_elt_type ();
+  gf

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement gfc_copy_sequence_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f634a20a43b04a7f9993caa37af123d9a02ba7ff

commit f634a20a43b04a7f9993caa37af123d9a02ba7ff
Author: Mikael Morin 
Date:   Thu Jan 30 21:21:39 2025 +0100

Déplacement gfc_copy_sequence_descriptor

Correction erreur compil'

Diff:
---
 gcc/fortran/trans-array.cc | 64 ++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  | 64 --
 gcc/fortran/trans.h|  1 -
 4 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index a1fb41fc9354..455c9bcd76cc 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1835,6 +1835,70 @@ gfc_set_descriptor_from_scalar (stmtblock_t *block, tree 
desc, tree scalar,
   gfc_conv_descriptor_data_set (block, desc, tmp);
 }
 
+int
+gfc_descriptor_rank (tree descriptor)
+{
+  if (TREE_TYPE (descriptor) != NULL_TREE)
+return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
+
+  tree dim = gfc_get_descriptor_dimension (descriptor);
+  tree dim_type = TREE_TYPE (dim);
+  gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
+  tree idx_type = TYPE_DOMAIN (dim_type);
+  gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE);
+  gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type)));
+  tree idx_max = TYPE_MAX_VALUE (idx_type);
+  if (idx_max == NULL_TREE)
+return GFC_MAX_DIMENSIONS;
+  wide_int max = wi::to_wide (idx_max);
+  return max.to_shwi () + 1;
+}
+
+
+void
+gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc,
+ bool assumed_rank_lhs)
+{
+  int lhs_rank = gfc_descriptor_rank (lhs_desc);
+  int rhs_rank = gfc_descriptor_rank (rhs_desc);
+  tree desc;
+
+  if (assumed_rank_lhs || lhs_rank == rhs_rank)
+desc = rhs_desc;
+  else
+{
+  tree arr = gfc_create_var (TREE_TYPE (lhs_desc), "parm");
+  gfc_conv_descriptor_data_set (&block, arr,
+   gfc_conv_descriptor_data_get (rhs_desc));
+  gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node,
+ gfc_index_zero_node);
+  tree size = gfc_conv_descriptor_size (rhs_desc, rhs_rank);
+  gfc_conv_descriptor_ubound_set (&block, arr, gfc_index_zero_node, size);
+  gfc_conv_descriptor_stride_set (
+   &block, arr, gfc_index_zero_node,
+   gfc_conv_descriptor_stride_get (rhs_desc, gfc_index_zero_node));
+  for (int i = 1; i < lhs_rank; i++)
+   {
+ gfc_conv_descriptor_lbound_set (&block, arr, gfc_rank_cst[i],
+ gfc_index_zero_node);
+ gfc_conv_descriptor_ubound_set (&block, arr, gfc_rank_cst[i],
+ gfc_index_zero_node);
+ gfc_conv_descriptor_stride_set (&block, arr, gfc_rank_cst[i], size);
+   }
+  gfc_add_modify (&block, gfc_conv_descriptor_dtype (arr),
+ gfc_conv_descriptor_dtype (rhs_desc));
+  gfc_add_modify (&block, gfc_conv_descriptor_rank (arr),
+ build_int_cst (signed_char_type_node, lhs_rank));
+  gfc_conv_descriptor_span_set (&block, arr,
+   gfc_conv_descriptor_span_get (arr));
+  gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node);
+  desc = arr;
+}
+
+  gfc_class_array_data_assign (&block, lhs_desc, desc, true);
+}
+
+
 
 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
 
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 691231f66903..124020a53858 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -150,6 +150,7 @@ void gfc_set_descriptor_with_shape (stmtblock_t *, tree, 
tree,
 tree gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr);
 void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree,
 symbol_attribute, bool, tree);
+void gfc_copy_sequence_descriptor (stmtblock_t &, tree, tree, bool);
 
 /* Get a single array element.  */
 void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 2ece9d369d80..205c49949626 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -800,70 +800,6 @@ gfc_get_vptr_from_expr (tree expr)
 }
 
 
-int
-gfc_descriptor_rank (tree descriptor)
-{
-  if (TREE_TYPE (descriptor) != NULL_TREE)
-return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
-
-  tree dim = gfc_get_descriptor_dimension (descriptor);
-  tree dim_type = TREE_TYPE (dim);
-  gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
-  tree idx_type = TYPE_DOMAIN (dim_type);
-  gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE);
-  gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type)));
-  tree idx_max = TYPE_MAX_VALUE (idx_type);
-  if (idx_max == NULL_TREE)
-return GFC_MAX_DIMENSIONS;
-  wide_int max = wi::to_wide

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement gfc_set_gfc_from_cfi

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c980269c8043debd82e75a01b623d7279088402a

commit c980269c8043debd82e75a01b623d7279088402a
Author: Mikael Morin 
Date:   Thu Jan 30 21:27:40 2025 +0100

Déplacement gfc_set_gfc_from_cfi

Correction compil'

Diff:
---
 gcc/fortran/trans-array.cc | 258 +
 gcc/fortran/trans-array.h  |   3 +
 gcc/fortran/trans-expr.cc  | 218 --
 gcc/fortran/trans.h|   3 -
 4 files changed, 241 insertions(+), 241 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 455c9bcd76cc..d6e7c9829ff2 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1466,6 +1466,26 @@ gfc_conv_shift_descriptor_subarray (stmtblock_t *block, 
tree desc,
 }
 
 
+int
+gfc_descriptor_rank (tree descriptor)
+{
+  if (TREE_TYPE (descriptor) != NULL_TREE)
+return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
+
+  tree dim = gfc_get_descriptor_dimension (descriptor);
+  tree dim_type = TREE_TYPE (dim);
+  gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
+  tree idx_type = TYPE_DOMAIN (dim_type);
+  gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE);
+  gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type)));
+  tree idx_max = TYPE_MAX_VALUE (idx_type);
+  if (idx_max == NULL_TREE)
+return GFC_MAX_DIMENSIONS;
+  wide_int max = wi::to_wide (idx_max);
+  return max.to_shwi () + 1;
+}
+
+
 void
 gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src,
   int src_rank, const gfc_array_spec &as)
@@ -1835,26 +1855,6 @@ gfc_set_descriptor_from_scalar (stmtblock_t *block, tree 
desc, tree scalar,
   gfc_conv_descriptor_data_set (block, desc, tmp);
 }
 
-int
-gfc_descriptor_rank (tree descriptor)
-{
-  if (TREE_TYPE (descriptor) != NULL_TREE)
-return GFC_TYPE_ARRAY_RANK (TREE_TYPE (descriptor));
-
-  tree dim = gfc_get_descriptor_dimension (descriptor);
-  tree dim_type = TREE_TYPE (dim);
-  gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
-  tree idx_type = TYPE_DOMAIN (dim_type);
-  gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE);
-  gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type)));
-  tree idx_max = TYPE_MAX_VALUE (idx_type);
-  if (idx_max == NULL_TREE)
-return GFC_MAX_DIMENSIONS;
-  wide_int max = wi::to_wide (idx_max);
-  return max.to_shwi () + 1;
-}
-
-
 void
 gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc,
  bool assumed_rank_lhs)
@@ -1899,6 +1899,224 @@ gfc_copy_sequence_descriptor (stmtblock_t &block, tree 
lhs_desc, tree rhs_desc,
 }
 
 
+void
+gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
+ stmtblock_t *conditional_block, tree gfc, tree cfi,
+ tree rank, gfc_symbol *gfc_sym,
+ bool init_static, bool contiguous_gfc, bool 
contiguous_cfi)
+{
+  tree tmp = gfc_get_cfi_desc_base_addr (cfi);
+  gfc_conv_descriptor_data_set (unconditional_block, gfc, tmp);
+
+  if (init_static)
+{
+  /* gfc->dtype = ... (from declaration, not from cfi).  */
+  tree etype = gfc_get_element_type (TREE_TYPE (gfc));
+  gfc_add_modify (unconditional_block, gfc_conv_descriptor_dtype (gfc),
+ gfc_get_dtype_rank_type (gfc_sym->as->rank, etype));
+
+  if (gfc_sym->as->type == AS_ASSUMED_RANK)
+   gfc_add_modify (unconditional_block,
+   gfc_conv_descriptor_rank (gfc), rank);
+}
+
+  if (gfc_sym && gfc_sym->ts.type == BT_ASSUMED)
+{
+  /* For type(*), take elem_len + dtype.type from the actual argument.  */
+  gfc_add_modify (unconditional_block, gfc_conv_descriptor_elem_len (gfc),
+ gfc_get_cfi_desc_elem_len (cfi));
+  tree cond;
+  tree ctype = gfc_get_cfi_desc_type (cfi);
+  ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
+  ctype, build_int_cst (TREE_TYPE (ctype),
+CFI_type_mask));
+  tree type = gfc_conv_descriptor_type (gfc);
+
+  /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
+  /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
+  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
+ build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
+  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
+build_int_cst (TREE_TYPE (type), BT_VOID));
+  tree tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
+  type,
+  build_int_cst (TREE_TYPE (type), 
BT_UNKNOWN));
+  tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
+ tmp, tmp2);
+  /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
+  cond = fold_build2_loc (input_location, EQ_

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement méthode set_descriptor_from_scalar

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:9652121cbd1968be55401f85dab5b3bf5a178cdd

commit 9652121cbd1968be55401f85dab5b3bf5a178cdd
Author: Mikael Morin 
Date:   Thu Jan 30 21:07:15 2025 +0100

Déplacement méthode set_descriptor_from_scalar

Correction erreur compil'

Diff:
---
 gcc/fortran/trans-array.cc | 63 +++
 gcc/fortran/trans-array.h  |  3 ++
 gcc/fortran/trans-expr.cc  | 83 +-
 3 files changed, 75 insertions(+), 74 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4d08a862c5be..a1fb41fc9354 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1772,6 +1772,69 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree 
desc,
   gfc_conv_descriptor_offset_set (block, desc, offset);
 }
 
+/* Convert a scalar to an array descriptor. To be used for assumed-rank
+   arrays.  */
+
+tree
+gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
+{
+  enum gfc_array_kind akind;
+
+  if (attr.pointer)
+akind = GFC_ARRAY_POINTER_CONT;
+  else if (attr.allocatable)
+akind = GFC_ARRAY_ALLOCATABLE;
+  else
+akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
+
+  if (POINTER_TYPE_P (TREE_TYPE (scalar)))
+scalar = TREE_TYPE (scalar);
+  return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
+   akind, !(attr.pointer || attr.target));
+}
+
+
+void
+gfc_set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
+   symbol_attribute scalar_attr, bool is_class,
+   tree cond_optional)
+{
+  tree type = gfc_get_scalar_to_descriptor_type (scalar, scalar_attr);
+  if (POINTER_TYPE_P (type))
+type = TREE_TYPE (type);
+
+  tree etype = gfc_get_element_type (type);
+  tree dtype_val;
+  if (etype == void_type_node)
+dtype_val = gfc_get_dtype_rank_type (0, TREE_TYPE (scalar));
+  else
+dtype_val = gfc_get_dtype (type);
+
+  tree dtype_ref = gfc_conv_descriptor_dtype (desc);
+  gfc_add_modify (block, dtype_ref, dtype_val);
+
+  gfc_conv_descriptor_span_set (block, desc, integer_zero_node);
+
+  tree tmp;
+  if (is_class)
+tmp = gfc_class_data_get (scalar);
+  else
+tmp = scalar;
+
+  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
+tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+
+  if (cond_optional)
+{
+  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
+   cond_optional, tmp,
+   fold_convert (TREE_TYPE (scalar),
+ null_pointer_node));
+}
+
+  gfc_conv_descriptor_data_set (block, desc, tmp);
+}
+
 
 /* Obtain offsets for trans-types.cc(gfc_get_array_descr_info).  */
 
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 296a8052dd73..691231f66903 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -147,6 +147,9 @@ void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol 
*, gfc_expr *, tree);
 void gfc_set_scalar_descriptor (stmtblock_t *block, tree, gfc_symbol *, 
gfc_expr *, tree);
 void gfc_set_descriptor_with_shape (stmtblock_t *, tree, tree,
gfc_expr *, locus *);
+tree gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr);
+void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree,
+symbol_attribute, bool, tree);
 
 /* Get a single array element.  */
 void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 18d54d2a1f93..2ece9d369d80 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -83,34 +83,12 @@ gfc_get_character_len_in_bytes (tree type)
 }
 
 
-/* Convert a scalar to an array descriptor. To be used for assumed-rank
-   arrays.  */
-
-static tree
-get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
-{
-  enum gfc_array_kind akind;
-
-  if (attr.pointer)
-akind = GFC_ARRAY_POINTER_CONT;
-  else if (attr.allocatable)
-akind = GFC_ARRAY_ALLOCATABLE;
-  else
-akind = GFC_ARRAY_ASSUMED_SHAPE_CONT;
-
-  if (POINTER_TYPE_P (TREE_TYPE (scalar)))
-scalar = TREE_TYPE (scalar);
-  return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
-   akind, !(attr.pointer || attr.target));
-}
-
-
 tree
 gfc_conv_scalar_null_to_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr 
*expr, tree scalar)
 {
   symbol_attribute attr = sym->attr;
 
-  tree type = get_scalar_to_descriptor_type (scalar, attr);
+  tree type = gfc_get_scalar_to_descriptor_type (scalar, attr);
   tree desc = gfc_create_var (type, "desc");
   DECL_ARTIFICIAL (desc) = 1;
 
@@ -172,55 +150,12 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol 
*sym, gfc_expr *expr)
 }
 
 
-void
-set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
-

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Introduction getters et setters descriptor compil' OK

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:bed2485b5e68eb56ceaee133594eae256cbaf215

commit bed2485b5e68eb56ceaee133594eae256cbaf215
Author: Mikael Morin 
Date:   Mon Feb 10 19:24:59 2025 +0100

Introduction getters et setters descriptor compil' OK

Correction régression realloc on assign (associate_61, ...)

Correction régression assumed_rank_7.f90

Correction ICE coarray_42.f90

Diff:
---
 gcc/fortran/trans-array.cc | 817 +
 gcc/fortran/trans-array.h  |  26 +-
 gcc/fortran/trans-decl.cc  |   8 +-
 gcc/fortran/trans-expr.cc  |  66 ++--
 gcc/fortran/trans-intrinsic.cc |  61 ++-
 gcc/fortran/trans-openmp.cc|   2 +-
 gcc/fortran/trans-stmt.cc  |   7 +-
 gcc/fortran/trans.cc   |   7 +-
 8 files changed, 671 insertions(+), 323 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index e60204ae3ee2..7072927a30be 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -242,8 +242,15 @@ gfc_get_cfi_dim_sm (tree desc, tree idx)
 #define LBOUND_SUBFIELD 1
 #define UBOUND_SUBFIELD 2
 
-static tree
-gfc_get_descriptor_field (tree desc, unsigned field_idx)
+
+namespace gfc_descriptor
+{
+
+namespace
+{
+
+tree
+get_field (tree desc, unsigned field_idx)
 {
   tree type = TREE_TYPE (desc);
   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
@@ -251,111 +258,119 @@ gfc_get_descriptor_field (tree desc, unsigned field_idx)
   tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
   gcc_assert (field != NULL_TREE);
 
+  return field;
+}
+
+tree
+get_component (tree desc, unsigned field_idx)
+{
+  tree field = get_field (desc, field_idx);
+
   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
  desc, field, NULL_TREE);
 }
 
-/* This provides READ-ONLY access to the data field.  The field itself
-   doesn't have the proper type.  */
+tree
+get_data (tree desc)
+{
+  return get_component (desc, DATA_FIELD);
+}
 
 tree
-gfc_conv_descriptor_data_get (tree desc)
+conv_data_get (tree desc)
 {
   tree type = TREE_TYPE (desc);
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-gcc_unreachable ();
+  gcc_assert (TREE_CODE (type) != REFERENCE_TYPE);
 
-  tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
-  return fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), field);
+  tree field = get_data (desc);
+  tree t = fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), field);
+  return non_lvalue_loc (input_location, t);
 }
 
-/* This provides WRITE access to the data field.
-
-   TUPLES_P is true if we are generating tuples.
-
-   This function gets called through the following macros:
- gfc_conv_descriptor_data_set
- gfc_conv_descriptor_data_set.  */
-
 void
-gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
+conv_data_set (stmtblock_t *block, tree desc, tree value)
 {
-  tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
+  tree field = get_data (desc);
   gfc_add_modify (block, field, fold_convert (TREE_TYPE (field), value));
 }
 
-
-/* This provides address access to the data field.  This should only be
-   used by array allocation, passing this on to the runtime.  */
-
 tree
-gfc_conv_descriptor_data_addr (tree desc)
+conv_data_addr (tree desc)
 {
-  tree field = gfc_get_descriptor_field (desc, DATA_FIELD);
+  tree field = get_data (desc);
   return gfc_build_addr_expr (NULL_TREE, field);
 }
 
-static tree
-gfc_conv_descriptor_offset (tree desc)
+tree
+get_offset (tree desc)
 {
-  tree field = gfc_get_descriptor_field (desc, OFFSET_FIELD);
+  tree field = get_component (desc, OFFSET_FIELD);
   gcc_assert (TREE_TYPE (field) == gfc_array_index_type);
   return field;
 }
 
 tree
-gfc_conv_descriptor_offset_get (tree desc)
+conv_offset_get (tree desc)
 {
-  return gfc_conv_descriptor_offset (desc);
+  return non_lvalue_loc (input_location, get_offset (desc));
 }
 
 void
-gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
-   tree value)
+conv_offset_set (stmtblock_t *block, tree desc, tree value)
 {
-  tree t = gfc_conv_descriptor_offset (desc);
+  tree t = get_offset (desc);
   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
 }
 
-
 tree
-gfc_conv_descriptor_dtype (tree desc)
+get_dtype (tree desc)
 {
-  tree field = gfc_get_descriptor_field (desc, DTYPE_FIELD);
+  tree field = get_component (desc, DTYPE_FIELD);
   gcc_assert (TREE_TYPE (field) == get_dtype_type_node ());
   return field;
 }
 
-static tree
-gfc_conv_descriptor_span (tree desc)
+tree
+conv_dtype_get (tree desc)
+{
+  return non_lvalue_loc (input_location, get_dtype (desc));
+}
+
+void
+conv_dtype_set (stmtblock_t *block, tree desc, tree val)
+{
+  tree t = get_dtype (desc);
+  gfc_add_modify (block, t, val);
+}
+
+tree
+get_span (tree desc)
 {
-  tree field = gfc_get_descriptor_field (desc, SPAN_FIELD);
+  tree field = get_component (desc, SPAN_FIELD);
   gcc_assert (TREE_TYPE (field) == gfc_arra

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Mises à jour dumps

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:62bf6ea09a684d80ab4ac2b406ce62460d0425a1

commit 62bf6ea09a684d80ab4ac2b406ce62460d0425a1
Author: Mikael Morin 
Date:   Tue Feb 11 18:07:23 2025 +0100

Mises à jour dumps

Mise à jour dump bind-c-contiguous-2.f90

Mise à jour dumps coarray_poly_*.f90

Mise à jour dump coarray_lock_7.f90

Correction dump coarray_allocate_7.f08

Mise à jour dump coarray_lib_alloc_4.f90

Mise à jour dump coarray_lib_alloc_2.f90

Mise à jour dump coarray_lib_alloc_3.f90

Mise à jour dump coarray_lib_alloc_1.f90

Mise à jour dump coarray_lib_token_4.f90

Mise à jour dump coarray_lib_token_3.f90

Mise à jour dump coarray_lib_token_2.f90

Mise à jour dump contiguous_3.f90

Diff:
---
 gcc/testsuite/gfortran.dg/bind-c-contiguous-2.f90 | 12 ++--
 gcc/testsuite/gfortran.dg/coarray_allocate_7.f08  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_lib_alloc_1.f90 | 12 ++--
 gcc/testsuite/gfortran.dg/coarray_lib_alloc_2.f90 | 12 ++--
 gcc/testsuite/gfortran.dg/coarray_lib_alloc_3.f90 | 12 ++--
 gcc/testsuite/gfortran.dg/coarray_lib_alloc_4.f90 |  8 
 gcc/testsuite/gfortran.dg/coarray_lib_token_2.f90 |  4 ++--
 gcc/testsuite/gfortran.dg/coarray_lib_token_3.f90 |  4 ++--
 gcc/testsuite/gfortran.dg/coarray_lib_token_4.f90 |  6 +++---
 gcc/testsuite/gfortran.dg/coarray_lock_7.f90  | 12 ++--
 gcc/testsuite/gfortran.dg/coarray_poly_4.f90  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_5.f90  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_6.f90  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_7.f90  |  2 +-
 gcc/testsuite/gfortran.dg/coarray_poly_8.f90  |  2 +-
 gcc/testsuite/gfortran.dg/contiguous_3.f90|  4 ++--
 16 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/gcc/testsuite/gfortran.dg/bind-c-contiguous-2.f90 
b/gcc/testsuite/gfortran.dg/bind-c-contiguous-2.f90
index 5b546800e7ff..243c4a57cba4 100644
--- a/gcc/testsuite/gfortran.dg/bind-c-contiguous-2.f90
+++ b/gcc/testsuite/gfortran.dg/bind-c-contiguous-2.f90
@@ -60,12 +60,12 @@ end
 
 ! Copy in + out
 
-! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(\\(void \\*\\) 
xx->data \\+ xx->dtype.elem_len \\* arrayidx.\[0-9\]+, _xx->base_addr \\+ 
shift.\[0-9\]+, xx->dtype.elem_len\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times {__builtin_memcpy \(\(void \*\) xx->data 
\+ xx->dtype.elem_len \* arrayidx.[0-9]+, _xx->base_addr \+ shift.[0-9]+, 
(?:NON_LVALUE_EXPR <)?xx->dtype.elem_len>?\);} 1 "original" } }
 ! { dg-final { scan-tree-dump-times "xx->data = \\(void \\* restrict\\) 
_xx->base_addr;" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(\\(void \\*\\) 
xx->data \\+ xx->dtype.elem_len \\* arrayidx.\[0-9\]+, _xx->base_addr \\+ 
shift.\[0-9\]+, xx->dtype.elem_len\\);" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(\\(void \\*\\) 
yy->data \\+ yy->dtype.elem_len \\* arrayidx.\[0-9\]+, _yy->base_addr \\+ 
shift.\[0-9\]+, yy->dtype.elem_len\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times {__builtin_memcpy \(\(void \*\) xx->data 
\+ xx->dtype.elem_len \* arrayidx.[0-9]+, _xx->base_addr \+ shift.[0-9]+, 
(?:NON_LVALUE_EXPR <)?xx->dtype.elem_len>?\);} 1 "original" } }
+! { dg-final { scan-tree-dump-times {__builtin_memcpy \(\(void \*\) yy->data 
\+ yy->dtype.elem_len \* arrayidx.[0-9]+, _yy->base_addr \+ shift.[0-9]+, 
(?:NON_LVALUE_EXPR <)?yy->dtype.elem_len>?\);} 1 "original" } }
 ! { dg-final { scan-tree-dump-times "yy->data = \\(void \\* restrict\\) 
_yy->base_addr;" 1 "original" } }
-! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(_yy->base_addr \\+ 
shift.\[0-9\]+, \\(void \\*\\) yy->data \\+ yy->dtype.elem_len \\* 
arrayidx.\[0-9\]+, yy->dtype.elem_len\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times {__builtin_memcpy \(_yy->base_addr \+ 
shift.[0-9]+, \(void \*\) yy->data \+ yy->dtype.elem_len \* arrayidx.[0-9]+, 
(?:NON_LVALUE_EXPR <)?yy->dtype.elem_len>?\);} 1 "original" } }
 
 ! { dg-final { scan-tree-dump-times "zz = 
\\(character\\(kind=1\\)\\\[0:\\\]\\\[1:zz.\[0-9\]+\\\] \\* restrict\\) 
_zz->base_addr;" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(\\(void \\*\\) zz \\+ 
_zz->elem_len \\* arrayidx.\[0-9\]+, _zz->base_addr \\+ shift.\[0-9\]+, 
_zz->elem_len\\);" 1 "original" } }
@@ -73,10 +73,10 @@ end
 
 ! Copy in only
 
-! { dg-final { scan-tree-dump-times "__builtin_memcpy \\(\\(void \\*\\) 
aa->data \\+ aa->dtype.elem_len \\* arrayidx.\[0-9\]+, _aa->base_addr \\+ 
shift.\[0-9\]+, aa->dtype.elem_len\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times {__builtin_memcpy \(\(void \*\) aa->data 
\+ aa->dtype.elem_len \* arrayidx.[0-9]+, _aa->base_addr \+ shift.[0-9]+, 
(?:NON_LVALUE_EXPR <)?aa->dtype.elem_len>?\);} 1 "original" } }
 
 ! { dg-final { scan-tree-dump-times "aa->data = \\(void \\* restrict\\) 
_aa->base_addr;" 1 "original" } }

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation gfc_conv_shift_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c55b04c7f241e7439c0f49b1762f8ebdea663073

commit c55b04c7f241e7439c0f49b1762f8ebdea663073
Author: Mikael Morin 
Date:   Thu Feb 6 17:16:13 2025 +0100

Factorisation gfc_conv_shift_descriptor

Correction compil'

Correction régression allocated_4.f90

Factorisation gfc_conv_shift_descriptor.

Correction régression allocated_4.f90

Modifications mineures

Correction régression bound_10.f90

Correction régression alloc_comp_constructor_1.f90

Correction régression realloc_on_assign_10

Revert "Correction régression realloc_on_assign_10"

This reverts commit 007ca869933eb74b76398200ef0237219ba01cd8.

Correction régression realloc_on_assign_11.f90

Diff:
---
 gcc/fortran/trans-array.cc | 165 ++---
 gcc/fortran/trans-expr.cc  |  15 -
 2 files changed, 94 insertions(+), 86 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index c09b9bdab155..a33422efa55f 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1476,35 +1476,43 @@ gfc_build_null_descriptor (tree type)
specified.  This also updates ubound and offset accordingly.  */
 
 static void
-conv_shift_descriptor_lbound (stmtblock_t* block, tree desc, int dim,
- tree new_lbound, tree offset)
+conv_shift_descriptor_lbound (stmtblock_t* block, tree from_desc, tree 
to_desc, int dim,
+ tree new_lbound, tree offset, bool zero_based)
 {
-  tree ubound, lbound, stride;
-  tree diff, offs_diff;
-
   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
+  new_lbound = gfc_evaluate_now (new_lbound, block);
 
-  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[dim]);
-  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[dim]);
-  stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[dim]);
+  tree lbound = gfc_conv_descriptor_lbound_get (from_desc, gfc_rank_cst[dim]);
+  tree ubound = gfc_conv_descriptor_ubound_get (from_desc, gfc_rank_cst[dim]);
+  tree stride = gfc_conv_descriptor_stride_get (from_desc, gfc_rank_cst[dim]);
 
-  /* Get difference (new - old) by which to shift stuff.  */
-  diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
- new_lbound, lbound);
+  tree diff;
+  if (zero_based)
+diff = new_lbound;
+  else
+{
+  /* Get difference (new - old) by which to shift stuff.  */
+  diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+ new_lbound, lbound);
+  diff = gfc_evaluate_now (diff, block);
+}
 
   /* Shift ubound and offset accordingly.  This has to be done before
  updating the lbound, as they depend on the lbound expression!  */
-  ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-   ubound, diff);
-  gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
-  offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-  diff, stride);
-  tree tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
- offset, offs_diff);
-  gfc_add_modify (block, offset, tmp);
+  tree tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+  ubound, diff);
+  gfc_conv_descriptor_ubound_set (block, to_desc, gfc_rank_cst[dim], tmp1);
+  /* Set lbound to the value we want.  */
+  gfc_conv_descriptor_lbound_set (block, to_desc, gfc_rank_cst[dim], 
new_lbound);
 
-  /* Finally set lbound to value we want.  */
-  gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
+  tree offs_diff = fold_build2_loc (input_location, MULT_EXPR, 
gfc_array_index_type,
+   diff, stride);
+  tree tmp2 = fold_build2_loc (input_location, MINUS_EXPR, 
gfc_array_index_type,
+  offset, offs_diff);
+  gfc_add_modify (block, offset, tmp2);
+
+  if (from_desc != to_desc)
+gfc_conv_descriptor_stride_set (block, to_desc, gfc_rank_cst[dim], stride);
 }
 
 
@@ -1512,6 +1520,7 @@ class lb_info_base
 {
 public:
   virtual tree lower_bound (stmtblock_t *block, int dim) const = 0;
+  virtual bool zero_based_src () const { return false; }
 };
 
 
@@ -1572,21 +1581,64 @@ public:
 
 
 static void
-conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+conv_shift_descriptor (stmtblock_t *block, tree src, tree dest, int rank,
   const lb_info_base &info)
 {
-  tree tmp = gfc_conv_descriptor_offset_get (desc);
-  tree offset_var = gfc_create_var (TREE_TYPE (tmp), "offset");
-  gfc_add_modify (block, offset_var, tmp);
+  if (src != dest)
+{
+  tree tmp = gfc_conv_descriptor_data_get (src);
+  gfc_conv_descriptor_data_set (block, dest, tmp);
+}
+
+  tree offset_va

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_descriptor_dimension

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:bf057de23fdec616404bbe9ca73384463f5077c2

commit bf057de23fdec616404bbe9ca73384463f5077c2
Author: Mikael Morin 
Date:   Fri Feb 7 12:07:36 2025 +0100

Factorisation set_descriptor_dimension

Correction compil'

Diff:
---
 gcc/fortran/trans-array.cc | 82 +-
 1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index a33422efa55f..4d2d0378bea7 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1472,6 +1472,41 @@ gfc_build_null_descriptor (tree type)
 }
 
 
+static tree
+set_descriptor_dimension (stmtblock_t *block, tree desc, int dim,
+ tree lbound, tree ubound, tree stride, tree *offset)
+{
+  /* Set bounds in descriptor.  */
+  lbound = fold_convert (gfc_array_index_type, lbound);
+  lbound = gfc_evaluate_now (lbound, block);
+  gfc_conv_descriptor_lbound_set (block, desc,
+ gfc_rank_cst[dim], lbound);
+
+  ubound = fold_convert (gfc_array_index_type, ubound);
+  ubound = gfc_evaluate_now (ubound, block);
+  gfc_conv_descriptor_ubound_set (block, desc,
+ gfc_rank_cst[dim], ubound);
+
+  /* Set stride.  */
+  stride = fold_convert (gfc_array_index_type, stride);
+  stride = gfc_evaluate_now (stride, block);
+  gfc_conv_descriptor_stride_set (block, desc,
+ gfc_rank_cst[dim], stride);
+
+  /* Update offset.  */
+  tree tmp = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, lbound, stride);
+  *offset = fold_build2_loc (input_location, MINUS_EXPR,
+ gfc_array_index_type, *offset, tmp);
+
+  /* Return stride for next dimension.  */
+  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+  stride = fold_build2_loc (input_location, MULT_EXPR,
+   gfc_array_index_type, stride, tmp);
+  return stride;
+}
+
+
 /* Modify a descriptor such that the lbound of a given dimension is the value
specified.  This also updates ubound and offset accordingly.  */
 
@@ -1822,9 +1857,9 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, 
tree src,
 
   /* Copy offset but adjust it such that it would correspond
  to a lbound of zero.  */
+  tree offset;
   if (src_rank == -1)
-gfc_conv_descriptor_offset_set (block, dest,
-   gfc_index_zero_node);
+offset = gfc_index_zero_node;
   else
 {
   tree offs = gfc_conv_descriptor_offset_get (src);
@@ -1840,7 +1875,7 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, 
tree src,
  offs = fold_build2_loc (input_location, PLUS_EXPR,
  gfc_array_index_type, offs, tmp);
}
-  gfc_conv_descriptor_offset_set (block, dest, offs);
+  offset = offs;
 }
   /* Set the bounds as declared for the LHS and calculate strides as
  well as another offset update accordingly.  */
@@ -1856,46 +1891,17 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree 
dest, tree src,
   /* Convert declared bounds.  */
   gfc_init_se (&lower_se, NULL);
   gfc_init_se (&upper_se, NULL);
-  gfc_conv_expr (&lower_se, as.lower[dim]);
-  gfc_conv_expr (&upper_se, as.upper[dim]);
+  gfc_conv_expr_val (&lower_se, as.lower[dim]);
+  gfc_conv_expr_val (&upper_se, as.upper[dim]);
 
   gfc_add_block_to_block (block, &lower_se.pre);
   gfc_add_block_to_block (block, &upper_se.pre);
 
-  tree lbound = fold_convert (gfc_array_index_type, lower_se.expr);
-  tree ubound = fold_convert (gfc_array_index_type, upper_se.expr);
-
-  lbound = gfc_evaluate_now (lbound, block);
-  ubound = gfc_evaluate_now (ubound, block);
-
-  gfc_add_block_to_block (block, &lower_se.post);
-  gfc_add_block_to_block (block, &upper_se.post);
-
-  /* Set bounds in descriptor.  */
-  gfc_conv_descriptor_lbound_set (block, dest,
- gfc_rank_cst[dim], lbound);
-  gfc_conv_descriptor_ubound_set (block, dest,
- gfc_rank_cst[dim], ubound);
-
-  /* Set stride.  */
-  stride = gfc_evaluate_now (stride, block);
-  gfc_conv_descriptor_stride_set (block, dest,
- gfc_rank_cst[dim], stride);
-
-  /* Update offset.  */
-  tree offs = gfc_conv_descriptor_offset_get (dest);
-  tmp = fold_build2_loc (input_location, MULT_EXPR,
-gfc_array_index_type, lbound, stride);
-  offs = fold_build2_loc (input_location, MINUS_EXPR,
- gfc_array_index_type, offs, tmp);
-  offs = gfc_evaluate_now (offs, block);
-  gfc_conv_descriptor_offset_set (block, dest, offs);
-
-  /* Update stride.  */
-  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
-  stride = fold_build2_loc (input_location, MULT_EX

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set temporary descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:e6c9f7a5d3a273f68c14ce413067b11826a33adf

commit e6c9f7a5d3a273f68c14ce413067b11826a33adf
Author: Mikael Morin 
Date:   Wed Feb 12 18:17:41 2025 +0100

Factorisation set temporary descriptor

Suppression code redondant initialisation descriptor temporaire

Réduction différences

Correction régression class_transformational_2

Diff:
---
 gcc/fortran/trans-array.cc | 119 -
 1 file changed, 74 insertions(+), 45 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 051ccafe9807..ba040d25241d 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3294,13 +3294,14 @@ gfc_set_loop_bounds_from_array_spec 
(gfc_interface_mapping * mapping,
DYNAMIC is true if the caller may want to extend the array later
using realloc.  This prevents us from putting the array on the stack.  */
 
-static void
+static tree
 gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
  gfc_array_info * info, tree size, tree nelem,
  tree initial, bool dynamic, bool dealloc)
 {
   tree tmp;
   tree desc;
+  tree ptr = NULL_TREE;
   bool onstack;
 
   desc = info->descriptor;
@@ -3308,7 +3309,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   if (size == NULL_TREE || (dynamic && integer_zerop (size)))
 {
   /* A callee allocated array.  */
-  gfc_conv_descriptor_data_set (pre, desc, null_pointer_node);
+  ptr = null_pointer_node;
   onstack = false;
 }
   else
@@ -3336,8 +3337,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   fold_build1_loc (input_location,
DECL_EXPR, TREE_TYPE (tmp),
tmp));
- tmp = gfc_build_addr_expr (NULL_TREE, tmp);
- gfc_conv_descriptor_data_set (pre, desc, tmp);
+ ptr = gfc_build_addr_expr (NULL_TREE, tmp);
}
   else
{
@@ -3345,7 +3345,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
  if (initial == NULL_TREE)
{
  tmp = gfc_call_malloc (pre, NULL, size);
- tmp = gfc_evaluate_now (tmp, pre);
+ ptr = gfc_evaluate_now (tmp, pre);
}
  else
{
@@ -3388,18 +3388,12 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
  build_empty_stmt (input_location));
  gfc_add_expr_to_block (pre, tmp);
 
- tmp = fold_convert (pvoid_type_node, packed);
+ ptr = fold_convert (pvoid_type_node, packed);
}
-
- gfc_conv_descriptor_data_set (pre, desc, tmp);
}
 }
   info->data = gfc_conv_descriptor_data_get (desc);
 
-  /* The offset is zero because we create temporaries with a zero
- lower bound.  */
-  gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
-
   if (dealloc && !onstack)
 {
   /* Free the temporary.  */
@@ -3407,6 +3401,8 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, 
stmtblock_t * post,
   tmp = gfc_call_free (tmp);
   gfc_add_expr_to_block (post, tmp);
 }
+
+  return ptr;
 }
 
 
@@ -3618,6 +3614,61 @@ get_class_info_from_ss (stmtblock_t * pre, gfc_ss *ss, 
tree *eltype,
 }
 
 
+static void
+set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src,
+ tree elemsize, tree data_ptr,
+ tree ubound[GFC_MAX_DIMENSIONS],
+ tree stride[GFC_MAX_DIMENSIONS], int rank,
+ bool callee_allocated, bool rank_changer)
+{
+  int n;
+
+  if (!class_src)
+{
+  /* Fill in the array dtype.  */
+  gfc_conv_descriptor_dtype_set (block, desc,
+gfc_get_dtype (TREE_TYPE (desc)));
+}
+  else if (rank_changer)
+{
+  /* For classes, we copy the whole original class descriptor to the
+ temporary one, so we don't need to set the individual dtype fields.
+Except for the case of rank altering intrinsics for which we
+generate descriptors of different rank.  */
+
+  /* Take the dtype from the class expression.  */
+  tree src_data = gfc_class_data_get (class_src);
+  tree dtype = gfc_conv_descriptor_dtype_get (src_data);
+  gfc_conv_descriptor_dtype_set (block, desc, dtype);
+
+  /* These transformational functions change the rank.  */
+  gfc_conv_descriptor_rank_set (block, desc, rank);
+}
+
+  if (!callee_allocated)
+{
+  for (n = 0; n < rank; n++)
+   {
+ /* Store the stride and bound components in the descriptor.  */
+ gfc_conv_descriptor_stride_set (block, desc, gfc_rank_cst[n],
+ stride[n]);
+
+ 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_descriptor_from_scalar dans conv_class_to_class

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:60fb6b7d916d2d309ca305c8848baefe06ae06c6

commit 60fb6b7d916d2d309ca305c8848baefe06ae06c6
Author: Mikael Morin 
Date:   Tue Jan 28 21:03:24 2025 +0100

Factorisation set_descriptor_from_scalar dans conv_class_to_class

Correction régression associate_66

Correction régression PR100040.f90

Diff:
---
 gcc/fortran/trans-expr.cc | 34 ++
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index a5cd0a452d81..6afb344245f2 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -172,6 +172,27 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol 
*sym, gfc_expr *expr)
 }
 
 
+void
+set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
+   gfc_expr *scalar_expr)
+{
+  tree type = get_scalar_to_descriptor_type (scalar,
+gfc_expr_attr (scalar_expr));
+  if (POINTER_TYPE_P (type))
+type = TREE_TYPE (type);
+
+  tree dtype_val = gfc_get_dtype (type);
+  tree dtype_ref = gfc_conv_descriptor_dtype (desc);
+  gfc_add_modify (block, dtype_ref, dtype_val);
+
+  tree tmp = gfc_class_data_get (scalar);
+  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
+tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+
+  gfc_conv_descriptor_data_set (block, desc, tmp);
+}
+
+
 tree
 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
 {
@@ -1434,18 +1455,7 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_typespec class_ts,
   && e->rank != class_ts.u.derived->components->as->rank)
 {
   if (e->rank == 0)
-   {
- tree type = get_scalar_to_descriptor_type (parmse->expr,
-gfc_expr_attr (e));
- gfc_add_modify (&block, gfc_conv_descriptor_dtype (ctree),
- gfc_get_dtype (type));
-
- tmp = gfc_class_data_get (parmse->expr);
- if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
-   tmp = gfc_build_addr_expr (NULL_TREE, tmp);
-
- gfc_conv_descriptor_data_set (&block, ctree, tmp);
-   }
+   set_descriptor_from_scalar (&block, ctree, parmse->expr, e);
   else
gfc_class_array_data_assign (&block, ctree, parmse->expr, false);
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_descriptor_dimension

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ddb31d5d6926f57296dc9514c6cd17227eaba66f

commit ddb31d5d6926f57296dc9514c6cd17227eaba66f
Author: Mikael Morin 
Date:   Thu Feb 13 20:26:47 2025 +0100

Factorisation set_descriptor_dimension

Correction typo

Diff:
---
 gcc/fortran/trans-array.cc | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ba040d25241d..3bfe41c64013 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1904,6 +1904,9 @@ set_bounds_update_offset (stmtblock_t *block, tree desc, 
int dim,
 gfc_conv_descriptor_stride_set (block, desc,
gfc_rank_cst[dim], stride);
 
+  if (!offset && !next_stride)
+return;
+
   /* Update offset.  */
   tree tmp = fold_build2_loc (input_location, MULT_EXPR,
  gfc_array_index_type, lbound_diff, stride);
@@ -3650,13 +3653,8 @@ set_temporary_descriptor (stmtblock_t *block, tree desc, 
tree class_src,
   for (n = 0; n < rank; n++)
{
  /* Store the stride and bound components in the descriptor.  */
- gfc_conv_descriptor_stride_set (block, desc, gfc_rank_cst[n],
- stride[n]);
-
- gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[n],
- gfc_index_zero_node);
-
- gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[n], 
ubound[n]);
+ set_descriptor_dimension (block, desc, n, gfc_index_zero_node, 
ubound[n],
+   stride[n], nullptr, nullptr);
}
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation shift_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:9a83288a7a4b4eed3b7c32271842013f9748d143

commit 9a83288a7a4b4eed3b7c32271842013f9748d143
Author: Mikael Morin 
Date:   Thu Feb 13 21:03:54 2025 +0100

Factorisation shift_descriptor

Diff:
---
 gcc/fortran/trans-expr.cc | 76 ---
 1 file changed, 39 insertions(+), 37 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 6ed87fc63a9b..016ac2ee944c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5207,6 +5207,43 @@ gfc_apply_interface_mapping (gfc_interface_mapping * 
mapping,
 }
 
 
+static void
+shift_descriptor (stmtblock_t *block, tree desc, int rank,
+ tree lbound[GFC_MAX_DIMENSIONS],
+ tree ubound[GFC_MAX_DIMENSIONS])
+
+{
+  tree size = gfc_index_one_node;
+  tree offset = gfc_index_zero_node;
+  for (int n = 0; n < rank; n++)
+{
+  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, tmp,
+gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ tmp);
+  gfc_conv_descriptor_lbound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ gfc_index_one_node);
+  size = gfc_evaluate_now (size, block);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type,
+   offset, size);
+  offset = gfc_evaluate_now (offset, block);
+  tmp = gfc_conv_array_extent_dim (lbound[n], ubound[n], nullptr);
+  size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, size, tmp);
+}
+
+  gfc_conv_descriptor_offset_set (block, desc,
+ offset);
+}
+
+
 /* Returns a reference to a temporary array into which a component of
an actual argument derived type array is copied and then returned
after the function call.  */
@@ -5227,7 +5264,6 @@ gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, 
int g77,
   tree tmp_index;
   tree tmp;
   tree base_type;
-  tree size;
   stmtblock_t body;
   int n;
   int dimen;
@@ -5471,42 +5507,8 @@ class_array_fcn:
   /* Determine the offset for pointer formal arguments and set the
  lbounds to one.  */
   if (formal_ptr)
-{
-  size = gfc_index_one_node;
-  offset = gfc_index_zero_node;
-  for (n = 0; n < dimen; n++)
-   {
- tmp = gfc_conv_descriptor_ubound_get (parmse->expr,
-   gfc_rank_cst[n]);
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type, tmp,
-gfc_index_one_node);
- gfc_conv_descriptor_ubound_set (&parmse->pre,
- parmse->expr,
- gfc_rank_cst[n],
- tmp);
- gfc_conv_descriptor_lbound_set (&parmse->pre,
- parmse->expr,
- gfc_rank_cst[n],
- gfc_index_one_node);
- size = gfc_evaluate_now (size, &parmse->pre);
- offset = fold_build2_loc (input_location, MINUS_EXPR,
-   gfc_array_index_type,
-   offset, size);
- offset = gfc_evaluate_now (offset, &parmse->pre);
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-rse.loop->to[n], rse.loop->from[n]);
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type,
-tmp, gfc_index_one_node);
- size = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, size, tmp);
-   }
-
-  gfc_conv_descriptor_offset_set (&parmse->pre, parmse->expr,
- offset);
-}
+shift_descriptor (&parmse->pre, parmse->expr, dimen,
+ rse.loop->from, rse.loop->to);
 
   /* We want either the address for the data or the address of the descriptor,
  depending on the mode of passing array arguments.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation set_descriptor_from_scalar dans gfc_conv_scalar_to_descriptor

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:468055f1d8a69b5b86fa7d661811bcd6263dbb51

commit 468055f1d8a69b5b86fa7d661811bcd6263dbb51
Author: Mikael Morin 
Date:   Wed Jan 29 19:05:04 2025 +0100

Factorisation set_descriptor_from_scalar dans gfc_conv_scalar_to_descriptor

Correction régression pr49213.f90

Correction régression associated_assumed_rank.f90

Suppression code redondant

Diff:
---
 gcc/fortran/trans-expr.cc | 59 ---
 1 file changed, 30 insertions(+), 29 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 091e1417faed..18d54d2a1f93 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -174,46 +174,53 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol 
*sym, gfc_expr *expr)
 
 void
 set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
-   gfc_expr *scalar_expr, bool is_class,
+   symbol_attribute scalar_attr, bool is_class,
tree cond_optional)
 {
-  tree type = get_scalar_to_descriptor_type (scalar,
-gfc_expr_attr (scalar_expr));
+  tree type = get_scalar_to_descriptor_type (scalar, scalar_attr);
   if (POINTER_TYPE_P (type))
 type = TREE_TYPE (type);
 
-  tree dtype_val = gfc_get_dtype (type);
+  tree etype = gfc_get_element_type (type);
+  tree dtype_val;
+  if (etype == void_type_node)
+dtype_val = gfc_get_dtype_rank_type (0, TREE_TYPE (scalar));
+  else
+dtype_val = gfc_get_dtype (type);
+
   tree dtype_ref = gfc_conv_descriptor_dtype (desc);
   gfc_add_modify (block, dtype_ref, dtype_val);
 
+  gfc_conv_descriptor_span_set (block, desc, integer_zero_node);
+
   tree tmp;
   if (is_class)
+tmp = gfc_class_data_get (scalar);
+  else
+tmp = scalar;
+
+  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
+tmp = gfc_build_addr_expr (NULL_TREE, tmp);
+
+  if (cond_optional)
 {
-  tmp = gfc_class_data_get (scalar);
-  if (!POINTER_TYPE_P (TREE_TYPE (tmp)))
-   tmp = gfc_build_addr_expr (NULL_TREE, tmp);
-}
-  else if (cond_optional)
-{
-  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (scalar),
-   cond_optional, scalar,
+  tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
+   cond_optional, tmp,
fold_convert (TREE_TYPE (scalar),
  null_pointer_node));
 }
-  else
-tmp = scalar;
 
   gfc_conv_descriptor_data_set (block, desc, tmp);
 }
 
 
+
 tree
 gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
 {
-  tree desc, type, etype;
+  tree desc, type;
 
   type = get_scalar_to_descriptor_type (scalar, attr);
-  etype = TREE_TYPE (scalar);
   desc = gfc_create_var (type, "desc");
   DECL_ARTIFICIAL (desc) = 1;
 
@@ -224,15 +231,9 @@ gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, 
symbol_attribute attr)
   gfc_add_modify (&se->pre, tmp, scalar);
   scalar = tmp;
 }
-  if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
-scalar = gfc_build_addr_expr (NULL_TREE, scalar);
-  else if (TREE_TYPE (etype) && TREE_CODE (TREE_TYPE (etype)) == ARRAY_TYPE)
-etype = TREE_TYPE (etype);
-  gfc_add_modify (&se->pre, gfc_conv_descriptor_dtype (desc),
- gfc_get_dtype_rank_type (0, etype));
-  gfc_conv_descriptor_data_set (&se->pre, desc, scalar);
-  gfc_conv_descriptor_span_set (&se->pre, desc,
-   gfc_conv_descriptor_elem_len (desc));
+
+  set_descriptor_from_scalar (&se->pre, desc, scalar, attr,
+ false, NULL_TREE);
 
   /* Copy pointer address back - but only if it could have changed and
  if the actual argument is a pointer and not, e.g., NULL().  */
@@ -1082,8 +1083,8 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
  /* Scalar to an assumed-rank array.  */
  if (fsym->ts.u.derived->components->as)
set_descriptor_from_scalar (&parmse->pre, ctree,
-   parmse->expr, e, false,
-   cond_optional);
+   parmse->expr, gfc_expr_attr (e),
+   false, cond_optional);
   else
{
  tmp = fold_convert (TREE_TYPE (ctree), parmse->expr);
@@ -1458,8 +1459,8 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_typespec class_ts,
   && e->rank != class_ts.u.derived->components->as->rank)
 {
   if (e->rank == 0)
-   set_descriptor_from_scalar (&block, ctree, parmse->expr, e,
-   true, NULL_TREE);
+   set_descriptor_from_scalar (&block, ctree, parmse->expr,
+   gfc_expr_attr (e), true, NULL_TREE);
   else
gfc_class_array_data_assign (&block, ctree, parmse->expr, false);
 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] match: Unwrap non-lvalue as unary or binary operand

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ab0d39c3b07ee84a26feed2a5a5fac92233073aa

commit ab0d39c3b07ee84a26feed2a5a5fac92233073aa
Author: Mikael Morin 
Date:   Thu Jul 4 15:24:36 2024 +0200

match: Unwrap non-lvalue as unary or binary operand

This avoids most of the testsuite dump pattern updates with a patch
generating more NON_LVALUE_EXPR trees that I plan to post later.

Regression tested on x86_64-linux.  OK for master?

-- 8< --

gcc/ChangeLog:

* match.pd (`op (non_lvalue X) Y`, `op X (non_lvalue Y)`,
`op (non_lvalue X)`): New simplifications, unwrap NON_LVALUE_EXPR
trees when they are used as operand of a unary or binary operator.

gcc/testsuite/ChangeLog:

* gfortran.dg/non_lvalue_2.f90: New test.

Diff:
---
 gcc/match.pd   | 12 
 gcc/testsuite/gfortran.dg/non_lvalue_2.f90 | 44 ++
 2 files changed, 56 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index 5e6bb8945e8b..85b4e8013783 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -281,6 +281,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(outer_op @0 @2)
@3))
 
+/* Remove superfluous NON_LVALUE_EXPR in unary operators.  */
+(for op (UNCOND_UNARY)
+ (simplify (op (non_lvalue @0))
+  (op @0)))
+
+/* Remove superfluous NON_LVALUE_EXPR in binary operators.  */
+(for op (UNCOND_BINARY tcc_comparison)
+ (simplify (op (non_lvalue @0) @1)
+  (op @0 @1))
+ (simplify (op @0 (non_lvalue @1))
+  (op @0 @1)))
+
 /* Simplify x - x.
This is unsafe for certain floats even in non-IEEE formats.
In IEEE, it is unsafe because it does wrong for NaNs.
diff --git a/gcc/testsuite/gfortran.dg/non_lvalue_2.f90 
b/gcc/testsuite/gfortran.dg/non_lvalue_2.f90
new file mode 100644
index ..8c3197eab1f0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/non_lvalue_2.f90
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! Check the removal of NON_LVALUE_EXPR if they are used in a non-lvalue context
+
+! The NON_LVALUE_EXPR is dropped if it's part (left operand) of a bigger 
expression
+function f1 (f1_arg1, f1_arg2)
+  integer, value :: f1_arg1, f1_arg2
+  integer :: f1
+  f1 = (f1_arg1 + 0) + f1_arg2
+end function
+! { dg-final { scan-tree-dump "__result_f1 = f1_arg1 \\+ f1_arg2;" "original" 
} }
+
+! The NON_LVALUE_EXPR is dropped if it's part (right operand) of a bigger 
expression
+function f2 (f2_arg1, f2_arg2)
+  integer, value :: f2_arg1, f2_arg2
+  integer :: f2
+  f2 = f2_arg1 + (f2_arg2 + 0)
+end function
+! { dg-final { scan-tree-dump "__result_f2 = f2_arg1 \\+ f2_arg2;" "original" 
} }
+
+! The NON_LVALUE_EXPR is dropped if it's part (left operand) of a binary 
logical operator
+function f3 (f3_arg1)
+  integer, value :: f3_arg1
+  logical :: f3
+  f3 = (f3_arg1 + 0) > 0
+end function
+! { dg-final { scan-tree-dump "__result_f3 = f3_arg1 > 0;" "original" } }
+
+! The NON_LVALUE_EXPR is dropped if it's part (right operand) of a binary 
logical operator
+function f4 (f4_arg1, f4_arg2)
+  integer, value :: f4_arg1, f4_arg2
+  logical :: f4
+  f4 = f4_arg1 > (f4_arg2 + 0)
+end function
+! { dg-final { scan-tree-dump "__result_f4 = f4_arg1 > f4_arg2;" "original" } }
+
+! The NON_LVALUE_EXPR is dropped if it's part of a unary operator
+function f5 (f5_arg1)
+  integer, value :: f5_arg1
+  integer :: f5
+  f5 = -(not(not(f5_arg1)))
+end function
+! { dg-final { scan-tree-dump "__result_f5 = -f5_arg1;" "original" } }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] match: Simplify double not and double negate to a non_lvalue

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:6c677650e4960d95c4e5f6495249108bcfaf4107

commit 6c677650e4960d95c4e5f6495249108bcfaf4107
Author: Mikael Morin 
Date:   Thu Jul 4 12:59:34 2024 +0200

match: Simplify double not and double negate to a non_lvalue

I noticed while testing the second patch that none of the NON_LVALUE_EXPR
trees I expected were generated when simplifying unary operators, whereas
they were generated with binary operators.

Regression tested on x86_64-linux.  OK for master?

-- 8< --

gcc/ChangeLog:

* match.pd (`-(-X)`, `~(~X)`): Add a NON_LVALUE_EXPR wrapper to the
simplification of doubled unary operators NEGATE_EXPR and
BIT_NOT_EXPR.

gcc/testsuite/ChangeLog:

* gfortran.dg/non_lvalue_1.f90: New test.

Diff:
---
 gcc/match.pd   |  4 ++--
 gcc/testsuite/gfortran.dg/non_lvalue_1.f90 | 21 +
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 171930874988..5e6bb8945e8b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2318,7 +2318,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* ~~x -> x */
 (simplify
   (bit_not (bit_not @0))
-  @0)
+  (non_lvalue @0))
 
 /* zero_one_valued_p will match when a value is known to be either
0 or 1 including constants 0 or 1.
@@ -3930,7 +3930,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (negate (nop_convert? (negate @1)))
   (if (!TYPE_OVERFLOW_SANITIZED (type)
&& !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1)))
-   (view_convert @1)))
+   (non_lvalue (view_convert @1
 
  /* We can't reassociate floating-point unless -fassociative-math
 or fixed-point plus or minus because of saturation to +-Inf.  */
diff --git a/gcc/testsuite/gfortran.dg/non_lvalue_1.f90 
b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90
new file mode 100644
index ..ac52b2720945
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/non_lvalue_1.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! Check the generation of NON_LVALUE_EXPR trees in cases where a unary 
operator expression
+! simplifies to a data reference.
+
+! A NON_LVALUE_EXPR is generated for a double negation that simplifies to a 
data reference.  */
+function f1 (f1_arg1)
+  integer, value :: f1_arg1
+  integer :: f1
+  f1 = -(-f1_arg1)
+end function
+! { dg-final { scan-tree-dump "__result_f1 = NON_LVALUE_EXPR ;" 
"original" } }
+
+! A NON_LVALUE_EXPR is generated for a double complement that simplifies to a 
data reference.  */
+function f2 (f2_arg1)
+  integer, value :: f2_arg1
+  integer :: f2
+  f2 = not(not(f2_arg1))
+end function
+! { dg-final { scan-tree-dump "__result_f2 = NON_LVALUE_EXPR ;" 
"original" } }


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

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a6c99173bb640f2af17d64ed1cd4ee00ae2146b1

commit a6c99173bb640f2af17d64ed1cd4ee00ae2146b1
Author: Mikael Morin 
Date:   Wed Feb 12 10:07:40 2025 +0100

Correction non_lvalue PR97046.f90

Diff:
---
 gcc/fortran/trans-array.cc | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 7072927a30be..19c6768cc66e 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2556,24 +2556,31 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
   tree tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, 
cond,
   gfc_finish_block (&set_void),
   gfc_finish_block (&set_unknown));
+
   /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
  build_int_cst (TREE_TYPE (ctype),
 CFI_type_struct));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_DERIVED));
+  stmtblock_t set_derived;
+  gfc_init_block (&set_derived);
+  tree derived_value = build_int_cst (TREE_TYPE (type), BT_DERIVED);
+  gfc_conv_descriptor_type_set (&set_derived, gfc, derived_value);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
+ gfc_finish_block (&set_derived), tmp2);
+
   /* if (CFI_type_Character) BT_CHARACTER else  < tmp2 >  */
   /* Note: this is kind=1, CFI_type_ucs4_char is handled in the 'else if'
 before (see below, as generated bottom up).  */
   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
  build_int_cst (TREE_TYPE (ctype),
  CFI_type_Character));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+  stmtblock_t set_character;
+  gfc_init_block (&set_character);
+  tree character_value = build_int_cst (TREE_TYPE (type), BT_CHARACTER);
+  gfc_conv_descriptor_type_set (&set_character, gfc, character_value);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
+ gfc_finish_block (&set_character), tmp2);
+
   /* if (CFI_type_ucs4_char) BT_CHARACTER else  < tmp2 >  */
   /* Note: gfc->elem_len = cfi->elem_len/4.  */
   /* However, assuming that CFI_type_ucs4_char cannot be recovered, leave
@@ -2583,18 +2590,22 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
  build_int_cst (TREE_TYPE (tmp),
 CFI_type_ucs4_char));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+  gfc_init_block (&set_character);
+  gfc_conv_descriptor_type_set (&set_character, gfc, character_value);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
+ gfc_finish_block (&set_character), tmp2);
+
   /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else  < tmp2 >  */
   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
  build_int_cst (TREE_TYPE (ctype),
  CFI_type_Complex));
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-build_int_cst (TREE_TYPE (type), BT_COMPLEX));
+  stmtblock_t set_complex;
+  gfc_init_block (&set_complex);
+  tree complex_value = build_int_cst (TREE_TYPE (type), BT_COMPLEX);
+  gfc_conv_descriptor_type_set (&set_complex, gfc, complex_value);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
- tmp, tmp2);
+ gfc_finish_block (&set_complex), tmp2);
+
   /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
   ctype else*/
   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
@@ -2610,10 +2621,11 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
 CFI_type_Real));
   cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
  cond, tmp);
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
- 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction erreurs non-lvalue lhs pr113363.f90

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a6b20dd1bd5b8669a2a496045c6f1970df5c7472

commit a6b20dd1bd5b8669a2a496045c6f1970df5c7472
Author: Mikael Morin 
Date:   Wed Feb 12 10:47:31 2025 +0100

Correction erreurs non-lvalue lhs pr113363.f90

Diff:
---
 gcc/fortran/trans-decl.cc | 21 +
 gcc/fortran/trans.cc  |  4 ++--
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 450a30871577..b3ebc056e4cf 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5113,10 +5113,23 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, 
gfc_wrapped_block * block)
  if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
{
  /* Nullify when entering the scope.  */
- tmp = fold_build2_loc (input_location, MODIFY_EXPR,
-TREE_TYPE (se.expr), se.expr,
-fold_convert (TREE_TYPE (se.expr),
-  null_pointer_node));
+ if (sym->ts.type == BT_CLASS
+ && (CLASS_DATA (sym)->attr.dimension
+ || CLASS_DATA (sym)->attr.codimension))
+   {
+ stmtblock_t nullify;
+ gfc_init_block (&nullify);
+ gfc_conv_descriptor_data_set (&nullify, descriptor,
+   null_pointer_node);
+ tmp = gfc_finish_block (&nullify);
+   }
+ else
+   {
+ tmp = fold_build2_loc (input_location, MODIFY_EXPR,
+TREE_TYPE (se.expr), se.expr,
+fold_convert (TREE_TYPE 
(se.expr),
+  
null_pointer_node));
+   }
  if (sym->attr.optional)
{
  tree present = gfc_conv_expr_present (sym);
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index e7cccb6b0bca..f0ad42c92ead 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -1737,7 +1737,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
 gfc_call_free (data_ptr),
 build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->loop->post, tmp);
-  gfc_add_modify (&se->loop->post, data_ptr, data_null);
+  gfc_conv_descriptor_data_set (&se->loop->post, desc, data_null);
 }
   else
 {
@@ -1751,7 +1751,7 @@ gfc_finalize_tree_expr (gfc_se *se, gfc_symbol *derived,
 gfc_call_free (data_ptr),
 build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->finalblock, tmp);
- gfc_add_modify (&se->finalblock, data_ptr, data_null);
+ gfc_conv_descriptor_data_set (&se->finalblock, desc, data_null);
}
 }
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation initialisation dimension descripteur

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:ded0b8188e80164e73fef5b8f3051ec2e7f36eb1

commit ded0b8188e80164e73fef5b8f3051ec2e7f36eb1
Author: Mikael Morin 
Date:   Sat Feb 8 21:37:49 2025 +0100

Factorisation initialisation dimension descripteur

Correction régression realloc_on_assign_12.f90

Diff:
---
 gcc/fortran/trans-array.cc | 87 +-
 1 file changed, 48 insertions(+), 39 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4d2d0378bea7..e60204ae3ee2 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1472,38 +1472,56 @@ gfc_build_null_descriptor (tree type)
 }
 
 
-static tree
-set_descriptor_dimension (stmtblock_t *block, tree desc, int dim,
- tree lbound, tree ubound, tree stride, tree *offset)
+static void
+set_bounds_update_offset (stmtblock_t *block, tree desc, int dim,
+ tree lbound, tree ubound, tree stride, tree 
lbound_diff,
+ tree *offset, tree *next_stride, bool 
stride_unchanged)
 {
-  /* Set bounds in descriptor.  */
+  /* Stabilize values in case the expressions depend on the existing bounds.  
*/
   lbound = fold_convert (gfc_array_index_type, lbound);
   lbound = gfc_evaluate_now (lbound, block);
-  gfc_conv_descriptor_lbound_set (block, desc,
- gfc_rank_cst[dim], lbound);
 
   ubound = fold_convert (gfc_array_index_type, ubound);
   ubound = gfc_evaluate_now (ubound, block);
-  gfc_conv_descriptor_ubound_set (block, desc,
- gfc_rank_cst[dim], ubound);
 
-  /* Set stride.  */
   stride = fold_convert (gfc_array_index_type, stride);
   stride = gfc_evaluate_now (stride, block);
-  gfc_conv_descriptor_stride_set (block, desc,
- gfc_rank_cst[dim], stride);
+
+  lbound_diff = fold_convert (gfc_array_index_type, lbound_diff);
+  lbound_diff = gfc_evaluate_now (lbound_diff, block);
+
+  gfc_conv_descriptor_lbound_set (block, desc,
+ gfc_rank_cst[dim], lbound);
+  gfc_conv_descriptor_ubound_set (block, desc,
+ gfc_rank_cst[dim], ubound);
+  if (!stride_unchanged)
+gfc_conv_descriptor_stride_set (block, desc,
+   gfc_rank_cst[dim], stride);
 
   /* Update offset.  */
   tree tmp = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, lbound, stride);
-  *offset = fold_build2_loc (input_location, MINUS_EXPR,
- gfc_array_index_type, *offset, tmp);
+ gfc_array_index_type, lbound_diff, stride);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR,
+gfc_array_index_type, *offset, tmp);
+  *offset = gfc_evaluate_now (tmp, block);
+
+  if (!next_stride)
+return;
 
-  /* Return stride for next dimension.  */
+  /* Set stride for next dimension.  */
   tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
-  stride = fold_build2_loc (input_location, MULT_EXPR,
-   gfc_array_index_type, stride, tmp);
-  return stride;
+  *next_stride = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, stride, tmp);
+}
+
+
+static void
+set_descriptor_dimension (stmtblock_t *block, tree desc, int dim,
+ tree lbound, tree ubound, tree stride, tree *offset,
+ tree *next_stride)
+{
+  set_bounds_update_offset (block, desc, dim, lbound, ubound, stride, lbound,
+   offset, next_stride, false);
 }
 
 
@@ -1512,7 +1530,7 @@ set_descriptor_dimension (stmtblock_t *block, tree desc, 
int dim,
 
 static void
 conv_shift_descriptor_lbound (stmtblock_t* block, tree from_desc, tree 
to_desc, int dim,
- tree new_lbound, tree offset, bool zero_based)
+ tree new_lbound, tree *offset, bool zero_based)
 {
   new_lbound = fold_convert (gfc_array_index_type, new_lbound);
   new_lbound = gfc_evaluate_now (new_lbound, block);
@@ -1536,18 +1554,9 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree 
from_desc, tree to_desc,
  updating the lbound, as they depend on the lbound expression!  */
   tree tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
   ubound, diff);
-  gfc_conv_descriptor_ubound_set (block, to_desc, gfc_rank_cst[dim], tmp1);
-  /* Set lbound to the value we want.  */
-  gfc_conv_descriptor_lbound_set (block, to_desc, gfc_rank_cst[dim], 
new_lbound);
 
-  tree offs_diff = fold_build2_loc (input_location, MULT_EXPR, 
gfc_array_index_type,
-   diff, stride);
-  tree tmp2 = fold_build2_loc (input_location, MINUS_EXPR, 
gfc_array_index_type,
-  offset, offs_diff);
-  gfc_add_modify (block, offset, tmp2);
-
-  if (from_desc != to_desc)
-

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Renseignement token par gfc_set_descriptor_from_scalar.

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d2722a02e8d2f2eada5abd697282e3a51327c285

commit d2722a02e8d2f2eada5abd697282e3a51327c285
Author: Mikael Morin 
Date:   Wed Feb 5 15:12:25 2025 +0100

Renseignement token par gfc_set_descriptor_from_scalar.

Diff:
---
 gcc/fortran/trans-array.cc | 27 ---
 gcc/fortran/trans-array.h  |  2 +-
 gcc/fortran/trans-expr.cc  | 15 +++
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 531281049646..c09b9bdab155 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -682,6 +682,7 @@ public:
   virtual bool set_span () const { return false; }
   virtual bool set_token () const { return true; }
   virtual tree get_data_value () const { return NULL_TREE; }
+  virtual tree get_caf_token () const { return null_pointer_node; }
   virtual bt get_type_type (const gfc_typespec &) const { return BT_UNKNOWN; }
   virtual tree get_length (gfc_typespec *ts) const { return get_size_info 
(*ts); }
 };
@@ -751,22 +752,24 @@ private:
   bool initialisation;
   gfc_typespec *ts;
   tree value;
+  tree caf_token;
   bool use_tree_type_;
   bool clear_token;
   tree get_elt_type () const;
 
 public:
   scalar_value(gfc_typespec &arg_ts, tree arg_value)
-: initialisation(true), ts(&arg_ts), value(arg_value), use_tree_type_ 
(false), clear_token(true) { }
-  scalar_value(tree arg_value)
-: initialisation(true), ts(nullptr), value(arg_value), use_tree_type_ 
(true), clear_token(false) { }
+: initialisation(true), ts(&arg_ts), value(arg_value), caf_token 
(NULL_TREE),  use_tree_type_ (false), clear_token(true) { }
+  scalar_value(tree arg_value, tree arg_caf_token)
+: initialisation(true), ts(nullptr), value(arg_value), caf_token 
(arg_caf_token), use_tree_type_ (true), clear_token(false) { }
   virtual bool is_initialization () const { return initialisation; }
   virtual bool initialize_data () const { return true; }
   virtual tree get_data_value () const;
   virtual gfc_typespec *get_type () const { return ts; }
   virtual bool set_span () const { return true; }
   virtual bool use_tree_type () const { return use_tree_type_; }
-  virtual bool set_token () const { return clear_token; }
+  virtual bool set_token () const { return clear_token || caf_token != 
NULL_TREE; }
+  virtual tree get_caf_token () const;
   virtual bt get_type_type (const gfc_typespec &) const;
   virtual tree get_length (gfc_typespec *ts) const;
 };
@@ -838,6 +841,16 @@ scalar_value::get_length (gfc_typespec * type_info) const
   return size;
 }
 
+tree
+scalar_value::get_caf_token () const
+{
+  if (set_token ()
+  && caf_token != NULL_TREE)
+return caf_token;
+  else
+return modify_info::get_caf_token ();
+}
+
 
 static tree
 build_dtype (gfc_typespec *ts, int rank, const symbol_attribute &,
@@ -933,7 +946,7 @@ get_descriptor_init (tree type, gfc_typespec *ts, int rank,
   tree token_field = gfc_advance_chain (fields,
CAF_TOKEN_FIELD - (!dim_present));
   tree token_value = fold_convert (TREE_TYPE (token_field),
-  null_pointer_node);
+  init.get_caf_token ());
   CONSTRUCTOR_APPEND_ELT (v, token_field, token_value);
 }
 
@@ -1430,11 +1443,11 @@ gfc_set_scalar_descriptor (stmtblock_t *block, tree 
descriptor,
 
 void
 gfc_set_descriptor_from_scalar (stmtblock_t *block, tree desc, tree scalar,
-   symbol_attribute *attr)
+   symbol_attribute *attr, tree caf_token)
 {
   init_struct (block, desc,
   get_descriptor_init (TREE_TYPE (desc), nullptr, 0, attr,
-   scalar_value (scalar)));
+   scalar_value (scalar, caf_token)));
 }
 
 
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 97cf7f8cb41f..2dad79aa9993 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -149,7 +149,7 @@ void gfc_set_descriptor_with_shape (stmtblock_t *, tree, 
tree,
gfc_expr *, locus *);
 tree gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr);
 void gfc_set_descriptor_from_scalar (stmtblock_t *, tree, tree,
-symbol_attribute *);
+symbol_attribute *, tree = NULL_TREE);
 void gfc_copy_sequence_descriptor (stmtblock_t &, tree, tree, bool);
 void gfc_set_gfc_from_cfi (stmtblock_t *, stmtblock_t *, tree, tree, tree,
   gfc_symbol *, bool, bool, bool);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 39bd7178c3c0..13a1ec1e8fe3 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -883,14 +883,20 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, 
gfc_symbol *fsym,
   /* Now set the data field.  */
   ctree = gfc_

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Interdiction non-lvalue as lhs

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:749c1436aba9cf3b6876fa8f31aac82af8329c64

commit 749c1436aba9cf3b6876fa8f31aac82af8329c64
Author: Mikael Morin 
Date:   Tue Feb 11 21:34:11 2025 +0100

Interdiction non-lvalue as lhs

git commit correction erreur gimplify

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

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 58a9d2a748d6..73f558eb634e 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -6838,6 +6838,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
  || TREE_CODE (*expr_p) == INIT_EXPR);
 
+  if (TREE_CODE (*to_p) == NON_LVALUE_EXPR)
+{
+  error ("non-lvalue used as lhs in %qD", *expr_p);
+  return GS_ERROR;
+}
+
   /* Trying to simplify a clobber using normal logic doesn't work,
  so handle it here.  */
   if (TREE_CLOBBER_P (*from_p))


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] réduction différences dump assumed_rank_12.f90

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:79734111aa08107a2cafd5bdb5744fa5cef5aa92

commit 79734111aa08107a2cafd5bdb5744fa5cef5aa92
Author: Mikael Morin 
Date:   Wed Feb 5 11:45:00 2025 +0100

réduction différences dump assumed_rank_12.f90

Diff:
---
 gcc/fortran/trans-array.cc | 126 -
 1 file changed, 124 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 90eafe7ffe18..531281049646 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1085,11 +1085,131 @@ field_count (tree type)
 }
 
 
-bool
+#if 0
+static bool
 complete_init_p (tree type, vec *init_values)
 {
   return (unsigned) field_count (type) == vec_safe_length (init_values);
 }
+#endif
+
+
+static int
+cmp_wi (const void *x, const void *y)
+{
+  const offset_int *wix = (const offset_int *) x;
+  const offset_int *wiy = (const offset_int *) y;
+
+  return wi::cmpu (*wix, *wiy);
+}
+
+
+static offset_int
+get_offset_bits (tree field)
+{
+  offset_int field_offset = wi::to_offset (DECL_FIELD_OFFSET (field));
+  offset_int field_bit_offset = wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
+  unsigned long offset_align = DECL_OFFSET_ALIGN (field);
+
+  return field_offset * offset_align + field_bit_offset;
+}
+
+
+static bool
+check_cleared_low_bits (const offset_int &val, int bitcount)
+{
+  if (bitcount == 0)
+return true;
+
+  offset_int mask = wi::mask  (bitcount, false);
+  if ((val & mask) != 0)
+return false;
+
+  return true;
+}
+
+
+static bool
+right_shift_if_clear (const offset_int &val, int bitcount, offset_int *result)
+{
+  if (bitcount == 0)
+{
+  *result = val;
+  return true;
+}
+
+  if (!check_cleared_low_bits (val, bitcount))
+return false;
+
+  *result = val >> bitcount;
+  return true;
+}
+
+
+static bool
+contiguous_init_p (tree type, tree value)
+{
+  gcc_assert (TREE_CODE (value) == CONSTRUCTOR);
+  auto_vec field_offsets;
+  int count = field_count (type);
+  field_offsets.reserve (count);
+
+  tree field = TYPE_FIELDS (type);
+  offset_int expected_offset = 0;
+  while (field != NULL_TREE)
+{
+  offset_int field_offset_bits = get_offset_bits (field);
+  offset_int field_offset;
+  if (!right_shift_if_clear (field_offset_bits, 3, &field_offset))
+   return false;
+
+  offset_int type_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE 
(field)));
+  int align = wi::ctz (type_size);
+  if (!check_cleared_low_bits (field_offset, align))
+   return false;
+
+  if (field_offset != expected_offset)
+   return false;
+
+  expected_offset += type_size;
+  field_offsets.quick_push (field_offset);
+
+  field = DECL_CHAIN (field);
+}
+
+  auto_vec value_offsets;
+  value_offsets.reserve (count);
+
+  unsigned i;
+  tree field_init;
+  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (value), i, field, field_init)
+{
+  if (TREE_TYPE (field) != TREE_TYPE (field_init))
+   return false;
+
+  offset_int field_offset_bits = get_offset_bits (field);
+  offset_int field_offset;
+  if (!right_shift_if_clear (field_offset_bits, 3, &field_offset))
+   return false;
+
+  value_offsets.quick_push (field_offset);
+}
+
+  value_offsets.qsort (cmp_wi);
+
+  unsigned idx = 0;
+  offset_int field_off, val_off;
+  while (field_offsets.iterate (idx, &field_off)
+&& value_offsets.iterate (idx, &val_off))
+{
+  if (val_off != field_off)
+   return false;
+
+  idx++;
+}
+
+  return true;
+}
 
 
 static bool
@@ -1161,7 +1281,9 @@ init_struct (stmtblock_t *block, tree data_ref, init_kind 
kind,
   if (TREE_STATIC (data_ref)
  || !modifiable_p (data_ref))
DECL_INITIAL (data_ref) = value;
-  else if (TREE_CODE (value) == CONSTRUCTOR)
+  else if (TREE_CODE (value) == CONSTRUCTOR
+  && !(TREE_CONSTANT (value)
+   && contiguous_init_p (type, value)))
{
  unsigned i;
  tree field, field_init;


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Update dump match count

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:123a4927b085ed0044f4ef885726f4ab3f2aaa84

commit 123a4927b085ed0044f4ef885726f4ab3f2aaa84
Author: Mikael Morin 
Date:   Thu Jan 30 16:53:48 2025 +0100

Update dump match count

Diff:
---
 gcc/testsuite/gfortran.dg/coarray_collectives_18.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90 
b/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90
index c83899de0e5b..a1f2a76ff73e 100644
--- a/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_collectives_18.f90
@@ -33,5 +33,5 @@ end program
 ! This lead to access to non exsitant memory in opencoarrays.
 ! In single image mode just checking for reduced number of
 ! descriptors is possible, i.e., execute always works.
-! { dg-final { scan-tree-dump-times "desc\\.\[0-9\]+" 12 "original" } }
+! { dg-final { scan-tree-dump-times "desc\\.\[0-9\]+" 10 "original" } }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Séparation motifs dump assumed_rank_12.f90

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:d57bd41920599b47a05068e6a78fbc44d786e441

commit d57bd41920599b47a05068e6a78fbc44d786e441
Author: Mikael Morin 
Date:   Wed Feb 5 11:57:09 2025 +0100

Séparation motifs dump assumed_rank_12.f90

Diff:
---
 gcc/testsuite/gfortran.dg/assumed_rank_12.f90 | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/assumed_rank_12.f90 
b/gcc/testsuite/gfortran.dg/assumed_rank_12.f90
index 873498f82d76..cacfb7ed52af 100644
--- a/gcc/testsuite/gfortran.dg/assumed_rank_12.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_rank_12.f90
@@ -16,5 +16,9 @@ function f() result(res)
 end function f
 end
 
-! { dg-final { scan-tree-dump " = f \\(\\);.*desc.0.dtype = .*;.*desc.0.data = 
.void .. D.*;.*sub \\(&desc.0\\);.*D.*= .integer.kind=4. .. desc.0.data;" 
"original" } }
+! { dg-final { scan-tree-dump " = f \\(\\);" "original" } }
+! { dg-final { scan-tree-dump "desc.0.dtype = .*;" "original" } }
+! { dg-final { scan-tree-dump "desc.0.data = .void .. D.*;" "original" } }
+! { dg-final { scan-tree-dump "sub \\(&desc.0\\);" "original" } }
+! { dg-final { scan-tree-dump "D.*= .integer.kind=4. .. desc.0.data;" 
"original" } }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Déplacement fonction

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:a7d30957412cc9d49cbe8c775f3d9ad1f46bfad8

commit a7d30957412cc9d49cbe8c775f3d9ad1f46bfad8
Author: Mikael Morin 
Date:   Fri Feb 14 09:34:02 2025 +0100

Déplacement fonction

Diff:
---
 gcc/fortran/trans-array.cc | 53 ++
 gcc/fortran/trans-array.h  |  1 +
 gcc/fortran/trans-expr.cc  | 41 ++-
 3 files changed, 47 insertions(+), 48 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 3bfe41c64013..8981a420c97a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -2225,6 +2225,44 @@ gfc_conv_shift_descriptor_subarray (stmtblock_t *block, 
tree desc,
 }
 
 
+void
+gfc_conv_shift_descriptor (stmtblock_t *block, tree desc, int rank,
+  tree lbound[GFC_MAX_DIMENSIONS],
+  tree ubound[GFC_MAX_DIMENSIONS])
+{
+  tree size = gfc_index_one_node;
+  tree offset = gfc_index_zero_node;
+  for (int n = 0; n < rank; n++)
+{
+  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR,
+gfc_array_index_type, tmp,
+gfc_index_one_node);
+  gfc_conv_descriptor_ubound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ tmp);
+  gfc_conv_descriptor_lbound_set (block,
+ desc,
+ gfc_rank_cst[n],
+ gfc_index_one_node);
+  size = gfc_evaluate_now (size, block);
+  offset = fold_build2_loc (input_location, MINUS_EXPR,
+   gfc_array_index_type,
+   offset, size);
+  offset = gfc_evaluate_now (offset, block);
+  tmp = gfc_conv_array_extent_dim (lbound[n], ubound[n], nullptr);
+  size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, size, tmp);
+}
+
+  gfc_conv_descriptor_offset_set (block, desc,
+ offset);
+}
+
+
+
+
 int
 gfc_descriptor_rank (tree descriptor)
 {
@@ -8392,15 +8430,12 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 start at zero, but when allocating it, the standard expects
 the array to start at one.  Therefore fix the upper bound to be
 (desc.ubound - desc.lbound) + 1.  */
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
-gfc_array_index_type,
-gfc_conv_descriptor_ubound_get (
-  expr3_desc, gfc_rank_cst[n]),
-gfc_conv_descriptor_lbound_get (
-  expr3_desc, gfc_rank_cst[n]));
- tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gfc_array_index_type, tmp,
-gfc_index_one_node);
+ tmp = gfc_conv_array_extent_dim (
+ gfc_conv_descriptor_lbound_get (expr3_desc,
+ gfc_rank_cst[n]),
+ gfc_conv_descriptor_ubound_get (expr3_desc,
+ gfc_rank_cst[n]),
+ nullptr);
  se.expr = gfc_evaluate_now (tmp, pblock);
}
  else
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 836a177da014..f37f09c21cff 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -237,6 +237,7 @@ void gfc_conv_shift_descriptor (stmtblock_t*, tree, const 
gfc_array_ref &);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, int);
 void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree);
 void gfc_conv_shift_descriptor_subarray (stmtblock_t*, tree, gfc_expr *, 
gfc_expr *);
+void gfc_conv_shift_descriptor (stmtblock_t *, tree, int, tree *, tree *);
 
 /* Add pre-loop scalarization code for intrinsic functions which require
special handling.  */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 016ac2ee944c..13cb7f9fd8fa 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5207,43 +5207,6 @@ gfc_apply_interface_mapping (gfc_interface_mapping * 
mapping,
 }
 
 
-static void
-shift_descriptor (stmtblock_t *block, tree desc, int rank,
- tree lbound[GFC_MAX_DIMENSIONS],
- tree ubound[GFC_MAX_DIMENSIONS])
-
-{
-  tree size = gfc_index_one_node;
-  tree offset = gfc_index_zero_node;
-  for (int n = 0; n < rank; n++)
-{
-  tree tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR,
-gf

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Ajout surcharge gfc_conv_descriptor_type_set

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:35c975b3a6ee65be51b96848764a90105aa59f81

commit 35c975b3a6ee65be51b96848764a90105aa59f81
Author: Mikael Morin 
Date:   Wed Feb 12 10:22:42 2025 +0100

Ajout surcharge gfc_conv_descriptor_type_set

Diff:
---
 gcc/fortran/trans-array.cc | 41 +
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 19c6768cc66e..051ccafe9807 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -261,6 +261,15 @@ get_field (tree desc, unsigned field_idx)
   return field;
 }
 
+tree
+get_dtype_subfield (tree desc, unsigned subfield)
+{
+  tree dtype = get_field (desc, DTYPE_FIELD);
+  tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (dtype)), subfield);
+  gcc_assert (field != NULL_TREE);
+  return field;
+}
+
 tree
 get_component (tree desc, unsigned field_idx)
 {
@@ -518,6 +527,14 @@ conv_type_set (stmtblock_t *block, tree desc, tree value)
  fold_convert_loc (loc, TREE_TYPE (t), value));
 }
 
+void
+conv_type_set (stmtblock_t *block, tree desc, int value)
+{
+  tree field = get_dtype_subfield (desc, GFC_DTYPE_TYPE);
+  tree val = build_int_cst (TREE_TYPE (field), value);
+  conv_type_set (block, desc, val);
+}
+
 tree
 get_dimensions (tree desc)
 {
@@ -870,6 +887,12 @@ gfc_conv_descriptor_type_set (stmtblock_t *block, tree 
desc, tree value)
   gfc_descriptor::conv_type_set (block, desc, value);
 }
 
+void
+gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, int value)
+{
+  gfc_descriptor::conv_type_set (block, desc, value);
+}
+
 tree
 gfc_conv_descriptor_token_get (tree desc)
 {
@@ -2536,7 +2559,6 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
   ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
   ctype, build_int_cst (TREE_TYPE (ctype),
 CFI_type_mask));
-  tree type = gfc_conv_descriptor_type_get (gfc);
 
   /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
   /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
@@ -2545,13 +2567,11 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
 
   stmtblock_t set_void;
   gfc_init_block (&set_void);
-  tree void_value = build_int_cst (TREE_TYPE (type), BT_VOID);
-  gfc_conv_descriptor_type_set (&set_void, gfc, void_value);
+  gfc_conv_descriptor_type_set (&set_void, gfc, BT_VOID);
 
   stmtblock_t set_unknown;
   gfc_init_block (&set_unknown);
-  tree unknown_value = build_int_cst (TREE_TYPE (type), BT_UNKNOWN);
-  gfc_conv_descriptor_type_set (&set_unknown, gfc, unknown_value);
+  gfc_conv_descriptor_type_set (&set_unknown, gfc, BT_UNKNOWN);
 
   tree tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, 
cond,
   gfc_finish_block (&set_void),
@@ -2563,8 +2583,7 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
 CFI_type_struct));
   stmtblock_t set_derived;
   gfc_init_block (&set_derived);
-  tree derived_value = build_int_cst (TREE_TYPE (type), BT_DERIVED);
-  gfc_conv_descriptor_type_set (&set_derived, gfc, derived_value);
+  gfc_conv_descriptor_type_set (&set_derived, gfc, BT_DERIVED);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
  gfc_finish_block (&set_derived), tmp2);
 
@@ -2576,8 +2595,7 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
  CFI_type_Character));
   stmtblock_t set_character;
   gfc_init_block (&set_character);
-  tree character_value = build_int_cst (TREE_TYPE (type), BT_CHARACTER);
-  gfc_conv_descriptor_type_set (&set_character, gfc, character_value);
+  gfc_conv_descriptor_type_set (&set_character, gfc, BT_CHARACTER);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
  gfc_finish_block (&set_character), tmp2);
 
@@ -2591,7 +2609,7 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
  build_int_cst (TREE_TYPE (tmp),
 CFI_type_ucs4_char));
   gfc_init_block (&set_character);
-  gfc_conv_descriptor_type_set (&set_character, gfc, character_value);
+  gfc_conv_descriptor_type_set (&set_character, gfc, BT_CHARACTER);
   tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
  gfc_finish_block (&set_character), tmp2);
 
@@ -2601,8 +2619,7 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block,
  CFI_type_Complex));
   stmtblock_t set_complex;
   gfc_init_block (&set_complex);
-  tree complex_value = build_int_cst (TREE_TYPE (type), BT_COMPLEX);
-  gfc_conv_descriptor_type_set (&set_complex, 

[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Essai suppression code inutile

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c8dd6ca3fb39f2b21f7edf0628718f0ae6fb1124

commit c8dd6ca3fb39f2b21f7edf0628718f0ae6fb1124
Author: Mikael Morin 
Date:   Fri Feb 14 13:50:51 2025 +0100

Essai suppression code inutile

Diff:
---
 gcc/fortran/trans-expr.cc | 10 --
 1 file changed, 10 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 13cb7f9fd8fa..44a09f546aa6 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5320,16 +5320,6 @@ gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, 
int g77,
   /* Translate the expression.  */
   gfc_conv_expr (&rse, expr);
 
-  /* Reset the offset for the function call since the loop
- is zero based on the data pointer.  Note that the temp
- comes first in the loop chain since it is added second.  */
-  if (gfc_is_class_array_function (expr))
-{
-  tmp = loop.ss->loop_chain->info->data.array.descriptor;
-  gfc_conv_descriptor_offset_set (&loop.pre, tmp,
- gfc_index_zero_node);
-}
-
   gfc_conv_tmp_array_ref (&lse);
 
   if (intent != INTENT_OUT)


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Suppression argument nelems gfc_array_allocate

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c761a6e18c135f3fdbef79c1da6fc72698816ecd

commit c761a6e18c135f3fdbef79c1da6fc72698816ecd
Author: Mikael Morin 
Date:   Fri Feb 14 12:11:43 2025 +0100

Suppression argument nelems gfc_array_allocate

Diff:
---
 gcc/fortran/trans-array.cc | 6 ++
 gcc/fortran/trans-array.h  | 2 +-
 gcc/fortran/trans-stmt.cc  | 5 +
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 891fe662b769..04578f92572e 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8683,9 +8683,8 @@ retrieve_last_ref (gfc_ref **ref_in, gfc_ref 
**prev_ref_in)
 bool
 gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
tree errlen, tree label_finish, tree expr3_elem_size,
-   tree *nelems, gfc_expr *expr3, tree e3_arr_desc,
-   bool e3_has_nodescriptor, gfc_omp_namelist *omp_alloc,
-   bool explicit_ts)
+   gfc_expr *expr3, tree e3_arr_desc, bool e3_has_nodescriptor,
+   gfc_omp_namelist *omp_alloc, bool explicit_ts)
 {
   tree tmp;
   tree pointer;
@@ -8822,7 +8821,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 expr3_elem_size, expr3, e3_arr_desc,
 e3_has_nodescriptor, expr, element_size,
 explicit_ts, &empty_array_cond);
-  *nelems = count;
 
   tree size = get_array_memory_size (element_size, count, empty_array_cond,
 &se->pre, &overflow);
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index f37f09c21cff..357bd64fb766 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Generate code to initialize and allocate an array.  Statements are added to
se, which should contain an expression for the array descriptor.  */
 bool gfc_array_allocate (gfc_se *, gfc_expr *, tree, tree, tree, tree,
-tree, tree *, gfc_expr *, tree, bool,
+tree, gfc_expr *, tree, bool,
 gfc_omp_namelist *, bool);
 
 /* Allow the bounds of a loop to be set from a callee's array spec.  */
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index f4e3ea36cbe3..4406bc6e4ce2 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -6394,7 +6394,6 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist 
*omp_allocate)
   stmtblock_t block;
   stmtblock_t post;
   stmtblock_t final_block;
-  tree nelems;
   bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
   bool needs_caf_sync, caf_refs_comp;
   bool e3_has_nodescriptor = false;
@@ -6926,7 +6925,6 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist 
*omp_allocate)
 to handle the complete array allocation.  Only the element size
 needs to be provided, which is done most of the time by the
 pre-evaluation step.  */
-  nelems = NULL_TREE;
   if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
|| code->expr3->ts.type == BT_CLASS))
{
@@ -6998,8 +6996,7 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist 
*omp_allocate)
}
 
   if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
-  label_finish, tmp, &nelems,
-  e3rhs ? e3rhs : code->expr3,
+  label_finish, tmp, e3rhs ? e3rhs : code->expr3,
   e3_is == E3_DESC ? expr3 : NULL_TREE,
   e3_has_nodescriptor, omp_alloc_item,
   code->ext.alloc.ts.type != BT_UNKNOWN))


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Mise à jour commentaires.

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:f002d571cfa29ce2a678181f64258577a6bba90b

commit f002d571cfa29ce2a678181f64258577a6bba90b
Author: Mikael Morin 
Date:   Fri Feb 14 12:23:42 2025 +0100

Mise à jour commentaires.

Diff:
---
 gcc/fortran/trans-array.cc | 37 ++---
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 04578f92572e..d21e8e774c3a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8302,6 +8302,13 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 }
 
 
+/* Calculates the memory size of an array, given the size of its elements,
+   the number of them, and the predicate whether the array is empty.
+elements_count = (size_t) elements_count;
+overflow += element_size == 0 ? 0: (MAX/element_size < elements_count ? 1: 
0);
+tmp = elements_count * element_size;
+return (tmp);  */
+
 static tree
 get_array_memory_size (tree element_size, tree elements_count,
   tree empty_array_cond, stmtblock_t * pblock,
@@ -8316,8 +8323,6 @@ get_array_memory_size (tree element_size, tree 
elements_count,
   stmtblock_t thenblock;
   stmtblock_t elseblock;
 
-
-
   elements_count = fold_convert (size_type_node, elements_count);
 
   /* First check for overflow. Since an array of type character can
@@ -8366,11 +8371,10 @@ get_array_memory_size (tree element_size, tree 
elements_count,
 }
 
 
-/* Fills in an array descriptor, and returns the size of the array.
-   The size will be a simple_val, ie a variable or a constant.  Also
-   calculates the offset of the base.  The pointer argument overflow,
-   which should be of integer type, will increase in value if overflow
-   occurs during the size calculation.  Returns the size of the array.
+/* Fills in an array descriptor, and returns the number of elements in the
+   array.  The pointer argument overflow, which should be of integer type,
+   will increase in value if overflow occurs during the size calculation.
+   Also sets the condition whether the array is empty through empty_array_cond.
{
 stride = 1;
 offset = 0;
@@ -8387,13 +8391,9 @@ get_array_memory_size (tree element_size, tree 
elements_count,
   }
 for (n = rank; n < rank+corank; n++)
   (Set lcobound/ucobound as above.)
-element_size = sizeof (array element);
-if (!rank)
-  return element_size
-stride = (size_t) stride;
-overflow += element_size == 0 ? 0: (MAX/element_size < stride ? 1: 0);
-stride = stride * element_size;
-return (stride);
+if (rank == 0)
+  return 1;
+return stride;
}  */
 /*GCC ARRAYS*/
 
@@ -8633,9 +8633,6 @@ gfc_array_init_count (tree descriptor, int rank, int 
corank, gfc_expr ** lower,
 
   *empty_array_cond = empty_cond;
 
-  /* The stride is the number of elements in the array, so multiply by the
- size of an element to get the total size.  */
-
   if (rank == 0)
 return gfc_index_one_node;
 
@@ -8822,8 +8819,10 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 e3_has_nodescriptor, expr, element_size,
 explicit_ts, &empty_array_cond);
 
-  tree size = get_array_memory_size (element_size, count, empty_array_cond,
-&se->pre, &overflow);
+  tree size = rank == 0
+ ? element_size
+ : get_array_memory_size (element_size, count, empty_array_cond,
+  &se->pre, &overflow);
 
   if (dimension)
 {


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Renommage gfc_array_init_count -> gfc_descr_init_count

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:8b736715caca8a9c533c7e721e677ed99401f17c

commit 8b736715caca8a9c533c7e721e677ed99401f17c
Author: Mikael Morin 
Date:   Fri Feb 14 13:46:24 2025 +0100

Renommage gfc_array_init_count -> gfc_descr_init_count

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

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index d21e8e774c3a..b121dc94f671 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8398,7 +8398,7 @@ get_array_memory_size (tree element_size, tree 
elements_count,
 /*GCC ARRAYS*/
 
 static tree
-gfc_array_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower,
+gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower,
  gfc_expr ** upper, stmtblock_t * pblock,
  stmtblock_t * descriptor_block, tree * overflow,
  tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
@@ -8811,7 +8811,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
  later will mislead the generation of the array dimensions for allocatable/
  pointer components in derived types.  */
   int rank = alloc_w_e3_arr_spec ? expr->rank : ref->u.ar.as->rank;
-  tree count = gfc_array_init_count (se->expr, rank,
+  tree count = gfc_descr_init_count (se->expr, rank,
 coarray ? ref->u.ar.as->corank : 0,
 lower, upper, &se->pre,
 &set_descriptor_block, &overflow,


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Factorisation descriptor_element_size

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:c141dd194ec615b06b21a493267385487c433cd2

commit c141dd194ec615b06b21a493267385487c433cd2
Author: Mikael Morin 
Date:   Fri Feb 14 11:04:01 2025 +0100

Factorisation descriptor_element_size

Diff:
---
 gcc/fortran/trans-array.cc | 85 +++---
 1 file changed, 51 insertions(+), 34 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 8981a420c97a..89c446c396a1 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8262,6 +8262,46 @@ gfc_conv_descriptor_cosize (tree desc, int rank, int 
corank)
 }
 
 
+static tree
+descriptor_element_size (tree descriptor, tree expr3_elem_size,
+gfc_expr *expr3)
+{
+  tree type;
+  tree tmp;
+
+  type = TREE_TYPE (descriptor);
+
+  /* Obviously, if there is a SOURCE expression (expr3) we must use its element
+ size.  */
+  if (expr3_elem_size != NULL_TREE)
+tmp = expr3_elem_size;
+  else if (expr3 != NULL)
+{
+  if (expr3->ts.type == BT_CLASS)
+   {
+ gfc_se se_sz;
+ gfc_expr *sz = gfc_copy_expr (expr3);
+ gfc_add_vptr_component (sz);
+ gfc_add_size_component (sz);
+ gfc_init_se (&se_sz, NULL);
+ gfc_conv_expr (&se_sz, sz);
+ gfc_free_expr (sz);
+ tmp = se_sz.expr;
+   }
+  else
+   {
+ tmp = gfc_typenode_for_spec (&expr3->ts);
+ tmp = TYPE_SIZE_UNIT (tmp);
+   }
+}
+  else
+tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+
+  /* Convert to size_t.  */
+  return fold_convert (size_type_node, tmp);
+}
+
+
 /* Fills in an array descriptor, and returns the size of the array.
The size will be a simple_val, ie a variable or a constant.  Also
calculates the offset of the base.  The pointer argument overflow,
@@ -8299,7 +8339,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 stmtblock_t * descriptor_block, tree * overflow,
 tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
 tree expr3_desc, bool e3_has_nodescriptor, gfc_expr *expr,
-tree *element_size, bool explicit_ts)
+tree element_size, bool explicit_ts)
 {
   tree type;
   tree tmp;
@@ -8532,37 +8572,10 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
 }
 
   /* The stride is the number of elements in the array, so multiply by the
- size of an element to get the total size.  Obviously, if there is a
- SOURCE expression (expr3) we must use its element size.  */
-  if (expr3_elem_size != NULL_TREE)
-tmp = expr3_elem_size;
-  else if (expr3 != NULL)
-{
-  if (expr3->ts.type == BT_CLASS)
-   {
- gfc_se se_sz;
- gfc_expr *sz = gfc_copy_expr (expr3);
- gfc_add_vptr_component (sz);
- gfc_add_size_component (sz);
- gfc_init_se (&se_sz, NULL);
- gfc_conv_expr (&se_sz, sz);
- gfc_free_expr (sz);
- tmp = se_sz.expr;
-   }
-  else
-   {
- tmp = gfc_typenode_for_spec (&expr3->ts);
- tmp = TYPE_SIZE_UNIT (tmp);
-   }
-}
-  else
-tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
-
-  /* Convert to size_t.  */
-  *element_size = fold_convert (size_type_node, tmp);
+ size of an element to get the total size.  */
 
   if (rank == 0)
-return *element_size;
+return element_size;
 
   *nelems = gfc_evaluate_now (stride, pblock);
   stride = fold_convert (size_type_node, stride);
@@ -8572,14 +8585,14 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
  dividing.  */
   tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
 size_type_node,
-TYPE_MAX_VALUE (size_type_node), *element_size);
+TYPE_MAX_VALUE (size_type_node), element_size);
   cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
logical_type_node, tmp, stride),
   PRED_FORTRAN_OVERFLOW);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
 integer_one_node, integer_zero_node);
   cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
-   logical_type_node, *element_size,
+   logical_type_node, element_size,
build_int_cst (size_type_node, 0)),
   PRED_FORTRAN_SIZE_ZERO);
   tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
@@ -8589,7 +8602,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   *overflow = gfc_evaluate_now (tmp, pblock);
 
   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
- stride, *element_size);
+ stride, ele

[gcc r15-7526] tree: Fix up the DECL_VALUE_EXPR GC marking [PR118790]

2025-02-14 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:74ea20e16cf18b42071557b71a42ea31c8192425

commit r15-7526-g74ea20e16cf18b42071557b71a42ea31c8192425
Author: Jakub Jelinek 
Date:   Fri Feb 14 12:01:13 2025 +0100

tree: Fix up the DECL_VALUE_EXPR GC marking [PR118790]

The ggc_set_mark call in gt_value_expr_mark_2 is actually wrong, that
just marks the VAR_DECL itself, but doesn't mark the subtrees of it (type
etc.).  So, I think we need to test gcc_marked_p for whether it is marked
or not, if not marked walk the DECL_VALUE_EXPR and then gt_ggc_mx mark
the VAR_DECL that was determined not marked and needs to be marked now.
One option would be to call gt_ggc_mx (t) right after the DECL_VALUE_EXPR
walking, but I'm a little bit worried that the subtree marking could mark
other VAR_DECLs (e.g. seen from DECL_SIZE or TREE_TYPE and the like) and
if they would be DECL_HAS_VALUE_EXPR_P we might not walk their
DECL_VALUE_EXPR anymore later.
So, the patch defers the gt_ggc_mx calls until we've walked all the
DECL_VALUE_EXPRs directly or indirectly connected to already marked
VAR_DECLs.

2025-02-14  Jakub Jelinek  

PR debug/118790
* tree.cc (struct gt_value_expr_mark_data): New type.
(gt_value_expr_mark_2): Don't call ggc_set_mark, instead check
ggc_marked_p.  Treat data as gt_value_expr_mark_data * with pset
in it rather than address of the pset itself and push to be marked
VAR_DECLs into to_mark vec.
(gt_value_expr_mark_1): Change argument from hash_set *
to gt_value_expr_mark_data * and find pset in it.
(gt_value_expr_mark): Pass to traverse_noresize address of
gt_value_expr_mark_data object rather than hash_table and
for all entries in the to_mark vector after the traversal call
gt_ggc_mx.

Diff:
---
 gcc/tree.cc | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/tree.cc b/gcc/tree.cc
index 4319f8d41e68..0743ed71c789 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -211,6 +211,11 @@ struct cl_option_hasher : ggc_cache_ptr_hash
 
 static GTY ((cache)) hash_table *cl_option_hash_table;
 
+struct gt_value_expr_mark_data {
+  hash_set pset;
+  auto_vec to_mark;
+};
+
 /* Callback called through walk_tree_1 to discover DECL_HAS_VALUE_EXPR_P
VAR_DECLs which weren't marked yet, in that case marks them and
walks their DECL_VALUE_EXPR expressions.  */
@@ -219,11 +224,12 @@ static tree
 gt_value_expr_mark_2 (tree *tp, int *, void *data)
 {
   tree t = *tp;
-  if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t) && !ggc_set_mark (t))
+  if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t) && !ggc_marked_p (t))
 {
   tree dve = DECL_VALUE_EXPR (t);
-  walk_tree_1 (&dve, gt_value_expr_mark_2, data,
-  (hash_set *) data, NULL);
+  gt_value_expr_mark_data *d = (gt_value_expr_mark_data *) data;
+  walk_tree_1 (&dve, gt_value_expr_mark_2, data, &d->pset, NULL);
+  d->to_mark.safe_push (t);
 }
   return NULL_TREE;
 }
@@ -232,10 +238,10 @@ gt_value_expr_mark_2 (tree *tp, int *, void *data)
value_expr_for_decl hash table.  */
 
 int
-gt_value_expr_mark_1 (tree_decl_map **e, hash_set *pset)
+gt_value_expr_mark_1 (tree_decl_map **e, gt_value_expr_mark_data *data)
 {
   if (ggc_marked_p ((*e)->base.from))
-walk_tree_1 (&(*e)->to, gt_value_expr_mark_2, pset, pset, NULL);
+walk_tree_1 (&(*e)->to, gt_value_expr_mark_2, data, &data->pset, NULL);
   return 1;
 }
 
@@ -255,8 +261,11 @@ gt_value_expr_mark (hash_table 
*h)
   if (!h)
 return;
 
-  hash_set pset;
-  h->traverse_noresize *, gt_value_expr_mark_1> (&pset);
+  gt_value_expr_mark_data data;
+  h->traverse_noresize (&data);
+  for (auto v : data.to_mark)
+gt_ggc_mx (v);
 }
 
 /* General tree->tree mapping  structure for use in hash tables.  */


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Mise à jour offset & span dans gfc_array_init_size

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:537d11778347885424c87b8aebe23ea97bcdd462

commit 537d11778347885424c87b8aebe23ea97bcdd462
Author: Mikael Morin 
Date:   Fri Feb 14 11:22:35 2025 +0100

Mise à jour offset & span dans gfc_array_init_size

Diff:
---
 gcc/fortran/trans-array.cc | 34 --
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 89c446c396a1..ca7590b8f7b7 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8334,8 +8334,8 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 /*GCC ARRAYS*/
 
 static tree
-gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
-gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock,
+gfc_array_init_size (tree descriptor, int rank, int corank, gfc_expr ** lower,
+gfc_expr ** upper, stmtblock_t * pblock,
 stmtblock_t * descriptor_block, tree * overflow,
 tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
 tree expr3_desc, bool e3_has_nodescriptor, gfc_expr *expr,
@@ -8577,6 +8577,12 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   if (rank == 0)
 return element_size;
 
+  /* Update the array descriptor with the offset and the span.  */
+  offset = gfc_evaluate_now (offset, pblock);
+  gfc_conv_descriptor_offset_set (descriptor_block, descriptor, offset);
+  tmp = fold_convert (gfc_array_index_type, element_size);
+  gfc_conv_descriptor_span_set (descriptor_block, descriptor, tmp);
+
   *nelems = gfc_evaluate_now (stride, pblock);
   stride = fold_convert (size_type_node, stride);
 
@@ -8604,12 +8610,6 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, tree * poffset,
   size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
  stride, element_size);
 
-  if (poffset != NULL)
-{
-  offset = gfc_evaluate_now (offset, pblock);
-  *poffset = offset;
-}
-
   if (integer_zerop (or_expr))
 return size;
   if (integer_onep (or_expr))
@@ -8672,7 +8672,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 {
   tree tmp;
   tree pointer;
-  tree offset = NULL_TREE;
   tree token = NULL_TREE;
   tree size;
   tree msg;
@@ -8801,11 +8800,10 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
   size = gfc_array_init_size (se->expr, alloc_w_e3_arr_spec ? expr->rank
   : ref->u.ar.as->rank,
  coarray ? ref->u.ar.as->corank : 0,
- &offset, lower, upper,
- &se->pre, &set_descriptor_block, &overflow,
- expr3_elem_size, nelems, expr3, e3_arr_desc,
- e3_has_nodescriptor, expr, element_size,
- explicit_ts);
+ lower, upper, &se->pre, &set_descriptor_block,
+ &overflow, expr3_elem_size, nelems, expr3,
+ e3_arr_desc, e3_has_nodescriptor, expr,
+ element_size, explicit_ts);
 
   if (dimension)
 {
@@ -8942,14 +8940,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree 
status, tree errmsg,
 
   gfc_add_expr_to_block (&se->pre, tmp);
 
-  /* Update the array descriptor with the offset and the span.  */
-  if (dimension)
-{
-  gfc_conv_descriptor_offset_set (&set_descriptor_block, se->expr, offset);
-  tmp = fold_convert (gfc_array_index_type, element_size);
-  gfc_conv_descriptor_span_set (&set_descriptor_block, se->expr, tmp);
-}
-
   set_descriptor = gfc_finish_block (&set_descriptor_block);
   if (status != NULL_TREE)
 {


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Séparation get_array_memory_size

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:5b2a88f775bfcb66e3b0bfda584a7592c2c39fdb

commit 5b2a88f775bfcb66e3b0bfda584a7592c2c39fdb
Author: Mikael Morin 
Date:   Fri Feb 14 12:07:08 2025 +0100

Séparation get_array_memory_size

Diff:
---
 gcc/fortran/trans-array.cc | 160 ++---
 1 file changed, 91 insertions(+), 69 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ca7590b8f7b7..891fe662b769 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8302,6 +8302,70 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 }
 
 
+static tree
+get_array_memory_size (tree element_size, tree elements_count,
+  tree empty_array_cond, stmtblock_t * pblock,
+  tree * overflow)
+{
+  tree tmp;
+  tree size;
+  tree thencase;
+  tree elsecase;
+  tree cond;
+  tree var;
+  stmtblock_t thenblock;
+  stmtblock_t elseblock;
+
+
+
+  elements_count = fold_convert (size_type_node, elements_count);
+
+  /* First check for overflow. Since an array of type character can
+ have zero element_size, we must check for that before
+ dividing.  */
+  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+size_type_node,
+TYPE_MAX_VALUE (size_type_node), element_size);
+  cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR,
+   logical_type_node, tmp, elements_count),
+  PRED_FORTRAN_OVERFLOW);
+  tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
+integer_one_node, integer_zero_node);
+  cond = gfc_unlikely (fold_build2_loc (input_location, EQ_EXPR,
+   logical_type_node, element_size,
+   build_int_cst (size_type_node, 0)),
+  PRED_FORTRAN_SIZE_ZERO);
+  tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond,
+integer_zero_node, tmp);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
+*overflow, tmp);
+  *overflow = gfc_evaluate_now (tmp, pblock);
+
+  size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
+ elements_count, element_size);
+
+  if (integer_zerop (empty_array_cond))
+return size;
+  if (integer_onep (empty_array_cond))
+return build_int_cst (size_type_node, 0);
+
+  var = gfc_create_var (TREE_TYPE (size), "size");
+  gfc_start_block (&thenblock);
+  gfc_add_modify (&thenblock, var, build_int_cst (size_type_node, 0));
+  thencase = gfc_finish_block (&thenblock);
+
+  gfc_start_block (&elseblock);
+  gfc_add_modify (&elseblock, var, size);
+  elsecase = gfc_finish_block (&elseblock);
+
+  tmp = gfc_evaluate_now (empty_array_cond, pblock);
+  tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
+  gfc_add_expr_to_block (pblock, tmp);
+
+  return var;
+}
+
+
 /* Fills in an array descriptor, and returns the size of the array.
The size will be a simple_val, ie a variable or a constant.  Also
calculates the offset of the base.  The pointer argument overflow,
@@ -8334,25 +8398,20 @@ descriptor_element_size (tree descriptor, tree 
expr3_elem_size,
 /*GCC ARRAYS*/
 
 static tree
-gfc_array_init_size (tree descriptor, int rank, int corank, gfc_expr ** lower,
-gfc_expr ** upper, stmtblock_t * pblock,
-stmtblock_t * descriptor_block, tree * overflow,
-tree expr3_elem_size, tree *nelems, gfc_expr *expr3,
-tree expr3_desc, bool e3_has_nodescriptor, gfc_expr *expr,
-tree element_size, bool explicit_ts)
+gfc_array_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower,
+ gfc_expr ** upper, stmtblock_t * pblock,
+ stmtblock_t * descriptor_block, tree * overflow,
+ tree expr3_elem_size, gfc_expr *expr3, tree expr3_desc,
+ bool e3_has_nodescriptor, gfc_expr *expr,
+ tree element_size, bool explicit_ts,
+ tree *empty_array_cond)
 {
   tree type;
   tree tmp;
   tree size;
   tree offset;
   tree stride;
-  tree or_expr;
-  tree thencase;
-  tree elsecase;
   tree cond;
-  tree var;
-  stmtblock_t thenblock;
-  stmtblock_t elseblock;
   gfc_expr *ubound;
   gfc_se se;
   int n;
@@ -8406,7 +8465,7 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, gfc_expr ** lower,
   else
 gfc_conv_descriptor_dtype_set (pblock, descriptor, gfc_get_dtype (type));
 
-  or_expr = logical_false_node;
+  tree empty_cond = logical_false_node;
 
   for (n = 0; n < rank; n++)
 {
@@ -8499,7 +8558,8 @@ gfc_array_init_size (tree descriptor, int rank, int 
corank, gfc_expr ** lower,
  gfc_rank_cst[n], stride);
 
   /* Calculate size and check whethe

[gcc r15-7527] c++: fix propagating REF_PARENTHESIZED_P [PR116379]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:b01664a6197f57615d3c62594037c575dfdd9035

commit r15-7527-gb01664a6197f57615d3c62594037c575dfdd9035
Author: Marek Polacek 
Date:   Thu Feb 13 15:56:16 2025 -0500

c++: fix propagating REF_PARENTHESIZED_P [PR116379]

Here we have:

  template
  struct X{
  T val;
  decltype(auto) value(){
  return (val);
  }
  };

where the return type of value should be 'int &' since '(val)' is an
expression, not a name, and decltype(auto) performs the type deduction
using the decltype rules.

The problem is that we weren't propagating REF_PARENTHESIZED_P
correctly: the return value of finish_non_static_data_member in this
test was a REFERENCE_REF_P, so we didn't set the flag.  We should
use force_paren_expr like below.

PR c++/116379

gcc/cp/ChangeLog:

* pt.cc (tsubst_expr) : Use force_paren_expr to set
REF_PARENTHESIZED_P.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/decltype-auto9.C: New test.

Reviewed-by: Jason Merrill 

Diff:
---
 gcc/cp/pt.cc|  4 ++--
 gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C | 15 +++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index a2fc8813e9de..5706a3987c34 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -21712,8 +21712,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
  {
r = finish_non_static_data_member (member, object, NULL_TREE,
   complain);
-   if (TREE_CODE (r) == COMPONENT_REF)
- REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+   if (REF_PARENTHESIZED_P (t))
+ force_paren_expr (r);
RETURN (r);
  }
else if (type_dependent_expression_p (object))
diff --git a/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C 
b/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C
new file mode 100644
index ..1ccf95a01702
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/decltype-auto9.C
@@ -0,0 +1,15 @@
+// PR c++/116379
+// { dg-do compile { target c++14 } }
+
+template
+struct X {
+  T val;
+  decltype(auto) value() { return (val); }
+};
+
+int main() {
+  int i = 0;
+  X x{ static_cast(i) };
+  using type = decltype(x.value());
+  using type = int&;
+}


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

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:4cc360ef650f45f0a1ace577ab663b9ed7ef777c

commit 4cc360ef650f45f0a1ace577ab663b9ed7ef777c
Author: Mikael Morin 
Date:   Fri Feb 14 18:48:22 2025 +0100

Correction class_result_10.f90

Diff:
---
 gcc/fortran/trans-array.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 4120785b49b5..c8e5fa60067a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -7445,7 +7445,8 @@ done:
  int dim = ss->dim[n];
 
  info->start[dim]  = gfc_index_zero_node;
- info->end[dim]= gfc_index_zero_node;
+ if (ss_info->type != GFC_SS_FUNCTION)
+   info->end[dim]= gfc_index_zero_node;
  info->stride[dim] = gfc_index_one_node;
}
  break;


[gcc r15-7534] c++: add fixed test [PR66519]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:9a6758edc229abc0ed0f5ce65958082b3e8a8502

commit r15-7534-g9a6758edc229abc0ed0f5ce65958082b3e8a8502
Author: Marek Polacek 
Date:   Fri Feb 14 13:14:01 2025 -0500

c++: add fixed test [PR66519]

Fixed by r10-6464.

PR c++/66519

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/variadic-parm2.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/cpp0x/variadic-parm2.C | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-parm2.C 
b/gcc/testsuite/g++.dg/cpp0x/variadic-parm2.C
new file mode 100644
index ..b061adbd7a95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-parm2.C
@@ -0,0 +1,12 @@
+// PR c++/66519
+// { dg-do compile { target c++11 } }
+
+template
+void a(F f, Tp... args, decltype(f(args...)) = 1) {}
+
+template
+void a(F, Tp...) {}
+
+void b(void) {
+a([]{});
+}


[gcc r15-7533] tree-optimization/118852 - wrong code with 502.gcc_r

2025-02-14 Thread Richard Biener via Gcc-cvs
https://gcc.gnu.org/g:589d79e6268b055422a7b6c11cd0a8a4f2531a8c

commit r15-7533-g589d79e6268b055422a7b6c11cd0a8a4f2531a8c
Author: Richard Biener 
Date:   Fri Feb 14 14:48:41 2025 +0100

tree-optimization/118852 - wrong code with 502.gcc_r

502.gcc_r when built with -fprofile-generate exposes a SLP discovery
issue where an IV forced live due to early break is not properly
discovered if its latch def is part of a different IVs SSA cycle.
To mitigate this we have to make sure to create an SLP instance
for the original IV.  Ideally we'd handle all vect_induction_def
the same but this is left for next stage1.

PR tree-optimization/118852
* tree-vect-slp.cc (vect_analyze_slp): For early-break
forced-live IVs make sure we create an appropriate
entry into the SLP graph.

* gcc.dg/vect/pr118852.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr118852.c | 105 +++
 gcc/tree-vect-slp.cc |  24 +++-
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr118852.c 
b/gcc/testsuite/gcc.dg/vect/pr118852.c
new file mode 100644
index ..d6b43378d6f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr118852.c
@@ -0,0 +1,105 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-profiling "-fprofile-generate" } */
+/* { dg-additional-options "-fallow-store-data-races -fprofile-arcs" } */
+/* { dg-additional-options "-msse4.2 -mprefer-vector-width=128" { target { 
x86_64-*-* i?86-*-* } } } */
+
+#include "tree-vect.h"
+
+typedef unsigned int hashval_t;
+struct htab {
+  void ** entries;
+  unsigned long size;
+};
+typedef struct htab *htab_t;
+unsigned long htab_size (htab_t h)
+{
+  return h->size;
+}
+typedef struct
+{
+  htab_t htab;
+  void * *slot;
+  void * *limit;
+} htab_iterator;
+
+static inline void *
+first_htab_element (htab_iterator *hti, htab_t table)
+{
+  hti->htab = table;
+  hti->slot = table->entries;
+  hti->limit = hti->slot + htab_size (table);
+  do
+{
+  void * x = *(hti->slot);
+  if (x != ((void *) 0) && x != ((void *) 1))
+ break;
+} while (++(hti->slot) < hti->limit);
+
+  if (hti->slot < hti->limit)
+return *(hti->slot);
+  return (void *) 0;
+}
+
+static inline unsigned char
+end_htab_p (const htab_iterator *hti)
+{
+  if (hti->slot >= hti->limit)
+return 1;
+  return 0;
+}
+
+static inline void *
+next_htab_element (htab_iterator *hti)
+{
+  while (++(hti->slot) < hti->limit)
+{
+  void * x = *(hti->slot);
+  if (x != ((void *) 0) && x != ((void *) 1))
+   return x;
+}
+  return (void *) 0;
+}
+
+typedef unsigned long vn_nary_op_t;
+
+typedef struct vn_tables_s
+{
+  htab_t nary;
+} *vn_tables_t;
+
+vn_tables_t valid_info;
+
+void __attribute__((noipa))
+announce (vn_nary_op_t p)
+{
+  static vn_nary_op_t prev = 0;
+  if (prev == 0x70904f0 && p != 0x70904c0)
+__builtin_abort ();
+  prev = p;
+}
+
+void __attribute__((noipa))
+set_hashtable_value_ids_1 (void)
+{
+  htab_iterator hi;
+  vn_nary_op_t vno;
+  for (vno = (vn_nary_op_t) first_htab_element (&(hi), (valid_info->nary)); 
!end_htab_p (&(hi)); vno = (vn_nary_op_t) next_htab_element (&(hi)))
+announce (vno);
+}
+
+int main()
+{
+  if (sizeof (void *) != sizeof (vn_nary_op_t))
+return 0;
+  check_vect ();
+  valid_info = __builtin_malloc (sizeof (struct vn_tables_s));
+  valid_info->nary = __builtin_malloc (sizeof (struct htab));
+  valid_info->nary->entries = __builtin_malloc (sizeof (void *) * 32);
+  valid_info->nary->size = 31;
+  static vn_nary_op_t x[] = { 0x70905e0, 0x0, 0x0, 0x7090610, 0x7090550, 
0x7090400, 0x70903a0, 0x0, 
+  0x0, 0x70904f0, 0x0, 0x0, 0x0, 0x0, 0x70904c0, 0x7090520, 0x7090460, 
+  0x7090490, 0x7090430, 0x0, 0x0, 0x0, 0x7090640, 0x0, 0x0, 0x70903d0, 
0x0, 
+  0x7090580, 0x0, 0x0, 0x70905b0};
+  __builtin_memcpy (valid_info->nary->entries, x, sizeof (void *) * 31);
+  set_hashtable_value_ids_1 ();
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 8ed746ea5a9e..9e09f8e980b5 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -5031,15 +5031,33 @@ vect_analyze_slp (vec_info *vinfo, unsigned 
max_tree_size,
vec stmts;
vec roots = vNULL;
vec remain = vNULL;
-   gphi *lc_phi = as_a (STMT_VINFO_STMT (stmt_info));
-   tree def = gimple_phi_arg_def_from_edge (lc_phi, latch_e);
-   stmt_vec_info lc_info = loop_vinfo->lookup_def (def);
+   gphi *phi = as_a (STMT_VINFO_STMT (stmt_info));
stmts.create (1);
+   tree def = gimple_phi_arg_def_from_edge (phi, latch_e);
+   stmt_vec_info lc_info = loop_vinfo->lookup_def (def);
stmts.quick_push (vect_stmt_to_vectorize (lc_info));
vect_build_slp_instance (vinfo, slp_inst_kind_reduc_group,
 stmts, roots, remain,

[gcc r14-11310] [PATCH] PR modula2/118761: gm2 driver doesnt behave as gcc for -fhelp=BLA

2025-02-14 Thread Gaius Mulley via Gcc-cvs
https://gcc.gnu.org/g:9c38d0a79caef1909df9f51ec8d17c5f8cfecabd

commit r14-11310-g9c38d0a79caef1909df9f51ec8d17c5f8cfecabd
Author: Gaius Mulley 
Date:   Fri Feb 14 19:17:02 2025 +

[PATCH] PR modula2/118761: gm2 driver doesnt behave as gcc for -fhelp=BLA

This patch enables the gm2 driver to handle -fsyntax-only -fhelp=optimizers,
for example, correctly without terminating with gm2: fatal error:
no input files.

gcc/m2/ChangeLog:

PR modula2/118761
* gm2spec.cc (lang_specific_driver): Add case clauses for
OPT__help, OPT__help_ set in_added_libraries to 0 and early
return.

(cherry picked from commit 3c5422e719d1fbabccaa9b63605171ea8bdfe57e)

Signed-off-by: Gaius Mulley 

Diff:
---
 gcc/m2/gm2spec.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/m2/gm2spec.cc b/gcc/m2/gm2spec.cc
index 2a4dccf8b93c..d1fefdcc27c7 100644
--- a/gcc/m2/gm2spec.cc
+++ b/gcc/m2/gm2spec.cc
@@ -576,6 +576,12 @@ lang_specific_driver (struct cl_decoded_option 
**in_decoded_options,
  args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
  m2_path_name = decoded_options[i].arg;
  break;
+   case OPT__help:
+   case OPT__help_:
+ /* Let gcc.cc handle this, as it has a really
+cool facility for handling --help and --verbose --help.  */
+ *in_added_libraries = 0;
+ return;
case OPT_I:
  args[i] |= SKIPOPT; /* We will add the option if it is needed.  */
  push_back_Ipath (decoded_options[i].arg);


[gcc r14-11309] Fortran: fix initialization of allocatable non-deferred character [PR59252]

2025-02-14 Thread Harald Anlauf via Gcc-cvs
https://gcc.gnu.org/g:5ec7193faa7a5a78dd5382aec220a49f4a76a976

commit r14-11309-g5ec7193faa7a5a78dd5382aec220a49f4a76a976
Author: Harald Anlauf 
Date:   Fri Feb 7 21:21:10 2025 +0100

Fortran: fix initialization of allocatable non-deferred character [PR59252]

PR fortran/59252

gcc/fortran/ChangeLog:

* trans-expr.cc (gfc_trans_subcomponent_assign): Initialize
allocatable non-deferred character with NULL properly.

gcc/testsuite/ChangeLog:

* gfortran.dg/allocatable_char_1.f90: New test.

(cherry picked from commit 818c36a85e3faec5442eb26799bfa3bba7764b36)

Diff:
---
 gcc/fortran/trans-expr.cc|  8 +++-
 gcc/testsuite/gfortran.dg/allocatable_char_1.f90 | 47 
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 601cc546d438..f6de2227675b 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -9407,9 +9407,13 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component 
* cm,
   tmp = gfc_trans_alloc_subarray_assign (tmp, cm, expr);
   gfc_add_expr_to_block (&block, tmp);
 }
-  else if (init && cm->attr.allocatable && expr->expr_type == EXPR_NULL)
+  else if (cm->attr.allocatable && expr->expr_type == EXPR_NULL
+  && (init
+  || (cm->ts.type == BT_CHARACTER
+  && !(cm->ts.deferred || cm->attr.pdt_string
 {
-  /* NULL initialization for allocatable components.  */
+  /* NULL initialization for allocatable components.
+Deferred-length character is dealt with later.  */
   gfc_add_modify (&block, dest, fold_convert (TREE_TYPE (dest),
  null_pointer_node));
 }
diff --git a/gcc/testsuite/gfortran.dg/allocatable_char_1.f90 
b/gcc/testsuite/gfortran.dg/allocatable_char_1.f90
new file mode 100644
index ..1d6c25c4942d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocatable_char_1.f90
@@ -0,0 +1,47 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/59252
+
+module mod
+  implicit none
+
+  type t1
+ character(256), allocatable :: label
+  end type t1
+
+  type t2
+ type(t1),   allocatable :: appv(:)
+  end type t2
+
+contains
+  subroutine construct(res)
+type(t2), allocatable, intent(inout) :: res
+if (.not. allocated(res)) allocate(res)
+  end subroutine construct
+
+  subroutine construct_appv(appv)
+type(t1), allocatable, intent(inout) :: appv(:)
+if (.not. allocated(appv)) allocate(appv(20))
+  end subroutine construct_appv
+
+  type(t1) function foo () result (res)
+  end function foo
+end module mod
+
+program testy
+  use mod
+  implicit none
+  type(t2), allocatable :: res
+  type(t1)  :: s
+
+  ! original test from pr59252
+  call construct (res)
+  call construct_appv(res%appv)
+  deallocate (res)
+
+  ! related test from pr118747 comment 2:
+  s = foo ()
+end program testy
+
+! { dg-final { scan-tree-dump-not "__builtin_memmove" "original" } }


[gcc r15-7535] c++: add fixed test [PR66878]

2025-02-14 Thread Marek Polacek via Gcc-cvs
https://gcc.gnu.org/g:720137f4ee6e80de5c22b9f9c9750f13b2132fe6

commit r15-7535-g720137f4ee6e80de5c22b9f9c9750f13b2132fe6
Author: Marek Polacek 
Date:   Fri Feb 14 13:48:03 2025 -0500

c++: add fixed test [PR66878]

Fixed by r11-175.

PR c++/66878

gcc/testsuite/ChangeLog:

* g++.dg/lookup/using71.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/lookup/using71.C | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/testsuite/g++.dg/lookup/using71.C 
b/gcc/testsuite/g++.dg/lookup/using71.C
new file mode 100644
index ..b899e0a27a30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/using71.C
@@ -0,0 +1,12 @@
+// PR c++/66878
+
+struct S;
+
+namespace H {
+namespace P {
+using ::S;
+}
+struct P::S {};
+}
+
+int main() {}


[gcc r15-7528] libstdc++: Conditionally use floating-point fetch_add builtins

2025-02-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:5ced917508eee7eb499e19feeb3def1fa1842bb4

commit r15-7528-g5ced917508eee7eb499e19feeb3def1fa1842bb4
Author: Matthew Malcomson 
Date:   Fri Feb 7 14:49:11 2025 +

libstdc++: Conditionally use floating-point fetch_add builtins

- Some hardware has support for floating point atomic fetch_add (and
  similar).
- There are existing compilers targetting this hardware that use
  libstdc++ -- e.g. NVC++.
- Since the libstdc++ atomic::fetch_add and similar is written
  directly as a CAS loop these compilers can not emit optimal code when
  seeing such constructs.
- I hope to use __atomic_fetch_add builtins on floating point types
  directly in libstdc++ so these compilers can emit better code.
- Clang already handles some floating point types in the
  __atomic_fetch_add family of builtins.
- In order to only use this when available, I originally thought I could
  check against the resolved versions of the builtin in a manner
  something like `__has_builtin(__atomic_fetch_add_)`.
  I then realised that clang does not expose resolved versions of these
  atomic builtins to the user.
  From the clang discourse it was suggested we instead use SFINAE (which
  clang already supports).
- I have recently pushed a patch for allowing the use of SFINAE on
  builtins: r15-6042-g9ed094a817ecaf
  Now that patch is committed, this patch does not change what happens
  for GCC, while it uses the builtin for codegen with clang.
- I have previously sent a patchset upstream adding the ability to use
  __atomic_fetch_add and similar on floating point types.
  https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668754.html
  Once that patchset is upstream (plus the automatic linking of
  libatomic as Joseph pointed out in the email below
  https://gcc.gnu.org/pipermail/gcc-patches/2024-October/665408.html )
  then current GCC should start to use the builtin branch added in this
  patch.

So *currently*, this patch allows external compilers (NVC++ in
particular) to generate better code, and similarly lets clang understand
the operation better since it maps to a known builtin.

I hope that by GCC 16 this patch would also allow GCC to understand the
operation better via mapping to a known builtin.

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (__atomic_fetch_addable): Define
new concept.
(__atomic_impl::__fetch_add_flt): Use new concept to make use of
__atomic_fetch_add when available.
(__atomic_fetch_subtractable, __fetch_sub_flt): Likewise.
(__atomic_add_fetchable, __add_fetch_flt): Likewise.
(__atomic_sub_fetchable, __sub_fetch_flt): Likewise.

Signed-off-by: Matthew Malcomson 
Co-authored-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/bits/atomic_base.h | 88 +++--
 1 file changed, 62 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 1ef21f30bbce..b56007b7bf5f 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1209,54 +1209,90 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __xor_fetch(_Tp* __ptr, _Val<_Tp> __i) noexcept
   { return __atomic_xor_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
 
+template
+  concept __atomic_fetch_addable
+   = requires (_Tp __t) { __atomic_fetch_add(&__t, __t, 0); };
+
 template
   _Tp
   __fetch_add_flt(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
   {
-   _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
-   _Val<_Tp> __newval = __oldval + __i;
-   while (!compare_exchange_weak(__ptr, __oldval, __newval, __m,
- memory_order_relaxed))
- __newval = __oldval + __i;
-   return __oldval;
+   if constexpr (__atomic_fetch_addable<_Tp>)
+ return __atomic_fetch_add(__ptr, __i, int(__m));
+   else
+ {
+   _Val<_Tp> __oldval = load (__ptr, memory_order_relaxed);
+   _Val<_Tp> __newval = __oldval + __i;
+   while (!compare_exchange_weak (__ptr, __oldval, __newval, __m,
+  memory_order_relaxed))
+ __newval = __oldval + __i;
+   return __oldval;
+ }
   }
 
+template
+  concept __atomic_fetch_subtractable
+   = requires (_Tp __t) { __atomic_fetch_sub(&__t, __t, 0); };
+
 template
   _Tp
   __fetch_sub_flt(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
   {
-   _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
-   _Val<_Tp> __newval = __oldval - __i;
-   while (!compare_exchange_weak(__ptr, __oldval, __newval, __m,
- memory_order_relaxed))
- __newval

[gcc r15-7532] c++: extended temp cleanups [PR118856]

2025-02-14 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:e96e1bb69c7b46db18e747ee379a62681bc8c82d

commit r15-7532-ge96e1bb69c7b46db18e747ee379a62681bc8c82d
Author: Jason Merrill 
Date:   Fri Feb 14 10:53:01 2025 +0100

c++: extended temp cleanups [PR118856]

A later testcase in PR118856 highlights a preexisting problem with multiple
reference-extended temporaries in a single declaration; if initializing a
later one throws, the cleanup for the earlier one is not in scope yet.
Let's deal with this by keeping a dummy TARGET_EXPR to hold the EH cleanup
until all other initialization is complete.  See the comment for various
other considered approaches.

We now avoid extending TARGET_EXPRs with CLEANUP_EH_ONLY set; all such
TARGET_EXPRs were already only internal iterator/flag variables that don't
want to be extended, as they are dead after initialization is complete even
if other temporaries are extended.  But some other internal temporaries did
not have the flag set because they don't have TARGET_EXPR_CLEANUP; I
introduce a get_internal_target_expr function to set the flag rather than
directly set the flag (and add a comment) in such places.  The places
changed to call get_internal_target_expr either already set the flag, or
have no cleanup at all.

PR c++/118856

gcc/cp/ChangeLog:

* call.cc (set_up_extended_ref_temp): Retain a TARGET_EXPR for
cleanups if something later in initialization throws.
(extend_temps_r): Don't extend eliding or EH-only TARGET_EXPRs.
* cp-tree.h (get_internal_target_expr): Declare.
* tree.cc (get_internal_target_expr): New.
* decl.cc (cp_finish_decomp, expand_static_init): Use it.
* except.cc (build_throw): Likewise.
* init.cc (build_new_1, build_vec_init, build_delete): Likewise.
(build_vec_delete): Likewise.
* typeck2.cc (maybe_push_temp_cleanup): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/eh/ref-temp3.C: New test.
* g++.dg/eh/ref-temp4.C: New test.

Diff:
---
 gcc/cp/cp-tree.h|  1 +
 gcc/cp/call.cc  | 40 -
 gcc/cp/decl.cc  |  4 ++--
 gcc/cp/except.cc|  2 +-
 gcc/cp/init.cc  | 16 +++
 gcc/cp/tree.cc  | 21 +++
 gcc/cp/typeck2.cc   |  2 +-
 gcc/testsuite/g++.dg/eh/ref-temp3.C | 36 +
 gcc/testsuite/g++.dg/eh/ref-temp4.C | 35 
 9 files changed, 144 insertions(+), 13 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b7749eb2b327..d87cc1555b7a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8207,6 +8207,7 @@ extern bool is_local_temp (tree);
 extern tree build_aggr_init_expr   (tree, tree);
 extern tree get_target_expr(tree,
 tsubst_flags_t = 
tf_warning_or_error);
+extern tree get_internal_target_expr   (tree);
 extern tree build_cplus_array_type (tree, tree, int is_dep = -1);
 extern tree build_array_of_n_type  (tree, unsigned HOST_WIDE_INT);
 extern bool array_of_runtime_bound_p   (tree);
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 38a8f7fdcda9..03130f80f861 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -14251,6 +14251,8 @@ set_up_extended_ref_temp (tree decl, tree expr, 
vec **cleanups,
init = add_stmt_to_compound (init, register_dtor_fn (var));
   else
{
+ /* ??? Instead of rebuilding the cleanup, we could replace the slot
+with var in TARGET_EXPR_CLEANUP (expr).  */
  tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error);
  if (cleanup)
{
@@ -14269,6 +14271,37 @@ set_up_extended_ref_temp (tree decl, tree expr, 
vec **cleanups,
  cleanup = build3 (COND_EXPR, void_type_node,
*cond_guard, cleanup, NULL_TREE);
}
+ if (flag_exceptions && TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE)
+   {
+ /* The normal cleanup for this extended variable isn't pushed
+until cp_finish_decl, so we need to retain a TARGET_EXPR
+to clean it up in case a later initializer throws
+(g++.dg/eh/ref-temp3.C).
+
+We don't do this for array temporaries because they have
+the array cleanup region from build_vec_init.
+
+Unlike maybe_push_temp_cleanup, we don't actually need a
+flag, but a TARGET_EXPR needs a TARGET_EXPR_SLOT.
+Perhaps this could use WITH_CLEANUP_EXPR instead, but
+gimplify.cc doesn't ha

[gcc r15-7531] c++: remove unicode from comment

2025-02-14 Thread Jason Merrill via Gcc-cvs
https://gcc.gnu.org/g:823de62f5f66f052193aa74520dec94fb3488958

commit r15-7531-g823de62f5f66f052193aa74520dec94fb3488958
Author: Jason Merrill 
Date:   Fri Feb 14 10:52:21 2025 +0100

c++: remove unicode from comment

We had a stray U+2019 right single quotation mark instead of U+0027
apostrophe.

gcc/cp/ChangeLog:

* init.cc (perform_member_init): Remove unicode from comment.

Diff:
---
 gcc/cp/init.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 20f4408cc9a1..bc0754735549 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -1093,7 +1093,7 @@ perform_member_init (tree member, tree init, 
hash_set &uninitialized)
 {
   /* With references and list-initialization, we need to deal with
 extending temporary lifetimes.  12.2p5: "A temporary bound to a
-reference member in a constructor’s ctor-initializer (12.6.2)
+reference member in a constructor's ctor-initializer (12.6.2)
 persists until the constructor exits."  */
   unsigned i; tree t;
   releasing_vec cleanups;


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction ICE class_to_type_1

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:3365380377cc2a545a2d49c4b100499b569dc9c1

commit 3365380377cc2a545a2d49c4b100499b569dc9c1
Author: Mikael Morin 
Date:   Fri Feb 14 17:11:03 2025 +0100

Correction ICE class_to_type_1

Diff:
---
 gcc/fortran/trans-array.cc | 30 --
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 996af4b4e7e8..ceaeeeb2a855 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8144,22 +8144,24 @@ late_set_loop_bounds (gfc_loopinfo *loop)
 
   for (n = 0; n < loop->dimen; n++)
 {
-  /* We should have found the scalarization loop specifier.  If not,
-that's bad news.  */
-  gcc_assert (loopspec[n]);
-
-  info = &loopspec[n]->info->data.array;
-  dim = loopspec[n]->dim[n];
-
   /* Set the extents of this range.  */
-  if ((loop->from[n] == NULL_TREE
-  || loop->to[n] == NULL_TREE)
- && loopspec[n]->info->type == GFC_SS_FUNCTION
- && info->start[dim]
- && info->end[dim])
+  if (loop->from[n] == NULL_TREE
+ || loop->to[n] == NULL_TREE)
{
- loop->from[n] = info->start[dim];
- loop->to[n] = info->end[dim];
+ /* We should have found the scalarization loop specifier.  If not,
+that's bad news.  */
+ gcc_assert (loopspec[n]);
+
+ info = &loopspec[n]->info->data.array;
+ dim = loopspec[n]->dim[n];
+
+ if (loopspec[n]->info->type == GFC_SS_FUNCTION
+ && info->start[dim]
+ && info->end[dim])
+   {
+ loop->from[n] = info->start[dim];
+ loop->to[n] = info->end[dim];
+   }
}
 }


[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Sauvegarde modif

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:b0e50451cf7cc27567d93819954790ec76bb4ae8

commit b0e50451cf7cc27567d93819954790ec76bb4ae8
Author: Mikael Morin 
Date:   Fri Feb 14 16:55:42 2025 +0100

Sauvegarde modif

Diff:
---
 gcc/fortran/trans-array.cc | 94 --
 gcc/fortran/trans-expr.cc  | 25 ++--
 2 files changed, 85 insertions(+), 34 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b121dc94f671..996af4b4e7e8 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5591,18 +5591,48 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, 
bool subscript,
  break;
 
case GFC_SS_FUNCTION:
- /* Array function return value.  We call the function and save its
-result in a temporary for use inside the loop.  */
- gfc_init_se (&se, NULL);
- se.loop = loop;
- se.ss = ss;
- if (gfc_is_class_array_function (expr))
-   expr->must_finalize = 1;
- gfc_conv_expr (&se, expr);
- gfc_add_block_to_block (&outer_loop->pre, &se.pre);
- gfc_add_block_to_block (&outer_loop->post, &se.post);
- gfc_add_block_to_block (&outer_loop->post, &se.finalblock);
- ss_info->string_length = se.string_length;
+ {
+   /* Array function return value.  We call the function and save its
+  result in a temporary for use inside the loop.  */
+   gfc_init_se (&se, NULL);
+   se.loop = loop;
+   se.ss = ss;
+   bool class_func = gfc_is_class_array_function (expr);
+   if (class_func)
+ expr->must_finalize = 1;
+   gfc_conv_expr (&se, expr);
+   gfc_add_block_to_block (&outer_loop->pre, &se.pre);
+   if (class_func
+   && se.expr
+   && GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)))
+ {
+   tree tmp = gfc_class_data_get (se.expr);
+   info->descriptor = tmp;
+   info->data = gfc_conv_descriptor_data_get (tmp);
+   info->offset = gfc_conv_descriptor_offset_get (tmp);
+   for (gfc_ss *s = ss; s; s = s->parent)
+ for (int n = 0; n < s->dimen; n++)
+   {
+ int dim = s->dim[n];
+ tree tree_dim = gfc_rank_cst[dim];
+
+ tree start = gfc_conv_descriptor_lbound_get (tmp, 
tree_dim);
+ start = gfc_evaluate_now (start, &outer_loop->pre);
+ info->start[dim] = start;
+
+ tree end = gfc_conv_descriptor_ubound_get (tmp, tree_dim);
+ end = gfc_evaluate_now (end, &outer_loop->pre);
+ info->end[dim] = end;
+
+ tree stride = gfc_conv_descriptor_stride_get (tmp, 
tree_dim);
+ stride = gfc_evaluate_now (stride, &outer_loop->pre);
+ info->stride[dim] = stride;
+   }
+ }
+   gfc_add_block_to_block (&outer_loop->post, &se.post);
+   gfc_add_block_to_block (&outer_loop->post, &se.finalblock);
+   ss_info->string_length = se.string_length;
+ }
  break;
 
case GFC_SS_CONSTRUCTOR:
@@ -8100,6 +8130,44 @@ set_loop_bounds (gfc_loopinfo *loop)
 }
 
 
+/* Last attempt to set the loop bounds, in case they depend on an allocatable
+   function result.  */
+
+static void
+late_set_loop_bounds (gfc_loopinfo *loop)
+{
+  int n, dim;
+  gfc_array_info *info;
+  gfc_ss **loopspec;
+
+  loopspec = loop->specloop;
+
+  for (n = 0; n < loop->dimen; n++)
+{
+  /* We should have found the scalarization loop specifier.  If not,
+that's bad news.  */
+  gcc_assert (loopspec[n]);
+
+  info = &loopspec[n]->info->data.array;
+  dim = loopspec[n]->dim[n];
+
+  /* Set the extents of this range.  */
+  if ((loop->from[n] == NULL_TREE
+  || loop->to[n] == NULL_TREE)
+ && loopspec[n]->info->type == GFC_SS_FUNCTION
+ && info->start[dim]
+ && info->end[dim])
+   {
+ loop->from[n] = info->start[dim];
+ loop->to[n] = info->end[dim];
+   }
+}
+
+  for (loop = loop->nested; loop; loop = loop->next)
+set_loop_bounds (loop);
+}
+
+
 /* Initialize the scalarization loop.  Creates the loop variables.  Determines
the range of the loop variables.  Creates a temporary if required.
Also generates code for scalar expressions which have been
@@ -8118,6 +8186,8 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
  allocating the temporary.  */
   gfc_add_loop_ss_code (loop, loop->ss, false, where);
 
+  late_set_loop_bounds (loop);
+
   tmp_ss = loop->temp_ss;
   /* If we want a temporary then create it.  */
   if (tmp_ss != NULL)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 44a09f546aa6..bbf187f9b7bb 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran

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

2025-02-14 Thread Mikael Morin via Gcc-cvs
https://gcc.gnu.org/g:2342ea2cdae3cd3aad4ba66521da98616079de4e

commit 2342ea2cdae3cd3aad4ba66521da98616079de4e
Author: Mikael Morin 
Date:   Fri Feb 14 17:23:47 2025 +0100

Correction régression class_to_type_2.f90

Diff:
---
 gcc/fortran/trans-array.cc | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index ceaeeeb2a855..4120785b49b5 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -8246,9 +8246,11 @@ gfc_set_delta (gfc_loopinfo *loop)
   gfc_ss_type ss_type;
 
   ss_type = ss->info->type;
-  if (ss_type != GFC_SS_SECTION
- && ss_type != GFC_SS_COMPONENT
- && ss_type != GFC_SS_CONSTRUCTOR)
+  if (!(ss_type == GFC_SS_SECTION
+   || ss_type == GFC_SS_COMPONENT
+   || ss_type == GFC_SS_CONSTRUCTOR
+   || (ss_type == GFC_SS_FUNCTION
+   && gfc_is_class_array_function (ss->info->expr
continue;
 
   info = &ss->info->data.array;