[gcc/devel/fortran_unsigned] Iplement conversions from unsigned to different data types.

2024-08-03 Thread Thomas Kテカnig via Gcc-cvs
https://gcc.gnu.org/g:b4e4cb4254048475e13d599c88da283ba1aa83c8

commit b4e4cb4254048475e13d599c88da283ba1aa83c8
Author: Thomas Koenig 
Date:   Sat Aug 3 11:20:49 2024 +0200

Iplement conversions from unsigned to different data types.

Diff:
---
 gcc/fortran/arith.cc | 110 ++-
 gcc/fortran/arith.h  |   5 ++
 gcc/fortran/intrinsic.cc |  18 -
 gcc/fortran/resolve.cc   |   7 ++
 gcc/fortran/simplify.cc  |  25 +++
 gcc/testsuite/gfortran.dg/unsigned_5.f90 | 123 +++
 libgfortran/io/read.c|   2 +-
 7 files changed, 286 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index 1b304b114dd8..73e0610689e6 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -2258,7 +2258,8 @@ wprecision_int_real (mpz_t n, mpfr_t r)
   return ret;
 }
 
-/* Convert integers to integers.  */
+/* Convert integers to integers; we can reuse this for also converting
+   unsigneds.  */
 
 gfc_expr *
 gfc_int2int (gfc_expr *src, int kind)
@@ -2266,7 +2267,7 @@ gfc_int2int (gfc_expr *src, int kind)
   gfc_expr *result;
   arith rc;
 
-  if (src->ts.type != BT_INTEGER)
+  if (src->ts.type != BT_INTEGER && src->ts.type != BT_UNSIGNED)
 return NULL;
 
   result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where);
@@ -2375,6 +2376,111 @@ gfc_int2complex (gfc_expr *src, int kind)
   return result;
 }
 
+/* Convert unsigned to unsigned, or integer to unsigned.  */
+
+gfc_expr *
+gfc_uint2uint (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  arith rc;
+  int k;
+
+  if (src->ts.type != BT_UNSIGNED && src->ts.type != BT_INTEGER)
+return NULL;
+
+  result = gfc_get_constant_expr (BT_UNSIGNED, kind, &src->where);
+  mpz_set (result->value.integer, src->value.integer);
+
+  rc = gfc_range_check (result);
+  if (rc != ARITH_OK)
+gfc_warning (0, gfc_arith_error (rc), &result->where);
+
+  k = gfc_validate_kind (BT_UNSIGNED, kind, false);
+  mpz_and (result->value.integer, result->value.integer,
+  gfc_unsigned_kinds[k].huge);
+
+  return result;
+}
+
+gfc_expr *
+gfc_int2uint (gfc_expr *src, int kind)
+{
+  return gfc_uint2uint (src, kind);
+}
+
+gfc_expr *
+gfc_uint2int (gfc_expr *src, int kind)
+{
+  return gfc_int2int (src, kind);
+}
+
+/* Convert UNSIGNED to reals.  */
+
+gfc_expr *
+gfc_uint2real (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  arith rc;
+
+  if (src->ts.type != BT_UNSIGNED)
+return NULL;
+
+  result = gfc_get_constant_expr (BT_REAL, kind, &src->where);
+
+  mpfr_set_z (result->value.real, src->value.integer, GFC_RND_MODE);
+
+  if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+{
+  arith_error (rc, &src->ts, &result->ts, &src->where);
+  gfc_free_expr (result);
+  return NULL;
+}
+
+  if (warn_conversion
+  && wprecision_int_real (src->value.integer, result->value.real))
+gfc_warning (OPT_Wconversion, "Change of value in conversion "
+"from %qs to %qs at %L",
+gfc_typename (&src->ts),
+gfc_typename (&result->ts),
+&src->where);
+
+  return result;
+}
+
+/* Convert default integer to default complex.  */
+
+gfc_expr *
+gfc_uint2complex (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  arith rc;
+
+  if (src->ts.type != BT_UNSIGNED)
+return NULL;
+
+  result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where);
+
+  mpc_set_z (result->value.complex, src->value.integer, GFC_MPC_RND_MODE);
+
+  if ((rc = gfc_check_real_range (mpc_realref (result->value.complex), kind))
+  != ARITH_OK)
+{
+  arith_error (rc, &src->ts, &result->ts, &src->where);
+  gfc_free_expr (result);
+  return NULL;
+}
+
+  if (warn_conversion
+  && wprecision_int_real (src->value.integer,
+ mpc_realref (result->value.complex)))
+  gfc_warning_now (OPT_Wconversion, "Change of value in conversion "
+  "from %qs to %qs at %L",
+  gfc_typename (&src->ts),
+  gfc_typename (&result->ts),
+  &src->where);
+
+  return result;
+}
 
 /* Convert default real to default integer.  */
 
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index f2e63bca2154..e796d4dac293 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -63,6 +63,11 @@ gfc_expr *gfc_le (gfc_expr *, gfc_expr *, gfc_intrinsic_op);
 gfc_expr *gfc_int2int (gfc_expr *, int);
 gfc_expr *gfc_int2real (gfc_expr *, int);
 gfc_expr *gfc_int2complex (gfc_expr *, int);
+gfc_expr *gfc_int2uint (gfc_expr *, int);
+gfc_expr *gfc_uint2uint (gfc_expr *, int);
+gfc_expr *gfc_uint2int (gfc_expr *, int);
+gfc_expr *gfc_uint2real (gfc_expr *, int);
+gfc_expr *gfc_uint2complex (gfc_expr *, int);
 gfc_expr *gfc_real2int (gfc_expr *, int);
 gfc_expr *gfc_real2real (gfc_expr *, int);
 gfc_expr *gfc_real2complex (g

[gcc r15-2707] libstdc++: use concrete return type for std::forward_like

2024-08-03 Thread Patrick Palka via Libstdc++-cvs
https://gcc.gnu.org/g:8256d5c0097dff00f9bdf9ee0c9d53bd7cec2802

commit r15-2707-g8256d5c0097dff00f9bdf9ee0c9d53bd7cec2802
Author: Patrick Palka 
Date:   Sat Aug 3 09:05:05 2024 -0400

libstdc++: use concrete return type for std::forward_like

Inspired by https://github.com/llvm/llvm-project/issues/101614 this
inverts the relationship between forward_like and __like_t so that
forward_like is defined in terms of __like_t and with a concrete return
type.  __like_t in turn is defined via partial specializations that
pattern match on the const- and reference-ness of T.

This turns out to be more SFINAE friendly and significantly cheaper
to compile than the previous implementation.

libstdc++-v3/ChangeLog:

* include/bits/move.h (__like_impl): New metafunction.
(__like_t): Redefine in terms of __like_impl.
(forward_like): Redefine in terms of __like_t.
* testsuite/20_util/forward_like/2_neg.cc: Don't expect
error outside the immediate context anymore.

Reviewed-by: Jonathan Wakely 

Diff:
---
 libstdc++-v3/include/bits/move.h   | 47 +++---
 .../testsuite/20_util/forward_like/2_neg.cc|  6 +--
 2 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index bb200c95964a..8397a01b6323 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -88,31 +88,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __glibcxx_forward_like // C++ >= 23
   template
-  [[nodiscard]]
-  constexpr decltype(auto)
-  forward_like(_Up&& __x) noexcept
-  {
-constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
-
-if constexpr (is_const_v>)
-  {
-   using _Up2 = remove_reference_t<_Up>;
-   if constexpr (__as_rval)
- return static_cast(__x);
-   else
- return static_cast(__x);
-  }
-else
-  {
-   if constexpr (__as_rval)
- return static_cast&&>(__x);
-   else
- return static_cast<_Up&>(__x);
-  }
-  }
+  struct __like_impl; // _Tp must be a reference and _Up an lvalue reference
+
+  template
+  struct __like_impl<_Tp&, _Up&>
+  { using type = _Up&; };
+
+  template
+  struct __like_impl
+  { using type = const _Up&; };
+
+  template
+  struct __like_impl<_Tp&&, _Up&>
+  { using type = _Up&&; };
+
+  template
+  struct __like_impl
+  { using type = const _Up&&; };
 
   template
-using __like_t = decltype(std::forward_like<_Tp>(std::declval<_Up>()));
+using __like_t = typename __like_impl<_Tp&&, _Up&>::type;
+
+  template
+  [[nodiscard]]
+  constexpr __like_t<_Tp, _Up>
+  forward_like(_Up&& __x) noexcept
+  { return static_cast<__like_t<_Tp, _Up>>(__x); }
 #endif
 
   /**
diff --git a/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc 
b/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
index ff835af19151..5dafa419a7ea 100644
--- a/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
@@ -2,9 +2,7 @@
 
 #include 
 
-auto x1 = std::forward_like(1); // { dg-error "here" }
+auto x1 = std::forward_like(1); // { dg-error "no match" }
 // { dg-error "forming reference to void" "" { target *-*-* } 0 }
-auto x2 = std::forward_like(1); // { dg-error "here" }
+auto x2 = std::forward_like(1); // { dg-error "no match" }
 // { dg-error "forming reference to qualified function" "" { target *-*-* } 0 }
-
-// { dg-prune-output "inconsistent deduction for auto return type" } // 
PR111484


[gcc r15-2708] libquadmath: Fix up libquadmath/math/sqrtq.c compilation in some powerpc* configurations [PR116007]

2024-08-03 Thread Jakub Jelinek via Gcc-cvs
https://gcc.gnu.org/g:3ac02e67503ccffa3dfeeffc0a60fce6bdaca43b

commit r15-2708-g3ac02e67503ccffa3dfeeffc0a60fce6bdaca43b
Author: Jakub Jelinek 
Date:   Sat Aug 3 20:37:54 2024 +0200

libquadmath: Fix up libquadmath/math/sqrtq.c compilation in some powerpc* 
configurations [PR116007]

My PR114623 change started using soft-fp.h and quad.h for the sqrtq 
implementation.
Unfortunately, that seems to fail building in some powerpc* configurations, 
where
TFmode isn't available.
quad.h has:
 #ifndef TFtype
 typedef float TFtype __attribute__ ((mode (TF)));
 #endif
and uses TFtype.  quad.h has:
 /* Define the complex type corresponding to __float128
("_Complex __float128" is not allowed) */
 #if (!defined(_ARCH_PPC)) || defined(__LONG_DOUBLE_IEEE128__)
 typedef _Complex float __attribute__((mode(TC))) __complex128;
 #else
 typedef _Complex float __attribute__((mode(KC))) __complex128;
 #endif
with the conditional and KCmode use added during porting of libquadmath
to powerpc*, so I've just defined TFtype for powerpc when 
__LONG_DOUBLE_IEEE128__
isn't defined; I could define it to float __attribute__ ((mode (KF))) but it
seemed easier to just define it to __float128 which should do the same 
thing.

2024-08-03  Jakub Jelinek  

PR target/116007
* math/sqrtq.c (TFtype): For PowerPC without __LONG_DOUBLE_IEEE128__
define to __float128 before including soft-fp.h and quad.h.

Diff:
---
 libquadmath/math/sqrtq.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libquadmath/math/sqrtq.c b/libquadmath/math/sqrtq.c
index 8ca2828d42ce..a58998a06670 100644
--- a/libquadmath/math/sqrtq.c
+++ b/libquadmath/math/sqrtq.c
@@ -9,6 +9,9 @@
 && defined(FE_TOWARDZERO) \
 && defined(FE_INEXACT)
 #define USE_SOFT_FP 1
+#if defined(_ARCH_PPC) && !defined(__LONG_DOUBLE_IEEE128__)
+#define TFtype __float128
+#endif
 #include "../../libgcc/soft-fp/soft-fp.h"
 #include "../../libgcc/soft-fp/quad.h"
 #endif


[gcc r14-10555] libstdc++: Fix __cpp_lib_chrono for old std::string ABI

2024-08-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c3866651a2a4623ebca544391051d3f69f141110

commit r14-10555-gc3866651a2a4623ebca544391051d3f69f141110
Author: Jonathan Wakely 
Date:   Thu Jun 20 13:28:08 2024 +0100

libstdc++: Fix __cpp_lib_chrono for old std::string ABI

The  header is incomplete for the old std::string ABI, because
std::chrono::tzdb is only defined for the new ABI. The feature test
macro advertising full C++20 support should not be defined for the old
ABI.

libstdc++-v3/ChangeLog:

* include/bits/version.def (chrono): Add cxx11abi = yes.
* include/bits/version.h: Regenerate.
* testsuite/std/time/syn_c++20.cc: Adjust expected value for
the feature test macro.

(cherry picked from commit f906b107634bfac29676e7fcf364d0ca7ceed666)

Diff:
---
 libstdc++-v3/include/bits/version.def|  1 +
 libstdc++-v3/include/bits/version.h  |  2 +-
 libstdc++-v3/testsuite/std/time/syn_c++20.cc | 11 +--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index e5f4c4c13c01..72e38d4d712d 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -574,6 +574,7 @@ ftms = {
 v = 201907;
 cxxmin = 20;
 hosted = yes;
+cxx11abi = yes; // std::chrono::tzdb requires cxx11 std::string
   };
   values = {
 v = 201611;
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index ad418d46664e..f6b265d8ffb8 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -639,7 +639,7 @@
 #undef __glibcxx_want_boyer_moore_searcher
 
 #if !defined(__cpp_lib_chrono)
-# if (__cplusplus >= 202002L) && _GLIBCXX_HOSTED
+# if (__cplusplus >= 202002L) && _GLIBCXX_USE_CXX11_ABI && _GLIBCXX_HOSTED
 #  define __glibcxx_chrono 201907L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_chrono)
 #   define __cpp_lib_chrono 201907L
diff --git a/libstdc++-v3/testsuite/std/time/syn_c++20.cc 
b/libstdc++-v3/testsuite/std/time/syn_c++20.cc
index f0b86199e9db..4a527262e9d8 100644
--- a/libstdc++-v3/testsuite/std/time/syn_c++20.cc
+++ b/libstdc++-v3/testsuite/std/time/syn_c++20.cc
@@ -20,9 +20,16 @@
 
 #include 
 
+// std::chrono::tzdb is not defined for the old std::string ABI.
+#if _GLIBCXX_USE_CXX_ABI
+# define EXPECTED_VALUE 201907L
+#else
+# define EXPECTED_VALUE 201611L
+#endif
+
 #ifndef __cpp_lib_chrono
 # error "Feature test macro for chrono is missing in "
-#elif __cpp_lib_chrono < 201907L
+#elif __cpp_lib_chrono < EXPECTED_VALUE
 # error "Feature test macro for chrono has wrong value in "
 #endif
 
@@ -94,7 +101,7 @@ namespace __gnu_test
   using std::chrono::make12;
   using std::chrono::make24;
 
-#if _GLIBCXX_USE_CXX11_ABI
+#if __cpp_lib_chrono >= 201803L
   using std::chrono::tzdb;
   using std::chrono::tzdb_list;
   using std::chrono::get_tzdb;