[Patch, fortran] PR fortran/100018 - ICE on missing polymorphic argument

2021-04-10 Thread José Rui Faustino de Sousa via Fortran

Hi all!

Proposed patch to PR100018 - ICE on missing polymorphic argument.

Patch tested only on x86_64-pc-linux-gnu.

Add association check before de-referencing pointer in order to avoid ICE.

Thank you very much.

Best regards,
José Rui


2021-4-10  José Rui Faustino de Sousa  

gcc/fortran/ChangeLog:

PR fortran/100018
* resolve.c: Add association check before de-referencing
pointer.


gcc/testsuite/ChangeLog:

PR fortran/100018
* gfortran.dg/PR10018.f90: New test.

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 1c9b0c5cb62..dd4b26680e0 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -11999,6 +11999,7 @@ start:
 	/* Assigning a class object always is a regular assign.  */
 	if (code->expr2->ts.type == BT_CLASS
 		&& code->expr1->ts.type == BT_CLASS
+		&& CLASS_DATA (code->expr2)
 		&& !CLASS_DATA (code->expr2)->attr.dimension
 		&& !(gfc_expr_attr (code->expr1).proc_pointer
 		 && code->expr2->expr_type == EXPR_VARIABLE
diff --git a/gcc/testsuite/gfortran.dg/PR10018.f90 b/gcc/testsuite/gfortran.dg/PR10018.f90
new file mode 100644
index 000..f1cf2676f85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR10018.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+!
+subroutine foo(that)
+  implicit none
+  class(*),  target, intent(in)  :: this
+  class(*), pointer, intent(out) :: that
+
+  that => this
+  return
+end subroutine foo
+! { dg-error "Symbol at \\\(1\\\) is not a DUMMY variable" "" { target "*-*-*" } 5 }


Re: [Patch, fortran] PR fortran/100018 - ICE on missing polymorphic argument

2021-04-10 Thread Tobias Burnus

Hi José,

On 10.04.21 18:58, José Rui Faustino de Sousa via Fortran wrote:

Proposed patch to PR100018 - ICE on missing polymorphic argument.
Patch tested only on x86_64-pc-linux-gnu.


LGTM – Thanks for the patch. Two nits:

If you don't want to rely on the author field of git and specify an 
extra line, you need a '0' for the moth in the date (-04- instead of -4-).


And you need an additional single-line summary for git – which should be 
part of the patch submission.


Tobias



Add association check before de-referencing pointer in order to avoid 
ICE.


Thank you very much.

Best regards,
José Rui


    2021-4-10  José Rui Faustino de Sousa 

gcc/fortran/ChangeLog:

PR fortran/100018
* resolve.c: Add association check before de-referencing
pointer.


gcc/testsuite/ChangeLog:

PR fortran/100018
* gfortran.dg/PR10018.f90: New test.



Re: GSoC 2021 - Fortran run-time argument checking

2021-04-10 Thread Tobias Burnus

Dear Krishna,

On 07.04.21 17:55, Krishna Kariya wrote:

1.
Do we need to create the global variables __gfortran_called_proc,
__gfortran_called_interface during compilation? If yes, how would these
global variables be initialized, the module containing the caller’s source
code or the module containing the callee’s source code?
I was thinking NULL initialized static variables (pointers to the actual 
data/called function) – as weak symbol, i.e. in every translation unit 
which is compiled with the arg-checking flag. The linker will choose one 
of the identical symbols and place it (on most systems) in the BSS.

Do we plan to do the instrumentation for runtime check inline in the IR
itself (inline monitoring)? Or can we write a runtime library that does the
checking, and we just insert calls to the runtime library routine at
compile time?
Either works – but I think it might be simpler to write and avoids a lot 
of string constants if the actual check is done in libgfortran.

3.
Do we need to handle multithreaded programs? How will we handle the race
condition in which two different threads call an external procedure at the
same time?


Shouldn't that work if we use a thread local/private variable ('__thread',
"set_decl_tls_model (decl, decl_default_tls_model (decl));").

In any case, it would be useful:

(a) combining code which does argument checking with code which does not

This means we cannot simply add anything which changes the ABI unless it 
is guaranteed to also work when the called procedure is not instrumented 
or when an instrumented procedure is called.


(b) avoid race conditions


4.
How will we identify the procedures which require the run-time check? I
mean, do we need to write a static analysis to figure out which functions
are called externally?


My idea was that -fcheck=argcheck will simply annotate all calls and 
procedures, except
intrinsic procedures, internal procedures, module procedures – we could 
argue about bind(C)

and about procedures in the same translation unit (that's known).

Tobias


Re: [Patch, fortran] 99307 - FAIL: gfortran.dg/class_assign_4.f90 execution test

2021-04-10 Thread Tobias Burnus

Dear Paul,

sorry for the belate reply. I think you forgot to attach the patch.

Tobias

On 06.04.21 19:08, Paul Richard Thomas via Fortran wrote:

Hi Tobias,

I believe that the attached fixes the problems that you found with
gfc_find_and_cut_at_last_class_ref.

I will test:
type1%type%array_class2 → NULL is returned  (why?)
class1%type%array_class2 → ts = class1 but array2_class is used later on
(ups!)
class1%...%scalar_class2 → ts = class1 but scalar_class2 is used

The ChangeLogs remain the same, apart from the date.

Regtests OK on FC33/x86_64.

Paul


On Mon, 29 Mar 2021 at 14:58, Tobias Burnus  wrote:


Hi all,

as preremark I want to note that the testcase class_assign_4.f90
was added for PR83118/PR96012 (fixes problems in handling class objects,
Dec 18, 2020)
and got revised for PR99124 (class defined operators, Feb 23, 2021).
Both patches were then also applied to GCC 9 and 10.

On 26.03.21 17:30, Paul Richard Thomas via Gcc-patches wrote:

This patch comes in two versions: submit.diff with Change.Logs or
submit2.diff with Change2.Logs.
The first fixes the problem by changing array temporaries from class
expressions into class temporaries. This permits the use of
gfc_get_class_from_expr to obtain the vptr for these temporaries and all
the good things that come with that when handling dynamic types. The

second

part of the fix is to use the array element length from the class
descriptor, when reallocating on assignment. This is needed because the
vptr is being set too early. I will set about trying to track down why

this

is happening and fix it after release.

The second version does the same as the first but puts in place a load of
tidying up that is permitted by the fix to class array temporaries.
I couldn't readily see how to prepare a testcase - ideas?
Both regtest on FC33/x86_64. The first was tested by Dominique (see the
PR). OK for master?

Typo – underscore-'c' should be a dot-'c' – both changelog files


   * trans-expr_c (gfc_trans_scalar_assign): Make use of pre and

I think the second longer version is nicer in general, but at least for
GCC 9/GCC10 the first version is simpler and, hence, less error prone.

As you only ask about mainline, I would prefer the second one.

However, I am not happy about gfc_find_and_cut_at_last_class_ref:


+ of refs following. If ts is non-null the cut is at the class entity
+ or component that is followed by an array reference, which is not +
an element. */ ... + + if (ts) + { + if (e->symtree + &&
e->symtree->n.sym->ts.type == BT_CLASS) + *ts =
&e->symtree->n.sym->ts; + else + *ts = NULL; + } + for (ref = e->ref;
ref; ref = ref->next) { + if (ts && ref->type == REF_COMPONENT + &&
ref->u.c.component->ts.type == BT_CLASS + && ref->next &&
ref->next->type == REF_COMPONENT + && strcmp
(ref->next->u.c.component->name, "_data") == 0 + && ref->next->next +
&& ref->next->next->type == REF_ARRAY + && ref->next->next->u.ar.type
!= AR_ELEMENT) + { + *ts = &ref->u.c.component->ts; + class_ref = ref;
+ break; + } + + if (ts && *ts == NULL) + return NULL; +

Namely, if there is:
type1%array_class2 → array_class2 is used for 'ts' and later (ok)
type1%type%array_class2 → NULL is returned  (why?)
class1%type%array_class2 → ts = class1 but array2_class is used later
on (ups!)
class1%...%scalar_class2 → ts = class1 but scalar_class2 is used
etc.

Thus this either needs to be cleaned up (separate 'ref' loop for
ts != NULL) – including the wording in the description which tells what
happens if 'ts' is passed as arg but the expr has rank == 0 – and
what value is assigned to 'ts'. (You can then also fix 'class.c::' to
'class.c: ' in the description above the function.)

Alternatively, you can leave the current code ref handling code in place
at build_class_array_ref, which might be the simpler alternative.

Otherwise, it looks sensible to me.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank
Thürauf





Re: [Patch, fortran] PR fortran/100018 - ICE on missing polymorphic argument

2021-04-10 Thread José Rui Faustino de Sousa via Fortran

On 10/04/21 17:37, Tobias Burnus wrote:
And you need an additional single-line summary for git – which should be 
part of the patch submission.




Fortran: Fix ICE due to referencing a NULL pointer [PR100018]

gcc/fortran/ChangeLog:

PR fortran/100018
* resolve.c: Add association check before de-referencing
pointer.


gcc/testsuite/ChangeLog:

PR fortran/100018
* gfortran.dg/PR10018.f90: New test.


Thank you very much.

Best regards,
José Rui


[Patch, fortran] PR fortran/100024 PR fortran/100025 ICE on subroutine missing explicit interface

2021-04-10 Thread José Rui Faustino de Sousa via Fortran

Hi all!

Proposed patch to PR100024 & PR100025 - ICE on missing polymorphic argument.

Patch tested only on x86_64-pc-linux-gnu.

Remove assertion checking for possible assumed rank arrays and added an 
explicit error message.


Change if clause to allow the handling of assumed-rank arrays as arrays.

Thank you very much.

Best regards,
José Rui

Fortran: Fix ICE on the handling of assumed-rank procedures 
[PR100024/PR100025]


gcc/fortran/ChangeLog:

* interface.c (argument_rank_mismatch): Remove assertion and add
an explicit error message.
(gfc_get_formal_from_actual_arglist): Allow handling of
assume-rank arrays.

gcc/testsuite/ChangeLog:

* gfortran.dg/PR100024.f90: New test.
* gfortran.dg/PR100025.f90: New test.


diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 60736123550..5868bf23f11 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -2237,8 +2237,11 @@ argument_rank_mismatch (const char *name, locus *where,
 }
   else
 {
-  gcc_assert (rank2 != -1);
-  if (rank1 == 0)
+  if (rank2 == -1)
+	gfc_error_opt (0, "The assumed-rank array actual argument at %L and "
+		   "actual argument at %L are ambiguous, an explicit "
+		   "interface is required.", where, where_formal);
+  else if (rank1 == 0)
 	gfc_error_opt (0, "Rank mismatch between actual argument at %L "
 		   "and actual argument at %L (scalar and rank-%d)",
 		   where, where_formal, rank2);
@@ -5358,7 +5361,7 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym,
 	  s->ts.is_iso_c = 0;
 	  s->ts.is_c_interop = 0;
 	  s->attr.flavor = FL_VARIABLE;
-	  if (a->expr->rank > 0)
+	  if (a->expr->rank)
 		{
 		  s->attr.dimension = 1;
 		  s->as = gfc_get_array_spec ();
diff --git a/gcc/testsuite/gfortran.dg/PR100024.f90 b/gcc/testsuite/gfortran.dg/PR100024.f90
new file mode 100644
index 000..fe82ef6da0a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100024.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+!
+program foobar
+
+  implicit none
+
+  type :: foo_t
+  end type foo_t
+
+  class(foo_t), pointer :: a
+  type(foo_t),   target :: b
+
+  call bar1(a)
+  call bar2(b)
+  stop
+
+contains
+  
+  subroutine bar1(this)
+class(foo_t), pointer, intent(in) :: this(..)
+
+call foo(this)
+return
+  end subroutine bar1
+
+  subroutine bar2(this)
+type(foo_t), pointer, intent(in) :: this(..)
+
+call foo(this)
+return
+  end subroutine bar2
+  
+end program foobar
+! { dg-error "Explicit interface required for polymorphic argument at \\\(1\\\)" "" { target "*-*-*" } 22 }
+! { dg-excess-errors "" }
+
+
diff --git a/gcc/testsuite/gfortran.dg/PR100025.f90 b/gcc/testsuite/gfortran.dg/PR100025.f90
new file mode 100644
index 000..ef8b58ad94a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100025.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+!
+program foo_p
+
+  implicit none
+
+  class(*), pointer :: a
+  
+  call foo(a)
+  call sub_s(a)
+  stop
+
+contains
+  
+  subroutine bar_s(this)
+class(*), intent(in) :: this(..)
+
+call foo(this)
+return
+  end subroutine bar_s
+  
+end program foo_p
+! { dg-error "Explicit interface required for polymorphic argument at \\\(1\\\)" "" { target "*-*-*" } 10 }
+! { dg-excess-errors "" }
+


[Patch, fortran] PR fortran/84006, PR fortran/100027 - ICE on storage_size with polymorphic argument

2021-04-10 Thread José Rui Faustino de Sousa via Fortran

Hi All!

Proposed patch to:
PR84006 - [8/9/10/11 Regression] ICE in storage_size() with CLASS entity
PR100027 - ICE on storage_size with polymorphic argument

Patch tested only on x86_64-pc-linux-gnu.

Add branch to if clause to handle polymorphic objects, not sure if I got 
all possible variations...


Thank you very much.

Best regards,
José Rui

Fortran: Fix ICE using storage_size intrinsic [PR84006, PR100027]

gcc/fortran/ChangeLog:

PR fortran/84006
PR fortran/100027
* trans-intrinsic.c (gfc_conv_intrinsic_storage_size): add if
clause branch to handle polymorphic objects.

gcc/testsuite/ChangeLog:

PR fortran/84006
* gfortran.dg/PR84006.f90: New test.

PR fortran/100027
* gfortran.dg/PR100027.f90: New test.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 5e53d1162fa..6536c121f2b 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -8353,10 +8353,16 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
   if (arg->ts.type == BT_CLASS)
 	{
 	  if (arg->rank > 0)
-	tmp = gfc_class_vtab_size_get (
-		 GFC_DECL_SAVED_DESCRIPTOR (arg->symtree->n.sym->backend_decl));
+	{
+	  if (TREE_CODE (argse.expr) == COMPONENT_REF)
+		tmp = TREE_OPERAND (argse.expr, 0);
+	  else
+		tmp = GFC_DECL_SAVED_DESCRIPTOR (
+		  arg->symtree->n.sym->backend_decl);
+	}
 	  else
-	tmp = gfc_class_vtab_size_get (TREE_OPERAND (argse.expr, 0));
+	tmp = TREE_OPERAND (argse.expr, 0);
+	  tmp = gfc_class_vtab_size_get (tmp);
 	  tmp = fold_convert (result_type, tmp);
 	  goto done;
 	}
diff --git a/gcc/testsuite/gfortran.dg/PR100027.f90 b/gcc/testsuite/gfortran.dg/PR100027.f90
new file mode 100644
index 000..dc565872cac
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100027.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+!
+
+program foo_p
+
+  implicit none
+
+  integer, parameter :: n = 11
+  
+  type :: foo_t
+  end type foo_t
+
+  type, extends(foo_t) :: bar_t
+  end type bar_t
+
+  class(*), pointer :: apu(:)
+  class(foo_t), pointer :: apf(:)
+  class(bar_t), pointer :: apb(:)
+  type(bar_t),   target :: atb(n)
+
+  integer :: m
+  
+  apu => atb
+  m = storage_size(apu)
+  apf => atb
+  m = storage_size(apf)
+  apb => atb
+  m = storage_size(apb)
+
+end program foo_p
+
diff --git a/gcc/testsuite/gfortran.dg/PR84006.f90 b/gcc/testsuite/gfortran.dg/PR84006.f90
new file mode 100644
index 000..41e2161b6e5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR84006.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+!
+
+program p
+  type t
+integer i
+  end type
+  integer rslt
+  class(t), allocatable :: t_alloc(:)
+  allocate (t_alloc(10), source=t(1))
+  rslt = storage_size(t_alloc)
+end program p