gcc/libgfortran/m4/iparm.m4
Jakub Jelinek 8c73c99b6a libfortran: Fix up maxval/maxloc for UNSIGNED [PR120158]
When libgfortran is compiled, there are some -Woverflow warnings like
../../../libgfortran/generated/maxloc0_4_m1.c:99:14: warning: unsigned conversion from ‘int’ to ‘GFC_UINTEGER_1’ {aka ‘unsigned char’} changes value from ‘-255’ to ‘1’ [-Woverflow]
   99 |     maxval = -GFC_UINTEGER_1_HUGE;
      |              ^
and those actually point a bug in the maxloc*/maxval* implementation
for UNSIGNED.
The intent of
 #if defined ('atype_inf`)
        result = -atype_inf;
 #else
        result = atype_min;
 #endif
(or similar for maxval) is to initialize the variable with
minimum value of the type, if the type has infinities, then
negative infinity, otherwise the minimum (normalized) value.
atype_min expands for signed integers to say (-GFC_INTEGER_4_HUGE-1)
or for floating point to say -GFC_REAL_8_HUGE.
For UNSIGNED it expands to e.g. -GFC_UINTEGER_4_HUGE, but that is
-0xffffffffU which is 1U, while the minimum value of the type is
0.
Haven't tried to construct testcases for that, but I believe e.g.
maskval could return incorrectly 1 on an array (or masked array)
full of 0s, or maxloc could identify incorrectly the maximum location.

The following patch makes sure atype_min expands to 0 for atype_name
GFC_UINTEGER*.

2025-05-07  Jakub Jelinek  <jakub@redhat.com>

	PR libfortran/120158
	* m4/iparm.m4 (atype_min): For atype_name starting with
	GFC_UINTEGER define to 0.
	* generated/maxloc0_16_m1.c: Regenerate.
	* generated/maxloc0_16_m2.c: Regenerate.
	* generated/maxloc0_16_m4.c: Regenerate.
	* generated/maxloc0_16_m8.c: Regenerate.
	* generated/maxloc0_16_m16.c: Regenerate.
	* generated/maxloc0_4_m1.c: Regenerate.
	* generated/maxloc0_4_m2.c: Regenerate.
	* generated/maxloc0_4_m4.c: Regenerate.
	* generated/maxloc0_4_m8.c: Regenerate.
	* generated/maxloc0_4_m16.c: Regenerate.
	* generated/maxloc0_8_m1.c: Regenerate.
	* generated/maxloc0_8_m2.c: Regenerate.
	* generated/maxloc0_8_m4.c: Regenerate.
	* generated/maxloc0_8_m8.c: Regenerate.
	* generated/maxloc0_8_m16.c: Regenerate.
	* generated/maxloc1_16_m1.c: Regenerate.
	* generated/maxloc1_16_m2.c: Regenerate.
	* generated/maxloc1_16_m4.c: Regenerate.
	* generated/maxloc1_16_m8.c: Regenerate.
	* generated/maxloc1_16_m16.c: Regenerate.
	* generated/maxloc1_4_m1.c: Regenerate.
	* generated/maxloc1_4_m2.c: Regenerate.
	* generated/maxloc1_4_m4.c: Regenerate.
	* generated/maxloc1_4_m8.c: Regenerate.
	* generated/maxloc1_4_m16.c: Regenerate.
	* generated/maxloc1_8_m1.c: Regenerate.
	* generated/maxloc1_8_m2.c: Regenerate.
	* generated/maxloc1_8_m4.c: Regenerate.
	* generated/maxloc1_8_m8.c: Regenerate.
	* generated/maxloc1_8_m16.c: Regenerate.
	* generated/maxval_m1.c: Regenerate.
	* generated/maxval_m2.c: Regenerate.
	* generated/maxval_m4.c: Regenerate.
	* generated/maxval_m8.c: Regenerate.
	* generated/maxval_m16.c: Regenerate.
2025-05-08 09:36:30 +02:00

40 lines
1.9 KiB
Text

dnl Support macro file for intrinsic functions.
dnl Works out all the function types from the filename.
dnl This file is part of the GNU Fortran 95 Runtime Library (libgfortran)
dnl Distributed under the GNU GPL with exception. See COPYING for details.
dnl M4 macro file to get type names from filenames
define(get_typename2, `GFC_$1_$2')dnl
define(get_typename, `get_typename2(ifelse($1,i,INTEGER,ifelse($1,r,REAL,ifelse($1,l,LOGICAL,ifelse($1,c,COMPLEX,ifelse($1,m,UINTEGER,ifelse($1,s,UINTEGER,unknown)))))),`$2')')dnl
define(get_arraytype, `gfc_array_$1$2')dnl
define(define_type, `dnl
ifelse(regexp($2,`^[0-9]'),-1,`dnl
define($1_letter, substr($2, 0, 1))dnl
define($1_kind, substr($2, 1))dnl
',`dnl
define($1_letter,i)dnl
define($1_kind,$2)dnl
')dnl
define($1_code,$1_letter`'$1_kind)dnl
define($1,get_arraytype($1_letter,$1_kind))dnl
define($1_name, get_typename($1_letter, $1_kind))')dnl
dnl
define_type(atype, regexp(file, `_\(.?[0-9]*\)\.c$', `\1'))dnl
define(rtype_tmp, regexp(file, `_\(.?[0-9]*\)_[^_]*\.c$', `\1'))dnl
ifelse(rtype_tmp,,`dnl
define_type(rtype, atype_code)dnl
define(rtype_qual,`')dnl
',`dnl
define_type(rtype, rtype_tmp)dnl
define(rtype_qual,`_'rtype_kind)dnl
')dnl
define(atype_max, atype_name`_HUGE')dnl
define(atype_min,ifelse(index(atype_name,`GFC_UINTEGER'),0,`0',ifelse(regexp(file, `_\(.\)[0-9]*\.c$', `\1'),`i',`(-'atype_max`-1)',`-'atype_max)))dnl
define(atype_inf, atype_name`_INFINITY')dnl
define(atype_nan, atype_name`_QUIET_NAN')dnl
define(name, regexp(regexp(file, `[^/]*$', `\&'), `^\([^_]*\)_', `\1'))dnl
define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
define(`u_name',`regexp(upcase(name),`\([A-Z]*\)',`\1')')dnl
define(rtype_ccode,ifelse(rtype_letter,`i',rtype_kind,rtype_code))dnl
define(initval,ifelse(index(name,`maxval'),0,0,index(name,`minval'),0,255))dnl
define(back_arg,ifelse(index(name,`maxloc'),0,``, GFC_LOGICAL_4 back'',dnl
index(name,`minloc'),0,``, GFC_LOGICAL_4 back''))dnl