bool
gfc_check_ishft (gfc_expr *i, gfc_expr *shift)
{
- if (!type_check (i, 0, BT_INTEGER)
- || !type_check (shift, 1, BT_INTEGER))
+ if (flag_unsigned)
+ {
+ if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED))
+ return false;
+ }
+ else
+ {
+ if (!type_check (i, 0, BT_INTEGER))
+ return false;
+ }
+
+ if (!type_check (shift, 1, BT_INTEGER))
return false;
if (!less_than_bitsize1 ("I", i, NULL, shift, true))
bool
gfc_check_ishftc (gfc_expr *i, gfc_expr *shift, gfc_expr *size)
{
- if (!type_check (i, 0, BT_INTEGER)
- || !type_check (shift, 1, BT_INTEGER))
- return false;
+ if (flag_unsigned)
+ {
+ if (!type_check2 (i, 0, BT_INTEGER, BT_UNSIGNED))
+ return false;
+ }
+ else
+ {
+ if (!type_check (i, 0, BT_INTEGER))
+ return false;
+ }
if (size != NULL)
{
gfc_current_intrinsic, &x->where))
return false;
}
- else if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
+ else
{
- gfc_error ("%<a1%> argument of %qs intrinsic at %L must be INTEGER, "
- "REAL or CHARACTER", gfc_current_intrinsic, &x->where);
- return false;
+ if (flag_unsigned)
+ {
+ if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL
+ && x->ts.type != BT_UNSIGNED)
+ {
+ gfc_error ("%<a1%> argument of %qs intrinsic at %L must be "
+ "INTEGER, REAL, CHARACTER or UNSIGNED",
+ gfc_current_intrinsic, &x->where);
+ return false;
+ }
+ }
+ else
+ {
+ if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
+ {
+ gfc_error ("%<a1%> argument of %qs intrinsic at %L must be "
+ "INTEGER, REAL or CHARACTER",
+ gfc_current_intrinsic, &x->where);
+ return false;
+ }
+ }
}
return check_rest (x->ts.type, x->ts.kind, arg);
@item @code{BIT_SIZE}, @code{DIGITS} and @code{HUGE}
@item @code{DSHIFTL} and @code{DSHIFTR}
@item @code{IBCLR}, @code{IBITS} and @code{IBITS}
+@item @code{MIN} and @code{MAX}
+@item @code{ISHFT} and @code{ISHFTC}
@end itemize
This list will grow in the near future.
@c ---------------------------------------------------------------------
gfc_extract_int (s, &shift);
- k = gfc_validate_kind (BT_INTEGER, e->ts.kind, false);
- bitsize = gfc_integer_kinds[k].bit_size;
+ k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+ if (e->ts.type == BT_INTEGER)
+ bitsize = gfc_integer_kinds[k].bit_size;
+ else
+ bitsize = gfc_unsigned_kinds[k].bit_size;
result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
}
}
- gfc_convert_mpz_to_signed (result->value.integer, bitsize);
+ if (result->ts.type == BT_INTEGER)
+ gfc_convert_mpz_to_signed (result->value.integer, bitsize);
+ else
+ gfc_reduce_unsigned(result);
+
free (bits);
return result;
if (shift == 0)
return result;
- gfc_convert_mpz_to_unsigned (result->value.integer, isize);
+ if (result->ts.type == BT_INTEGER)
+ gfc_convert_mpz_to_unsigned (result->value.integer, isize);
bits = XCNEWVEC (int, ssize);
}
}
- gfc_convert_mpz_to_signed (result->value.integer, isize);
+ if (result->ts.type == BT_INTEGER)
+ gfc_convert_mpz_to_signed (result->value.integer, isize);
free (bits);
return result;
switch (arg->ts.type)
{
case BT_INTEGER:
+ case BT_UNSIGNED:
if (extremum->ts.kind < arg->ts.kind)
extremum->ts.kind = arg->ts.kind;
ret = mpz_cmp (arg->value.integer,
--- /dev/null
+! { dg-do run }
+! { dg-options "-funsigned" }
+! Test min/max
+program main
+ unsigned :: u_a, u_b
+ if (max(1u,2u) /= 2u) error stop 1
+ if (max(2u,1u) /= 2u) error stop 2
+ if (min(1u,2u) /= 1u) error stop 3
+ if (min(2u,1u) /= 1u) error stop 4
+ u_a = 1u
+ u_b = 2u
+ if (max(u_a,u_b) /= u_b) error stop 5
+ if (max(u_b,u_a) /= u_b) error stop 6
+ if (min(u_a,u_b) /= u_a) error stop 7
+ if (min(u_b,u_a) /= u_a) error stop 8
+ if (max(4294967295u, 1u) /= 4294967295u) error stop 9
+ u_a = 4294967295u
+ u_b = 1u
+ if (max(u_a,u_b) /= 4294967295u) error stop 10
+ if (max(u_b,u_a) /= 4294967295u) error stop 11
+ if (min(u_a,u_b) /= 1u) error stop 12
+ if (min(u_b,u_a) /= 1u) error stop 13
+end program
--- /dev/null
+! { dg-do run }
+! { dg-options "-funsigned" }
+! Test some
+program main
+ unsigned :: u_a
+ u_a = 1u
+ if (ishft(1u,31) /= 2147483648u) stop 1
+ if (ishft(u_a,31) /= 2147483648u) stop 2
+
+ u_a = 3u
+ if (ishft(3u,2) /= 12u) stop 3
+ if (ishft(u_a,2) /= 12u) stop 4
+
+ u_a = huge(u_a)
+ if (ishftc(huge(u_a),1) /= huge(u_a)) stop 5
+ if (ishftc(u_a,1) /= u_a) stop 6
+
+end program
--- /dev/null
+! { dg-do run }
+! { dg-options "-funsigned" }
+! Test basic functionality of ishft and ishftc.
+program main
+ unsigned :: u_a
+ u_a = 1u
+ if (ishft(1u,31) /= 2147483648u) stop 1
+ if (ishft(u_a,31) /= 2147483648u) stop 2
+
+ u_a = 3u
+ if (ishft(3u,2) /= 12u) stop 3
+ if (ishft(u_a,2) /= 12u) stop 4
+
+ u_a = huge(u_a)
+ if (ishftc(huge(u_a),1) /= huge(u_a)) stop 5
+ if (ishftc(u_a,1) /= u_a) stop 6
+
+end program