1! RUN: %S/test_folding.sh %s %t %f18
2! Test operation folding edge case (both expected value and messages)
3! These tests make assumptions regarding real(4) and integer(4) extrema.
4
5#define TEST_ISNAN(v) logical, parameter :: test_##v =.NOT.(v.EQ.v)
6
7module integer_tests
8  integer(4), parameter :: i4_pmax = 2147483647_4
9  ! Fortran grammar rule R605 prevents from writing -2147483648_4 in an
10  ! expression because literal-constant are not signed so this would parse
11  ! to -(2147483648_4) and 2147483648_4 is not accepted as a literal-constant.
12  ! However, one can reach this value with operations.
13  integer(4), parameter :: i4_nmax = -2147483647_4 - 1_4
14
15  ! Integer division by zero are not tested here because they are handled as fatal
16  ! errors in constants.
17
18  !WARN: INTEGER(4) negation overflowed
19  logical, parameter :: test_overflow_unary_minus1 = (-i4_nmax).EQ.i4_nmax
20  logical, parameter :: test_no_overflow_unary_minus1 = (-i4_pmax).EQ.(i4_nmax+1_4)
21  logical, parameter :: test_no_overflow_unary_plus1 = (+i4_pmax).EQ.i4_pmax
22  logical, parameter :: test_no_overflow_unary_plus2 = (+i4_nmax).EQ.i4_nmax
23
24  !WARN: INTEGER(4) addition overflowed
25  logical, parameter :: test_overflow_add1 = (i4_pmax+1_4).EQ.i4_nmax
26  !WARN: INTEGER(4) addition overflowed
27  logical, parameter :: test_overflow_add2 = (i4_nmax + (-1_4)).EQ.i4_pmax
28  !WARN: INTEGER(4) addition overflowed
29  logical, parameter :: test_overflow_add3 = (i4_pmax + i4_pmax).EQ.(-2_4)
30  !WARN: INTEGER(4) addition overflowed
31  logical, parameter :: test_overflow_add4 = (i4_nmax + i4_nmax).EQ.(0_4)
32  logical, parameter :: test_no_overflow_add1 = (i4_pmax + 0_4).EQ.i4_pmax
33  logical, parameter :: test_no_overflow_add2 = (i4_nmax + (-0_4)).EQ.i4_nmax
34  logical, parameter :: test_no_overflow_add3 = (i4_pmax + i4_nmax).EQ.(-1_4)
35  logical, parameter :: test_no_overflow_add4 = (i4_nmax + i4_pmax).EQ.(-1_4)
36
37  !WARN: INTEGER(4) subtraction overflowed
38  logical, parameter :: test_overflow_sub1 = (i4_nmax - 1_4).EQ.i4_pmax
39  !WARN: INTEGER(4) subtraction overflowed
40  logical, parameter :: test_overflow_sub2 = (i4_pmax - (-1_4)).EQ.i4_nmax
41  !WARN: INTEGER(4) subtraction overflowed
42  logical, parameter :: test_overflow_sub3 = (i4_nmax - i4_pmax).EQ.(1_4)
43  !WARN: INTEGER(4) subtraction overflowed
44  logical, parameter :: test_overflow_sub4 = (i4_pmax - i4_nmax).EQ.(-1_4)
45  logical, parameter :: test_no_overflow_sub1 = (i4_nmax - 0_4).EQ.i4_nmax
46  logical, parameter :: test_no_overflow_sub2 = (i4_pmax - (-0_4)).EQ.i4_pmax
47  logical, parameter :: test_no_overflow_sub3 = (i4_nmax - i4_nmax).EQ.0_4
48  logical, parameter :: test_no_overflow_sub4 = (i4_pmax - i4_pmax).EQ.0_4
49
50
51  !WARN: INTEGER(4) multiplication overflowed
52  logical, parameter :: test_overflow_mult1 = (i4_pmax*2_4).EQ.(-2_4)
53  !WARN: INTEGER(4) multiplication overflowed
54  logical, parameter :: test_overflow_mult2 = (i4_nmax*2_4).EQ.(0_4)
55  !WARN: INTEGER(4) multiplication overflowed
56  logical, parameter :: test_overflow_mult3 = (i4_nmax*i4_nmax).EQ.(0_4)
57  !WARN: INTEGER(4) multiplication overflowed
58  logical, parameter :: test_overflow_mult4 = (i4_pmax*i4_pmax).EQ.(1_4)
59
60  !WARN: INTEGER(4) division overflowed
61  logical, parameter :: test_overflow_div1 = (i4_nmax/(-1_4)).EQ.(i4_nmax)
62  logical, parameter :: test_no_overflow_div1 = (i4_nmax/(-2_4)).EQ.(1_4 + i4_pmax/2_4)
63  logical, parameter :: test_no_overflow_div2 = (i4_nmax/i4_nmax).EQ.(1_4)
64
65  !WARN: INTEGER(4) power overflowed
66  logical, parameter :: test_overflow_pow1 = (i4_pmax**2_4).EQ.(1_4)
67  !WARN: INTEGER(4) power overflowed
68  logical, parameter :: test_overflow_pow3 = (i4_nmax**2_4).EQ.(0_4)
69  logical, parameter :: test_no_overflow_pow1 = ((-1_4)**i4_nmax).EQ.(1_4)
70  logical, parameter :: test_no_overflow_pow2 = ((-1_4)**i4_pmax).EQ.(-1_4)
71
72end module
73
74module real_tests
75  ! Test real(4) operation folding on edge cases (inf and NaN)
76
77  real(4), parameter :: r4_pmax = 3.4028235E38
78  real(4), parameter :: r4_nmax = -3.4028235E38
79  !WARN: invalid argument on division
80  real(4), parameter :: r4_nan = 0._4/0._4
81  TEST_ISNAN(r4_nan)
82  !WARN: division by zero
83  real(4), parameter :: r4_pinf = 1._4/0._4
84  !WARN: division by zero
85  real(4), parameter :: r4_ninf = -1._4/0._4
86
87  logical, parameter :: test_r4_nan_parentheses1 = .NOT.(((r4_nan)).EQ.r4_nan)
88  logical, parameter :: test_r4_nan_parentheses2 = .NOT.(((r4_nan)).NE.r4_nan)
89  logical, parameter :: test_r4_pinf_parentheses = ((r4_pinf)).EQ.r4_pinf
90  logical, parameter :: test_r4_ninf_parentheses = ((r4_ninf)).EQ.r4_ninf
91
92  ! No warnings expected
93  logical, parameter :: test_r4_negation1 = (-r4_pmax).EQ.r4_nmax
94  logical, parameter :: test_r4_negation2 = (-r4_nmax).EQ.r4_pmax
95  logical, parameter :: test_r4_negation3 = (-r4_pinf).EQ.r4_ninf
96  logical, parameter :: test_r4_negation4 = (-r4_ninf).EQ.r4_pinf
97  logical, parameter :: test_r4_plus1 = (+r4_pmax).EQ.r4_pmax
98  logical, parameter :: test_r4_plus2 = (+r4_nmax).EQ.r4_nmax
99  logical, parameter :: test_r4_plus3 = (+r4_pinf).EQ.r4_pinf
100  logical, parameter :: test_r4_plus4 = (+r4_ninf).EQ.r4_ninf
101  ! NaN propagation , no warnings expected (quiet)
102  real(4), parameter :: r4_nan_minus = (-r4_nan)
103  TEST_ISNAN(r4_nan_minus)
104  real(4), parameter :: r4_nan_plus = (+r4_nan)
105  TEST_ISNAN(r4_nan_plus)
106
107  !WARN: overflow on addition
108  logical, parameter :: test_inf_r4_add9 = (r4_pmax + r4_pmax).eq.(r4_pinf)
109  !WARN: overflow on addition
110  logical, parameter :: test_inf_r4_add10 = (r4_nmax + r4_nmax).eq.(r4_ninf)
111  !WARN: overflow on subtraction
112  logical, parameter :: test_inf_r4_sub9 = (r4_pmax - r4_nmax).eq.(r4_pinf)
113  !WARN: overflow on subtraction
114  logical, parameter :: test_inf_r4_sub10 = (r4_nmax - r4_pmax).eq.(r4_ninf)
115
116  ! No warnings expected below (inf propagation).
117  logical, parameter :: test_inf_r4_add1 = (r4_pinf + r4_pinf).EQ.(r4_pinf)
118  logical, parameter :: test_inf_r4_add2 = (r4_ninf + r4_ninf).EQ.(r4_ninf)
119  logical, parameter :: test_inf_r4_add3 = (r4_pinf + r4_nmax).EQ.(r4_pinf)
120  logical, parameter :: test_inf_r4_add4 = (r4_pinf + r4_pmax).EQ.(r4_pinf)
121  logical, parameter :: test_inf_r4_add5 = (r4_ninf + r4_pmax).EQ.(r4_ninf)
122  logical, parameter :: test_inf_r4_add6 = (r4_ninf + r4_nmax).EQ.(r4_ninf)
123  logical, parameter :: test_inf_r4_add7 = (r4_ninf + 0._4).EQ.(r4_ninf)
124  logical, parameter :: test_inf_r4_add8 = (r4_pinf + 0._4).EQ.(r4_pinf)
125
126  !WARN: invalid argument on subtraction
127  real(4), parameter :: r4_nan_sub1 = r4_pinf - r4_pinf
128  TEST_ISNAN(r4_nan_sub1)
129  !WARN: invalid argument on subtraction
130  real(4), parameter :: r4_nan_sub2 = r4_ninf - r4_ninf
131  TEST_ISNAN(r4_nan_sub2)
132  !WARN: invalid argument on addition
133  real(4), parameter :: r4_nan_add1 = r4_ninf + r4_pinf
134  TEST_ISNAN(r4_nan_add1)
135  !WARN: invalid argument on addition
136  real(4), parameter :: r4_nan_add2 = r4_pinf + r4_ninf
137  TEST_ISNAN(r4_nan_add2)
138
139  ! No warnings expected here (quite NaN propagation)
140  real(4), parameter :: r4_nan_sub3 = 0._4 - r4_nan
141  TEST_ISNAN(r4_nan_sub3)
142  real(4), parameter :: r4_nan_sub4 = r4_nan - r4_pmax
143  TEST_ISNAN(r4_nan_sub4)
144  real(4), parameter :: r4_nan_sub5 = r4_nan - r4_nmax
145  TEST_ISNAN(r4_nan_sub5)
146  real(4), parameter :: r4_nan_sub6 = r4_nan - r4_nan
147  TEST_ISNAN(r4_nan_sub6)
148  real(4), parameter :: r4_nan_add3 = 0._4 + r4_nan
149  TEST_ISNAN(r4_nan_add3)
150  real(4), parameter :: r4_nan_add4 = r4_nan + r4_pmax
151  TEST_ISNAN(r4_nan_add4)
152  real(4), parameter :: r4_nan_add5 = r4_nmax + r4_nan
153  TEST_ISNAN(r4_nan_add5)
154  real(4), parameter :: r4_nan_add6 = r4_nan + r4_nan
155  TEST_ISNAN(r4_nan_add6)
156
157  !WARN: overflow on multiplication
158  logical, parameter :: test_inf_r4_mult1 = (1.5_4*r4_pmax).eq.(r4_pinf)
159  !WARN: overflow on multiplication
160  logical, parameter :: test_inf_r4_mult2 = (1.5_4*r4_nmax).eq.(r4_ninf)
161  !WARN: overflow on division
162  logical, parameter :: test_inf_r4_div1 = (r4_nmax/(-0.5_4)).eq.(r4_pinf)
163  !WARN: overflow on division
164  logical, parameter :: test_inf_r4_div2 = (r4_pmax/(-0.5_4)).eq.(r4_ninf)
165
166  ! No warnings expected below (inf propagation).
167  logical, parameter :: test_inf_r4_mult3 = (r4_pinf*r4_pinf).EQ.(r4_pinf)
168  logical, parameter :: test_inf_r4_mult4 = (r4_ninf*r4_ninf).EQ.(r4_pinf)
169  logical, parameter :: test_inf_r4_mult5 = (r4_pinf*0.1_4).EQ.(r4_pinf)
170  logical, parameter :: test_inf_r4_mult6 = (r4_ninf*r4_nmax).EQ.(r4_pinf)
171  logical, parameter :: test_inf_r4_div3 = (r4_pinf/0.).EQ.(r4_pinf)
172  logical, parameter :: test_inf_r4_div4 = (r4_ninf/0.).EQ.(r4_ninf)
173  logical, parameter :: test_inf_r4_div5 = (0./r4_pinf).EQ.(0.)
174  logical, parameter :: test_inf_r4_div6 = (0./r4_ninf).EQ.(0.)
175  logical, parameter :: test_inf_r4_div7 = (r4_pinf/r4_pmax).EQ.(r4_pinf)
176  logical, parameter :: test_inf_r4_div8 = (r4_pinf/r4_nmax).EQ.(r4_ninf)
177  logical, parameter :: test_inf_r4_div9 = (r4_nmax/r4_pinf).EQ.(0.)
178  logical, parameter :: test_inf_r4_div10 = (r4_nmax/r4_ninf).EQ.(0.)
179
180  !WARN: invalid argument on division
181  real(4), parameter :: r4_nan_div1 = 0._4/0._4
182  TEST_ISNAN(r4_nan_div1)
183  !WARN: invalid argument on division
184  real(4), parameter :: r4_nan_div2 = r4_ninf/r4_ninf
185  TEST_ISNAN(r4_nan_div2)
186  !WARN: invalid argument on division
187  real(4), parameter :: r4_nan_div3 = r4_ninf/r4_pinf
188  TEST_ISNAN(r4_nan_div3)
189  !WARN: invalid argument on division
190  real(4), parameter :: r4_nan_div4 = r4_pinf/r4_ninf
191  TEST_ISNAN(r4_nan_div4)
192  !WARN: invalid argument on division
193  real(4), parameter :: r4_nan_div5 = r4_pinf/r4_pinf
194  TEST_ISNAN(r4_nan_div5)
195  !WARN: invalid argument on multiplication
196  real(4), parameter :: r4_nan_mult1 = r4_pinf*0._4
197  TEST_ISNAN(r4_nan_mult1)
198  !WARN: invalid argument on multiplication
199  real(4), parameter :: r4_nan_mult2 = 0._4*r4_ninf
200  TEST_ISNAN(r4_nan_mult2)
201
202  ! No warnings expected here (quite NaN propagation)
203  real(4), parameter :: r4_nan_div6 = 0._4/r4_nan
204  TEST_ISNAN(r4_nan_div6)
205  real(4), parameter :: r4_nan_div7 = r4_nan/r4_nan
206  TEST_ISNAN(r4_nan_div7)
207  real(4), parameter :: r4_nan_div8 = r4_nan/0._4
208  TEST_ISNAN(r4_nan_div8)
209  real(4), parameter :: r4_nan_div9 = r4_nan/1._4
210  TEST_ISNAN(r4_nan_div9)
211  real(4), parameter :: r4_nan_mult3 = r4_nan*1._4
212  TEST_ISNAN(r4_nan_mult3)
213  real(4), parameter :: r4_nan_mult4 = r4_nan*r4_nan
214  TEST_ISNAN(r4_nan_mult4)
215  real(4), parameter :: r4_nan_mult5 = 0._4*r4_nan
216  TEST_ISNAN(r4_nan_mult5)
217
218  ! TODO: ** operator folding
219  !  logical, parameter :: test_inf_r4_exp1 = (r4_pmax**2._4).EQ.(r4_pinf)
220
221  ! Relational operator edge cases (No warnings expected?)
222  logical, parameter :: test_inf_r4_eq1 = r4_pinf.EQ.r4_pinf
223  logical, parameter :: test_inf_r4_eq2 = r4_ninf.EQ.r4_ninf
224  logical, parameter :: test_inf_r4_eq3 = .NOT.(r4_pinf.EQ.r4_ninf)
225  logical, parameter :: test_inf_r4_eq4 = .NOT.(r4_pinf.EQ.r4_pmax)
226
227  logical, parameter :: test_inf_r4_ne1 = .NOT.(r4_pinf.NE.r4_pinf)
228  logical, parameter :: test_inf_r4_ne2 = .NOT.(r4_ninf.NE.r4_ninf)
229  logical, parameter :: test_inf_r4_ne3 = r4_pinf.NE.r4_ninf
230  logical, parameter :: test_inf_r4_ne4 = r4_pinf.NE.r4_pmax
231
232  logical, parameter :: test_inf_r4_gt1 = .NOT.(r4_pinf.GT.r4_pinf)
233  logical, parameter :: test_inf_r4_gt2 = .NOT.(r4_ninf.GT.r4_ninf)
234  logical, parameter :: test_inf_r4_gt3 = r4_pinf.GT.r4_ninf
235  logical, parameter :: test_inf_r4_gt4 = r4_pinf.GT.r4_pmax
236
237  logical, parameter :: test_inf_r4_lt1 = .NOT.(r4_pinf.LT.r4_pinf)
238  logical, parameter :: test_inf_r4_lt2 = .NOT.(r4_ninf.LT.r4_ninf)
239  logical, parameter :: test_inf_r4_lt3 = r4_ninf.LT.r4_pinf
240  logical, parameter :: test_inf_r4_lt4 = r4_pmax.LT.r4_pinf
241
242  logical, parameter :: test_inf_r4_ge1 = r4_pinf.GE.r4_pinf
243  logical, parameter :: test_inf_r4_ge2 = r4_ninf.GE.r4_ninf
244  logical, parameter :: test_inf_r4_ge3 = .NOT.(r4_ninf.GE.r4_pinf)
245  logical, parameter :: test_inf_r4_ge4 = .NOT.(r4_pmax.GE.r4_pinf)
246
247  logical, parameter :: test_inf_r4_le1 = r4_pinf.LE.r4_pinf
248  logical, parameter :: test_inf_r4_le2 = r4_ninf.LE.r4_ninf
249  logical, parameter :: test_inf_r4_le3 = .NOT.(r4_pinf.LE.r4_ninf)
250  logical, parameter :: test_inf_r4_le4 = .NOT.(r4_pinf.LE.r4_pmax)
251
252  ! Invalid relational argument
253  logical, parameter :: test_nan_r4_eq1 = .NOT.(r4_nan.EQ.r4_nan)
254  logical, parameter :: test_nan_r4_ne1 = .NOT.(r4_nan.NE.r4_nan)
255
256end module
257
258! TODO: edge case conversions
259! TODO: complex tests (or is real tests enough?)
260
261! Logical operation (with logical arguments) cannot overflow or be invalid.
262! CHARACTER folding operations may cause host memory exhaustion if the
263! string are very large. This will cause a fatal error for the program
264! doing folding (e.g. f18), so there is nothing very interesting to test here.
265