diff mbox

[Fortran] PR 47399 - fix half of the PR: ICE with PARAMETER TBP

Message ID 4D3AAEDA.2010807@net-b.de
State New
Headers show

Commit Message

Tobias Burnus Jan. 22, 2011, 10:18 a.m. UTC
The fix for the ICE is simple: Just modifying the gcc_assert is enough.

The patch below only fixes that part.
OK for the trunk?

  * * *

The accept invalid part of the PR is much harder. Seemingly someone 
could not correctly read when creating gfc_is_constant_expr as the 
function also allows specification expressions.

Fortran 95 has two confusing close concepts, initialization expressions 
and constant expressions; both reduce to a constant at compile time - 
and I have not yet fully deciphered what their difference is. In Fortran 
2003 both are combined to "initialization expressions" and Fortran 2008 
renamed those to "constant expressions".

Thus, changing gfc_is_constant_expr should be done, but the problem is 
that some of the callers indeed want to check for specification 
expressions (or something related like restricted expressions or ...). 
Thus, one needs to go through F95/F2003/F2008 and check the concepts and 
then check all 56 callers of gfc_is_constant_expr to see which check 
they actually want...

Tobias

Comments

Jerry DeLisle Jan. 22, 2011, 1:44 p.m. UTC | #1
On 01/22/2011 02:18 AM, Tobias Burnus wrote:
> The fix for the ICE is simple: Just modifying the gcc_assert is enough.
>
> The patch below only fixes that part.
> OK for the trunk?

Yes, OK

Regarding below, to which standard do we accept invalid?  If it is pre F2003 or 
F2008, I would forget about it.  Who cares?

Jerry

>
> * * *
>
> The accept invalid part of the PR is much harder. Seemingly someone could not
> correctly read when creating gfc_is_constant_expr as the function also allows
> specification expressions.
>
> Fortran 95 has two confusing close concepts, initialization expressions and
> constant expressions; both reduce to a constant at compile time - and I have not
> yet fully deciphered what their difference is. In Fortran 2003 both are combined
> to "initialization expressions" and Fortran 2008 renamed those to "constant
> expressions".
>
> Thus, changing gfc_is_constant_expr should be done, but the problem is that some
> of the callers indeed want to check for specification expressions (or something
> related like restricted expressions or ...). Thus, one needs to go through
> F95/F2003/F2008 and check the concepts and then check all 56 callers of
> gfc_is_constant_expr to see which check they actually want...
>
> Tobias
Tobias Burnus Jan. 22, 2011, 1:52 p.m. UTC | #2
Jerry DeLisle wrote:
> Regarding below, to which standard do we accept invalid?  If it is pre 
> F2003 or F2008, I would forget about it.  Who cares?

Well, it is still invalid in Fortran 2008. Besides, the command is used 
56 times - I think the chance that it potentially causes several ICE, 
accept invalid and possible also reject-valid is rather high ...

I committed the gcc_assert fix as Rev. 169126.
Thanks for the review!

Tobias
Jerry DeLisle Jan. 22, 2011, 2:19 p.m. UTC | #3
On 01/22/2011 05:52 AM, Tobias Burnus wrote:
> Jerry DeLisle wrote:
>> Regarding below, to which standard do we accept invalid? If it is pre F2003 or
>> F2008, I would forget about it. Who cares?
>
> Well, it is still invalid in Fortran 2008. Besides, the command is used 56 times
> - I think the chance that it potentially causes several ICE, accept invalid and
> possible also reject-valid is rather high ...
>

Then we better keep it in sight for fixing. I was hoping it was a case where the 
later standard relaxed a requirement. Thanks.

> I committed the gcc_assert fix as Rev. 169126.
> Thanks for the review!
>
> Tobias
>
Steve Kargl Jan. 22, 2011, 7 p.m. UTC | #4
On Sat, Jan 22, 2011 at 11:18:02AM +0100, Tobias Burnus wrote:
> 
> The accept invalid part of the PR is much harder. Seemingly someone 
> could not correctly read when creating gfc_is_constant_expr as the 
> function also allows specification expressions.
> 
> Fortran 95 has two confusing close concepts, initialization expressions 
> and constant expressions; both reduce to a constant at compile time - 
> and I have not yet fully deciphered what their difference is. In Fortran 
> 2003 both are combined to "initialization expressions" and Fortran 2008 
> renamed those to "constant expressions".
> 
> Thus, changing gfc_is_constant_expr should be done, but the problem is 
> that some of the callers indeed want to check for specification 
> expressions (or something related like restricted expressions or ...). 
> Thus, one needs to go through F95/F2003/F2008 and check the concepts and 
> then check all 56 callers of gfc_is_constant_expr to see which check 
> they actually want...
> 

I suspect that there are definitely many obscure bugs
lurking in the constant/initialization/specification
handling.  There are at least 10 PR about c/i/s
statements.  I stop counting when I found PR 38822,
which was the one I was looking for.  This is a PR
due to James van Buskirk code.  See comment #8 for
one (subtle?) difference between i and s statements.

For the record: 25095, 25104, 29962, 31292, 31560,
31592, 32365, 34663, 35040, and 38822.

PS: I think we can close 32151.  The error message may
not be too appropriate, but with trunk the error locus
points right at the problem.
diff mbox

Patch

2011-01-22  Tobias Burnus  <burnus@net-b.de>

	PR fortran/47399
	* primary.c (gfc_match_varspec): Relax gcc_assert to allow for
	PARAMETER TBP.

2011-01-22  Tobias Burnus  <burnus@net-b.de>

	PR fortran/47399
	* gfortran.dg/typebound_proc_19.f90: New.

diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index ed85398..360176e 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1843,7 +1843,10 @@  gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
 	    return MATCH_ERROR;
 
 	  gcc_assert (!tail || !tail->next);
-	  gcc_assert (primary->expr_type == EXPR_VARIABLE);
+	  gcc_assert (primary->expr_type == EXPR_VARIABLE
+		      || (primary->expr_type == EXPR_STRUCTURE
+			  && primary->symtree && primary->symtree->n.sym
+			  && primary->symtree->n.sym->attr.flavor));
 
 	  if (tbp->n.tb->is_generic)
 	    tbp_sym = NULL;
diff --git a/gcc/testsuite/gfortran.dg/typebound_proc_19.f90 b/gcc/testsuite/gfortran.dg/typebound_proc_19.f90
new file mode 100644
index 0000000..be15bf0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_proc_19.f90
@@ -0,0 +1,43 @@ 
+! { dg-do compile }
+!
+! PR fortran/47399
+!
+! Contributed by Wolfgang Kilian.
+!
+
+module mytypes
+   implicit none
+   private
+   public :: mytype, get_i
+
+   integer, save :: i_priv = 13
+   type :: mytype
+      integer :: dummy
+    contains
+      procedure, nopass :: i => get_i
+   end type mytype
+ contains
+   pure function get_i () result (i)
+     integer :: i
+     i = i_priv
+   end function get_i
+end module mytypes
+
+subroutine test()
+   use mytypes
+   implicit none
+
+   type(mytype) :: a
+   type(mytype), parameter :: a_const = mytype (0)
+   integer, dimension (get_i()) :: x            ! #1
+   integer, dimension (a%i()) :: y              ! #2
+   integer, dimension (a_const%i()) :: z        ! #3
+
+   if (size (x) /= 13 .or. size(y) /= 13 .or. size(z) /= 13) call abort()
+!   print *, size (x), size(y), size(z)
+end subroutine test
+
+call test()
+end
+
+! { dg-final { cleanup-modules "mytypes" } }