Re: [Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-30 Thread Paul Richard Thomas
Hi Thomas,

I tried failing cases of that kind; or assignment to len/kind part refs and
returned correct errors. Must check where I was going wrong.

Paul from a chilly Garching-bei-Muenchen


On Sun, 28 Oct 2018, 13:38 Thomas Koenig  Hi Paul,
>
>
> >> inq would be easier to understand and unambiguous imho.
> >
> > Why? inquiry_type seems fine to me.
>
> I think Bernhard means the name of the member, i.
>
> I think it makes sense to leave as it is - gfc_ref is a
> struct that occurs a lot in complicated expressions, and the other
> members are one and two letters, too.
>
> > snip
> >> Is the switch really worth it? I'd have used a plain chain of strcmp,
> >> fwiw.
> >
> > I have done it. However, I might revert in order to combine the switch
> > block where I set the typespec for the primary expression.
>
> Whatever suits you best.
>
> > I haven't added testcases for errors. Does anybody think that this is
> necessary?
>
> Might not be a bad idea to run through at least each new error message
> again.
>
> There is one illwfL test case which ICEs:
>
> $ cat b.f90
> program main
>character(len=:), allocatable :: a
>allocate(a,source="abc")
>a%len = 2
>print *,a
> end
> $ gfortran b.f90
> gimplification failed:
> (integer(kind=4)) .a   type   size 
>  unit-size 
>  align:32 warn_if_not_align:0 symtab:0 alias-set -1
> canonical-type 0x7f138acd15e8 precision:32 min  0x7f138acbcd68 -2147483648> max 
>  pointer_to_this >
>
>  arg:0   type   size 
>  unit-size 
>  align:64 warn_if_not_align:0 symtab:0 alias-set -1
> canonical-type 0x7f138acd1738 precision:64 min  0x7f138acbcdf8 -9223372036854775808> max  9223372036854775807>
>  pointer_to_this >
>  used DI b.f90:1:0 size 
> unit-size 
>  align:64 warn_if_not_align:0 context  0x7f138ae83200 MAIN__>
>  chain  0x7f138ae82540>
>  used unsigned DI b.f90:2:0 size  64> unit-size 
>  align:64 warn_if_not_align:0 context  0x7f138ae83200 MAIN__
> b.f90:4:0:
>
>  4 |   a%len = 2
>|
> internal compiler error: gimplification failed
> 0xb45602 gimplify_expr(tree_node**, gimple**, gimple**, bool
> (*)(tree_node*), int)
>  ../../trunk/gcc/gimplify.c:12568
>
> Regards
>
> Thomas
>


Re: [Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-29 Thread Paul Richard Thomas
Hi Thomas,

Thanks for finding the assignment a%len = 2 that escapes the check for
lvalues. I am back home tomorrow night and will investigate why this
one evades the trap. I think that an error test is needed in
expr.c(gfc_check_assign).

Cheers

Paul

On Sun, 28 Oct 2018 at 13:38, Thomas Koenig  wrote:
>
> Hi Paul,
>
>
> >> inq would be easier to understand and unambiguous imho.
> >
> > Why? inquiry_type seems fine to me.
>
> I think Bernhard means the name of the member, i.
>
> I think it makes sense to leave as it is - gfc_ref is a
> struct that occurs a lot in complicated expressions, and the other
> members are one and two letters, too.
>
> > snip
> >> Is the switch really worth it? I'd have used a plain chain of strcmp,
> >> fwiw.
> >
> > I have done it. However, I might revert in order to combine the switch
> > block where I set the typespec for the primary expression.
>
> Whatever suits you best.
>
> > I haven't added testcases for errors. Does anybody think that this is 
> > necessary?
>
> Might not be a bad idea to run through at least each new error message
> again.
>
> There is one illwfL test case which ICEs:
>
> $ cat b.f90
> program main
>character(len=:), allocatable :: a
>allocate(a,source="abc")
>a%len = 2
>print *,a
> end
> $ gfortran b.f90
> gimplification failed:
> (integer(kind=4)) .a   type   size 
>  unit-size 
>  align:32 warn_if_not_align:0 symtab:0 alias-set -1
> canonical-type 0x7f138acd15e8 precision:32 min  0x7f138acbcd68 -2147483648> max 
>  pointer_to_this >
>
>  arg:0   type   size 
>  unit-size 
>  align:64 warn_if_not_align:0 symtab:0 alias-set -1
> canonical-type 0x7f138acd1738 precision:64 min  0x7f138acbcdf8 -9223372036854775808> max  9223372036854775807>
>  pointer_to_this >
>  used DI b.f90:1:0 size 
> unit-size 
>  align:64 warn_if_not_align:0 context  0x7f138ae83200 MAIN__>
>  chain 
>  used unsigned DI b.f90:2:0 size  64> unit-size 
>  align:64 warn_if_not_align:0 context  0x7f138ae83200 MAIN__
> b.f90:4:0:
>
>  4 |   a%len = 2
>|
> internal compiler error: gimplification failed
> 0xb45602 gimplify_expr(tree_node**, gimple**, gimple**, bool
> (*)(tree_node*), int)
>  ../../trunk/gcc/gimplify.c:12568
>
> Regards
>
> Thomas



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Re: [Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-28 Thread Thomas Koenig

Hi Paul,



inq would be easier to understand and unambiguous imho.


Why? inquiry_type seems fine to me.


I think Bernhard means the name of the member, i.

I think it makes sense to leave as it is - gfc_ref is a
struct that occurs a lot in complicated expressions, and the other
members are one and two letters, too.


snip

Is the switch really worth it? I'd have used a plain chain of strcmp,
fwiw.


I have done it. However, I might revert in order to combine the switch
block where I set the typespec for the primary expression.


Whatever suits you best.


I haven't added testcases for errors. Does anybody think that this is necessary?


Might not be a bad idea to run through at least each new error message
again.

There is one illwfL test case which ICEs:

$ cat b.f90
program main
  character(len=:), allocatable :: a
  allocate(a,source="abc")
  a%len = 2
  print *,a
end
$ gfortran b.f90
gimplification failed:
(integer(kind=4)) .a 
unit-size 
align:32 warn_if_not_align:0 symtab:0 alias-set -1 
canonical-type 0x7f138acd15e8 precision:32 min 0x7f138acbcd68 -2147483648> max 

pointer_to_this >

arg:0 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set -1 
canonical-type 0x7f138acd1738 precision:64 min 0x7f138acbcdf8 -9223372036854775808> max 9223372036854775807>

pointer_to_this >
used DI b.f90:1:0 size  
unit-size 
align:64 warn_if_not_align:0 context 0x7f138ae83200 MAIN__>

chain 
used unsigned DI b.f90:2:0 size 64> unit-size 
align:64 warn_if_not_align:0 context 0x7f138ae83200 MAIN__

b.f90:4:0:

4 |   a%len = 2
  |
internal compiler error: gimplification failed
0xb45602 gimplify_expr(tree_node**, gimple**, gimple**, bool 
(*)(tree_node*), int)

../../trunk/gcc/gimplify.c:12568

Regards

Thomas


Re: [Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-28 Thread Paul Richard Thomas
Hi Bernhard,

Thanks for going through the patch:
snip
> missing space before open parenthesis

Corrected.
snip
> inq would be easier to understand and unambiguous imho.

Why? inquiry_type seems fine to me.

snip
> Is the switch really worth it? I'd have used a plain chain of strcmp,
> fwiw.

I have done it. However, I might revert in order to combine the switch
block where I set the typespec for the primary expression.

snip
> I guess RE and IM should be capitalised?

Done

> you could break here
>
> > +
> > for (ref = expr->ref; ref; ref = ref->next)
> >   switch (ref->type)
> > {

Done

>
> > Index: gcc/fortran/trans-expr.c
snip...

> Don't you have to gfc_free_expr (se->expr) or gfc_replace_expr() ?

No these are tree expressions not gfc_expr. No cleanup is needed.

I haven't added testcases for errors. Does anybody think that this is necessary?

Cheers

Paul


Re: [Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-28 Thread Bernhard Reutner-Fischer
On Sat, 27 Oct 2018 20:03:47 +0100
Paul Richard Thomas  wrote:

A few nits.

> + /* Pull an inquiry result out of an expression.  */
> + 
> + static bool
> + find_inquiry_ref (gfc_expr *p, gfc_expr **newp)
> + {
> +   gfc_ref *ref;
> +   gfc_ref *inquiry = NULL;
> +   gfc_expr *tmp;
> + 
> +   tmp = gfc_copy_expr (p);
> + 
> +   if (tmp->ref && tmp->ref->type == REF_INQUIRY)
> + {
> +   inquiry = tmp->ref;
> +   tmp->ref = NULL;
> + }
> +   else
> + {
> +   for (ref = tmp->ref; ref; ref = ref->next)
> + if (ref->next && ref->next->type == REF_INQUIRY)
> +   {
> + inquiry = ref->next;
> + ref->next = NULL;
> +   }
> + }
> + 
> +   if(!inquiry)

missing space before open parenthesis

> *** typedef struct gfc_ref
> *** 1960,1965 
> --- 1963,1970 
>   }
>   ss;
>   
> + inquiry_type i;

inq would be easier to understand and unambiguous imho.

> + /* Used by gfc_match_varspec() to match an inquiry reference.  */
> + 
> + static bool
> + is_inquiry_ref (const char *name, gfc_ref **ref)
> + {
> +   inquiry_type type;
> + 
> +   if (name == NULL)
> + return false;
> + 
> +   if (ref) *ref = NULL;
> + 
> +   switch (name[0])
> + {
> + case 'r':
> +   if (strcmp (name, "re") == 0)
> + type = INQUIRY_RE;
> +   else
> + return false;
> +   break;
> + 
> + case 'i':
> +   if (strcmp (name, "im") == 0)
> + type = INQUIRY_IM;
> +   else
> + return false;
> +   break;
> + 
> + case 'k':
> +   if (strcmp (name, "kind") == 0)
> + type = INQUIRY_KIND;
> +   else
> + return false;
> +   break;
> + 
> + case 'l':
> +   if (strcmp (name, "len") == 0)
> + type = INQUIRY_LEN;
> +   else
> + return false;
> +   break;
> + 
> + default:
> +   return false;
> + }

Is the switch really worth it? I'd have used a plain chain of strcmp,
fwiw.

> !   switch (tmp->u.i)
> ! {
> ! case INQUIRY_RE:
> ! case INQUIRY_IM:
> !   if (!gfc_notify_std (GFC_STD_F2008, "re or im
> part_refs at %C")) !  return MATCH_ERROR;

I guess RE and IM should be capitalised?

> *** gfc_variable_attr (gfc_expr *expr, gfc_t
> *** 2358,2363 
> --- 2521,2527 
> gfc_ref *ref;
> gfc_symbol *sym;
> gfc_component *comp;
> +   bool has_inquiry_part;
>   
> if (expr->expr_type != EXPR_VARIABLE && expr->expr_type !=
> EXPR_FUNCTION) gfc_internal_error ("gfc_variable_attr(): Expression
> isn't a variable"); *** gfc_variable_attr (gfc_expr
> *expr, gfc_t *** 2387,2392 
> --- 2551,2561 
> if (ts != NULL && expr->ts.type == BT_UNKNOWN)
>   *ts = sym->ts;
>   
> +   has_inquiry_part = false;
> +   for (ref = expr->ref; ref; ref = ref->next)
> + if (ref->type == REF_INQUIRY)
> +   has_inquiry_part = true;

you could break here

> + 
> for (ref = expr->ref; ref; ref = ref->next)
>   switch (ref->type)
> {

> Index: gcc/fortran/trans-expr.c
> ===
> *** gcc/fortran/trans-expr.c  (revision 265411)
> --- gcc/fortran/trans-expr.c  (working copy)
> *** conv_parent_component_references (gfc_se
> *** 2510,2515 
> --- 2510,2549 
> conv_parent_component_references (se, );
>   }
>   
> + 
> + static void
> + conv_inquiry (gfc_se * se, gfc_ref * ref, gfc_expr *expr,
> gfc_typespec *ts)
> + {
> +   tree res = se->expr;
> + 
> +   switch (ref->u.i)
> + {
> + case INQUIRY_RE:
> +   res = fold_build1_loc (input_location, REALPART_EXPR,
> +  TREE_TYPE (TREE_TYPE (res)), res);
> +   break;
> + 
> + case INQUIRY_IM:
> +   res = fold_build1_loc (input_location, IMAGPART_EXPR,
> +  TREE_TYPE (TREE_TYPE (res)), res);
> +   break;
> + 
> + case INQUIRY_KIND:
> +   res = build_int_cst (gfc_typenode_for_spec (>ts),
> +ts->kind);
> +   break;
> + 
> + case INQUIRY_LEN:
> +   res = fold_convert (gfc_typenode_for_spec (>ts),
> +   se->string_length);
> +   break;
> + 
> + default:
> +   gcc_unreachable ();
> + }
> +   se->expr = res;

Don't you have to gfc_free_expr (se->expr) or gfc_replace_expr() ?

cheers,


[Patch, fortran] PR40196 - [F03] [F08] Type parameter inquiry (str%len, a%kind) and Complex parts (z%re, z%im)

2018-10-27 Thread Paul Richard Thomas
I was triggered to do this by one of the comments in response to Anton
Shterenlikht's standards survey. The comment was sufficiently
inconsiderate that my first thought was not to respond. However,
curiosity got the better of me... so said the dead cat!

There is a lot of this patch but it is (more or less) straight
forward. The tricky parts were to get the logic right in
gfc_match_varspec and in expr.c. One more step on the way to real
F2002 and F2008 compliance!

Bootstraps and regtests on FC28/x86_64 - OK for trunk?

Paul

2018-10-27  Paul Thomas  

PR fortran/40196
* dependency.c (are_identical_variables): Return false if the
inquiry refs are not the same.
(gfc_ref_needs_temporary_p): Break on an inquiry ref.
* dump_parse_tree.c (show_ref): Show the inquiry ref type.
* expr.c (gfc_free_ref_list): Break on an inquiry ref.
(gfc_copy_ref): Copy the inquiry ref types.
(find_inquiry_ref): New function.
(simplify_const_ref, simplify_ref_chain): Call it. Add new arg
to simplify_ref_chain.
(gfc_simplify_expr): Use the new arg in call to
simplify_ref_chain.
(gfc_get_full_arrayspec_from_expr, gfc_is_coarray): Break on
inquiry ref.
(gfc_traverse_expr): Return true for inquiry ref.
* frontend-passes.c (gfc_expr_walker): Break on inquiry ref.
* gfortran.h : Add enums and union member in gfc_ref to
implement inquiry refs.
* intrinsic.c : Fix white nois.
* match.c (gfc_match_assignment): A constant lavlue is an
error.
* module.c : Add DECL_MIO_NAME for inquiry_type and the mstring
for inquiry_types.
(mio_ref): Handle inquiry refs.
* primary.c (is_inquiry_ref): New function.
(gfc_match_varspec): Handle inquiry refs calling new function.
(gfc_variable_attr): Detect inquiry ref for disambiguation
with components.
(caf_variable_attr): Treat inquiry and substring refs in the
same way.
* resolve.c (find_array_spec): ditto.
(gfc_resolve_substring_charlen): If there is neither a charlen
ref not an inquiry ref, return.
(resolve_ref): Handle inqiry refs as appropriate.
(resolve_allocate_expr): ENtities with an inquiry ref cannot be
allocated.
* simplify.c (simplify_bound, simplify_cobound): Punt on
inquiry refs.
* trans-array.c (get_array_ctor_var_strlen): Break on inquiry
ref.
*trans-expr.c (conv_inquiry): New function.
(gfc_conv_variable): Retain the last typespec to pass to
conv_inquiry on detecting an inquiry ref.


2018-10-27  Paul Thomas  

PR fortran/40196
* gfortran.dg/inquiry_part_ref_1.f08: New test.
Index: gcc/fortran/dependency.c
===
*** gcc/fortran/dependency.c	(revision 265411)
--- gcc/fortran/dependency.c	(working copy)
*** are_identical_variables (gfc_expr *e1, g
*** 189,194 
--- 189,199 
  
  	  break;
  
+ 	case REF_INQUIRY:
+ 	  if (r1->u.i != r2->u.i)
+ 	return false;
+ 	  break;
+ 
  	default:
  	  gfc_internal_error ("are_identical_variables: Bad type");
  	}
*** gfc_ref_needs_temporary_p (gfc_ref *ref)
*** 905,910 
--- 910,916 
  	return subarray_p;
  
case REF_COMPONENT:
+   case REF_INQUIRY:
  	break;
}
  
Index: gcc/fortran/dump-parse-tree.c
===
*** gcc/fortran/dump-parse-tree.c	(revision 265411)
--- gcc/fortran/dump-parse-tree.c	(working copy)
*** show_ref (gfc_ref *p)
*** 308,313 
--- 308,330 
  	fputc (')', dumpfile);
  	break;
  
+   case REF_INQUIRY:
+ 	switch (p->u.i)
+ 	{
+ 	  case INQUIRY_KIND:
+ 	fprintf (dumpfile, " INQUIRY_KIND ");
+ 	break;
+ 	  case INQUIRY_LEN:
+ 	fprintf (dumpfile, " INQUIRY_LEN ");
+ 	break;
+ 	  case INQUIRY_RE:
+ 	fprintf (dumpfile, " INQUIRY_RE ");
+ 	break;
+ 	  case INQUIRY_IM:
+ 	fprintf (dumpfile, " INQUIRY_IM ");
+ 	}
+ 	break;
+ 
default:
  	gfc_internal_error ("show_ref(): Bad component code");
}
*** write_decl (gfc_typespec *ts, gfc_array_
*** 3167,3173 
  
fputs (sym_name, dumpfile);
fputs (post, dumpfile);
! 
if (rok == T_WARN)
  fprintf (dumpfile," /* WARNING: Converting '%s' to interoperable type */",
  	 gfc_typename (ts));
--- 3184,3190 
  
fputs (sym_name, dumpfile);
fputs (post, dumpfile);
! 
if (rok == T_WARN)
  fprintf (dumpfile," /* WARNING: Converting '%s' to interoperable type */",
  	 gfc_typename (ts));
Index: gcc/fortran/expr.c
===
*** gcc/fortran/expr.c	(revision 265411)
--- gcc/fortran/expr.c	(working copy)
*** gfc_free_ref_list (gfc_ref *p)
*** 599,604 
--- 599,605 
  	  break;
  
  	case REF_COMPONENT:
+ 	case REF_INQUIRY:
  	  break;
  	}
  
*** gfc_copy_ref (gfc_ref *src)
*** 756,761 
--- 757,766 
dest->u.c = src->u.c;