Re: [PATCH] Fortran: check types of operands of arithmetic binary operations [PR107217]

2022-10-12 Thread Mikael Morin

Le 11/10/2022 à 22:23, Harald Anlauf via Fortran a écrit :

Dear all,

we need to check that the operands of arithmetic binary operations
are consistent and of numeric type.

The PR reported an issue for multiplication ("*"), but we better
extend this to the other binary operations.

I chose the following solution:
- consistent types for +,-,*,/, keeping an internal error if any
   unhandled type shows up,


I thought it was insufficient for cases where types are consistent but 
invalid, for example:

   print *, [real :: ([.true.])] / [real :: ([.false.])]
but this case is properly caught, and a few other as well, so no problem.


- numeric types for **

Regtested on x86_64-pc-linux-gnu.  OK for mainline?


Yes, thanks.


Question about Fortran bounds and -Wanalyzer-use-of-uninitialized-value

2022-10-12 Thread David Malcolm via Fortran
Sorry in advance if this is a silly question; my knowledge of Fortran
is next to nothing, I'm afraid.

PR analyzer/107210 reports an ICE in -fanalyzer on this reproducer:


! { dg-additional-options "-O1" }

subroutine check_int (j)
  INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
  target :: ib
  POINTER :: ip, ipa
  logical :: l(5)

  l = (/ sizeof(i) == 4, sizeof(ia) == 20, sizeof(ib) == 80, &
   sizeof(ip) == 4, sizeof(ipa) == 8 /) ! { dg-warning "use of 
uninitialized value" }

  if (any(.not.l)) STOP 4

end subroutine check_int


The fix for the ICE is trivial (a missing check that tree_fits_uhwi_p),
but after the fix, I see these warnings from the analyzer:


   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
  |   ^
Warning: use of uninitialized value ‘ipa.dim[0].ubound’ [CWE-457] 
[-Wanalyzer-use-of-uninitialized-value]
  ‘check_int’: events 1-3
|
|4 |   INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
|  | ^
|  | |
|  | (1) region created on 
stack here
|  | (2) capacity: 8 bytes
|..
|   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
|  |   ~  
|  |   |
|  |   (3) use of uninitialized 
value ‘ipa.dim[0].ubound’ here
|
../../src/gcc/testsuite/gfortran.dg/analyzer/pr107210.f90:10:43:

   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
  |   ^
Warning: use of uninitialized value ‘ipa.dim[0].lbound’ [CWE-457] 
[-Wanalyzer-use-of-uninitialized-value]
  ‘check_int’: events 1-3
|
|4 |   INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
|  | ^
|  | |
|  | (1) region created on 
stack here
|  | (2) capacity: 8 bytes
|..
|   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
|  |   ~  
|  |   |
|  |   (3) use of uninitialized 
value ‘ipa.dim[0].lbound’ here
|


The gimple in question is:

__attribute__((fn spec (". w ")))
void check_int (integer(kind=4) & restrict j)
{
  integer(kind=8) ipa$dim$0$lbound;
  integer(kind=8) ipa$dim$0$ubound;
  logical(kind=4) A.1[5];
  logical(kind=4) l[5];
  integer(kind=8) _1;
  logical(kind=4) _3;
  logical(kind=4) _4;
  integer(kind=8) _5;
  logical(kind=4) _6;
  integer(kind=8) S.5_7;
  logical(kind=4) test.6_8;
  integer(kind=8) S.7_9;
  integer(kind=8) S.5_16;
  integer(kind=8) S.7_18;

   [local count: 178992760]:
  MEM  [(c_char * {ref-all})&A.1] = 0x1000100010001;
  _1 = ipa$dim$0$ubound_2(D) - ipa$dim$0$lbound_12(D);
  _3 = _1 == 1;
  MEM[(logical(kind=4) *)&A.1 + 16B] = _3;

[...snip...]

where the analyzer is complaining about this gimple statement:
  _1 = ipa$dim$0$ubound_2(D) - ipa$dim$0$lbound_12(D);
where both:
  ipa$dim$0$ubound_2(D)
and:
  ipa$dim$0$lbound_12(D)
are considered by it to be uninitialized.

Is the analyzer correct here, or is there an aspect of Fortan and/or
gimple that I'm missing?

Thanks
Dave



Re: Question about Fortran bounds and -Wanalyzer-use-of-uninitialized-value

2022-10-12 Thread Harald Anlauf via Fortran

Hi Dave,

Am 12.10.22 um 15:46 schrieb David Malcolm via Fortran:

Sorry in advance if this is a silly question; my knowledge of Fortran
is next to nothing, I'm afraid.

PR analyzer/107210 reports an ICE in -fanalyzer on this reproducer:


! { dg-additional-options "-O1" }

subroutine check_int (j)
   INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
   target :: ib
   POINTER :: ip, ipa
   logical :: l(5)

   l = (/ sizeof(i) == 4, sizeof(ia) == 20, sizeof(ib) == 80, &
sizeof(ip) == 4, sizeof(ipa) == 8 /) ! { dg-warning "use of uninitialized 
value" }

   if (any(.not.l)) STOP 4

end subroutine check_int


The fix for the ICE is trivial (a missing check that tree_fits_uhwi_p),
but after the fix, I see these warnings from the analyzer:


10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
   |   ^
Warning: use of uninitialized value ‘ipa.dim[0].ubound’ [CWE-457] 
[-Wanalyzer-use-of-uninitialized-value]
   ‘check_int’: events 1-3
 |
 |4 |   INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
 |  | ^
 |  | |
 |  | (1) region created on 
stack here
 |  | (2) capacity: 8 bytes
 |..
 |   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
 |  |   ~
 |  |   |
 |  |   (3) use of 
uninitialized value ‘ipa.dim[0].ubound’ here
 |
../../src/gcc/testsuite/gfortran.dg/analyzer/pr107210.f90:10:43:

10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
   |   ^
Warning: use of uninitialized value ‘ipa.dim[0].lbound’ [CWE-457] 
[-Wanalyzer-use-of-uninitialized-value]
   ‘check_int’: events 1-3
 |
 |4 |   INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
 |  | ^
 |  | |
 |  | (1) region created on 
stack here
 |  | (2) capacity: 8 bytes
 |..
 |   10 |sizeof(ip) == 4, sizeof(ipa) == 8 /)
 |  |   ~
 |  |   |
 |  |   (3) use of 
uninitialized value ‘ipa.dim[0].lbound’ here
 |


The gimple in question is:

__attribute__((fn spec (". w ")))
void check_int (integer(kind=4) & restrict j)
{
   integer(kind=8) ipa$dim$0$lbound;
   integer(kind=8) ipa$dim$0$ubound;
   logical(kind=4) A.1[5];
   logical(kind=4) l[5];
   integer(kind=8) _1;
   logical(kind=4) _3;
   logical(kind=4) _4;
   integer(kind=8) _5;
   logical(kind=4) _6;
   integer(kind=8) S.5_7;
   logical(kind=4) test.6_8;
   integer(kind=8) S.7_9;
   integer(kind=8) S.5_16;
   integer(kind=8) S.7_18;

[local count: 178992760]:
   MEM  [(c_char * {ref-all})&A.1] = 0x1000100010001;
   _1 = ipa$dim$0$ubound_2(D) - ipa$dim$0$lbound_12(D);
   _3 = _1 == 1;
   MEM[(logical(kind=4) *)&A.1 + 16B] = _3;

[...snip...]

where the analyzer is complaining about this gimple statement:
   _1 = ipa$dim$0$ubound_2(D) - ipa$dim$0$lbound_12(D);
where both:
   ipa$dim$0$ubound_2(D)
and:
   ipa$dim$0$lbound_12(D)
are considered by it to be uninitialized.

Is the analyzer correct here, or is there an aspect of Fortan and/or
gimple that I'm missing?


if you compile w/o -fanalyzer but with -O -Wall you will get
warnings, too.  Note that SIZEOF is an extension documented here:

https://gcc.gnu.org/onlinedocs/gfortran/SIZEOF.html

where is says:

..  If the argument has the POINTER attribute, the number of bytes of 
the storage area pointed to is returned. ...


which can be determined only if the arrays bounds are known.
The testcase gfortran.dg/sizeof.f90 from which the above was reduced
sets these bounds via

  ipa=>ib(2:3,1)

If I restore this, then I get no related warnings for -O -Wall.


Thanks
Dave







[PATCH] Fortran: simplify array constructors with typespec [PR93483, PR107216, PR107219]

2022-10-12 Thread Harald Anlauf via Fortran
Dear Fortranners,

this one was really bugging me for quite some time.  We failed to
properly handle (= simplify) expressions using array constructors
with typespec, and with parentheses and unary '+' and '-'
sprinkled here and there.  When there was no typespec, there was
no related problem.

The underlying issue apparently was that we should simplify
elements of the array constructor before attempting the type
conversion.

Thanks to Gerhard, who insisted by submitted many related PRs.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

From ee65197f4d0b0050dc61687b5a77f1afe3bd4a27 Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Wed, 12 Oct 2022 21:33:36 +0200
Subject: [PATCH] Fortran: simplify array constructors with typespec [PR93483,
 PR107216, PR107219]

gcc/fortran/ChangeLog:

	PR fortran/93483
	PR fortran/107216
	PR fortran/107219
	* array.cc (walk_array_constructor): If an element of an array
	constructor is an EXPR_OP, try simplification before type conversion.

gcc/testsuite/ChangeLog:

	PR fortran/93483
	PR fortran/107216
	PR fortran/107219
	* gfortran.dg/array_constructor_56.f90: New test.
---
 gcc/fortran/array.cc  |  4 
 .../gfortran.dg/array_constructor_56.f90  | 22 +++
 2 files changed, 26 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/array_constructor_56.f90

diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index bbdb5b392fc..9bec299f160 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -1205,6 +1205,10 @@ walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head)
   for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
 {
   e = c->expr;
+
+  if (e->expr_type == EXPR_OP)
+	gfc_simplify_expr (e, 0);
+
   if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
 	  && !e->ref && e->value.constructor)
 	{
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_56.f90 b/gcc/testsuite/gfortran.dg/array_constructor_56.f90
new file mode 100644
index 000..4701fb36225
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_constructor_56.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+!
+! Test the fix for the following:
+! PR fortran/93483
+! PR fortran/107216
+! PR fortran/107219
+!
+! Contributed by G.Steinmetz
+
+program p
+  real, parameter :: r0(*) = +[real :: +(1) ]
+  real, parameter :: r1(*) = +[real :: +[1] ]
+  real, parameter :: r2(*) = -[real :: [(1)]]
+  real, parameter :: r3(*) = +[real :: [-(1)]]
+  real, parameter :: r4(*) = -[real :: [[(1)]]]
+  real, parameter :: r5(*) = -[real :: -[1, 2]]
+  real, parameter :: r6(*) = +[real :: +[1, 2]]
+  real, parameter :: r7(*) =  [real :: 1, 2] * [real :: 1, (2)]
+  real, parameter :: r8(*) =  [real :: 1, (2)] * [real :: 1, 2]
+  real, parameter :: r9(*) = +[real :: 1, 2] * [real :: 1, (2)]
+  real, parameter :: rr(*) = -[real :: 1, (2)] * [real :: 1, 2]
+end
--
2.35.3