aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/check.cc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2024-08-08 20:10:33 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2024-08-08 20:10:33 +0200
commit8366ec0e2fbf52cdf209272826b64d4e049743de (patch)
tree7cb3dd3d648af470e0e398c0e213d20d4d543f64 /gcc/fortran/check.cc
parentd5c05281bacf79bca1c10c34135aa61e14be8acb (diff)
downloadgcc-devel/fortran_unsigned.zip
gcc-devel/fortran_unsigned.tar.gz
gcc-devel/fortran_unsigned.tar.bz2
Add merge_bits.devel/fortran_unsigned
Diffstat (limited to 'gcc/fortran/check.cc')
-rw-r--r--gcc/fortran/check.cc50
1 files changed, 42 insertions, 8 deletions
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 108e05d..ae1ca6e 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -4443,20 +4443,54 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask)
&& !gfc_boz2int (j, i->ts.kind))
return false;
- if (!type_check (i, 0, BT_INTEGER))
- return false;
+ if (flag_unsigned)
+ {
+ /* If i is BOZ and j is unsigned, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_UNSIGNED
+ && !gfc_boz2uint (i, j->ts.kind))
+ return false;
- if (!type_check (j, 1, BT_INTEGER))
- return false;
+ /* If j is BOZ and i is unsigned, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_UNSIGNED
+ && !gfc_boz2int (j, i->ts.kind))
+ return false;
+
+ if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED))
+ return false;
+
+ if (!type_check2 (j, 1, BT_INTEGER, BT_UNSIGNED))
+ return false;
+ }
+ else
+ {
+ if (!type_check (i, 0, BT_INTEGER))
+ return false;
+
+ if (!type_check (j, 1, BT_INTEGER))
+ return false;
+ }
if (!same_type_check (i, 0, j, 1))
return false;
- if (mask->ts.type == BT_BOZ && !gfc_boz2int(mask, i->ts.kind))
- return false;
+ if (mask->ts.type == BT_BOZ)
+ {
+ if (i->ts.type == BT_INTEGER && !gfc_boz2int (mask, i->ts.kind))
+ return false;
+ if (i->ts.type == BT_UNSIGNED && !gfc_boz2uint (mask, i->ts.kind))
+ return false;
+ }
- if (!type_check (mask, 2, BT_INTEGER))
- return false;
+ if (flag_unsigned)
+ {
+ if (!type_check2 (mask, 2, BT_INTEGER, BT_UNSIGNED))
+ return false;
+ }
+ else
+ {
+ if (!type_check (mask, 2, BT_INTEGER))
+ return false;
+ }
if (!same_type_check (i, 0, mask, 2))
return false;