[Patch, Fortran] Allow ref'ing PDT's len() in parameter-initializer [PR102003]

2023-07-10 Thread Andre Vehreschild via Fortran
Hi all,

while browsing the pdt meta-bug I came across 102003 and thought to myself:
Well, that one is easy. How foolish of me...

Anyway, the solution attached prevents a pdt_len (or pdt_kind) expression in a
function call (e.g. len() or kind()) to mark the whole expression as a pdt one.
The second part of the patch in simplify.cc then takes care of either generating
the correct component ref or when a constant expression (i.e.
gfc_init_expr_flag is set) is required to look this up from the actual symbol
(not from the type, because there the default value is stored).

Regtested ok on x86_64-linux-gnu/Fedora 37.

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
gcc/fortran/ChangeLog:

* expr.cc (gfc_match_init_expr): Prevent PDT analysis for function
calls.
* simplify.cc (gfc_simplify_len): Replace len() of PDT with pdt
component ref or constant.

gcc/testsuite/ChangeLog:

* gfortran.dg/pdt_33.f03: New test.

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index e418f1f3301..fb6eb76cda7 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -3229,7 +3229,7 @@ gfc_match_init_expr (gfc_expr **result)
   return m;
 }

-  if (gfc_derived_parameter_expr (expr))
+  if (expr->expr_type != EXPR_FUNCTION && gfc_derived_parameter_expr (expr))
 {
   *result = expr;
   gfc_init_expr_flag = false;
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 81680117f70..8fb453d0a54 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -4580,19 +4580,54 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
   return range_check (result, "LEN");
 }
   else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
-	   && e->symtree->n.sym
-	   && e->symtree->n.sym->ts.type != BT_DERIVED
-	   && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
-	   && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
-	   && e->symtree->n.sym->assoc->target->symtree->n.sym
-	   && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym))
-
-/* The expression in assoc->target points to a ref to the _data component
-   of the unlimited polymorphic entity.  To get the _len component the last
-   _data ref needs to be stripped and a ref to the _len component added.  */
-return gfc_get_len_component (e->symtree->n.sym->assoc->target, k);
-  else
-return NULL;
+	   && e->symtree->n.sym)
+{
+  if (e->symtree->n.sym->ts.type != BT_DERIVED
+	 && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
+	 && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
+	 && e->symtree->n.sym->assoc->target->symtree->n.sym
+	 && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree
+->n.sym))
+	/* The expression in assoc->target points to a ref to the _data
+	   component of the unlimited polymorphic entity.  To get the _len
+	   component the last _data ref needs to be stripped and a ref to the
+	   _len component added.  */
+	return gfc_get_len_component (e->symtree->n.sym->assoc->target, k);
+  else if (e->symtree->n.sym->ts.type == BT_DERIVED
+	   && e->ref && e->ref->type == REF_COMPONENT
+	   && e->ref->u.c.component->attr.pdt_string
+	   && e->ref->u.c.component->ts.type == BT_CHARACTER
+	   && e->ref->u.c.component->ts.u.cl->length)
+	{
+	  if (gfc_init_expr_flag)
+	{
+	  /* The actual length of a pdt is in its components.  In the
+		 initializer of the current ref is only the default value.
+		 Therefore traverse the chain of components and pick the correct
+		 one's initializer expressions.  */
+	  for (gfc_component *comp = e->symtree->n.sym->ts.u.derived
+		   ->components; comp != NULL; comp = comp->next)
+		{
+		  if (!strcmp (comp->name, e->ref->u.c.component->ts.u.cl
+			   ->length->symtree->name))
+		return gfc_copy_expr (comp->initializer);
+		}
+	}
+	  else
+	{
+	  gfc_expr *len_expr = gfc_copy_expr (e);
+	  gfc_free_ref_list (len_expr->ref);
+	  len_expr->ref = NULL;
+	  gfc_find_component (len_expr->symtree->n.sym->ts.u.derived, e->ref
+  ->u.c.component->ts.u.cl->length->symtree
+  ->name,
+  false, true, &len_expr->ref);
+	  len_expr->ts = len_expr->ref->u.c.component->ts;
+	  return len_expr;
+	}
+	}
+}
+  return NULL;
 }


diff --git a/gcc/testsuite/gfortran.dg/pdt_33.f03 b/gcc/testsuite/gfortran.dg/pdt_33.f03
new file mode 100644
index 000..c12bd9b411c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_33.f03
@@ -0,0 +1,18 @@
+! { dg-do run }
+!
+! Test the fix for PR102003, where len parameters where not returned as constants.
+!
+! Contributed by Harald Anlauf  
+!
+program pr102003
+  type pdt(n)
+ integer, len :: n = 8
+ character(len=n) :: c
+  end type pdt
+  type(pdt(42)) :: p
+  integer, parameter :: m = len (p% c)
+
+  if (m /= 42) stop 1
+  if (len (p% c) /= 42) stop 2
+end
+


Re: [Patch, Fortran] Allow ref'ing PDT's len() in parameter-initializer [PR102003]

2023-07-10 Thread Harald Anlauf via Fortran

Hi Andre,

thanks for looking into this!

While it fixes the original PR, here is a minor extension of the
testcase that ICEs here with your patch:

program pr102003
  type pdt(n)
 integer, len :: n = 8
 character(len=n) :: c
  end type pdt
  type(pdt(42)) :: p
  integer, parameter :: m = len (p% c)
  integer, parameter :: n = p% c% len

  if (m /= 42) stop 1
  if (len (p% c) /= 42) stop 2
  print *, p% c% len   ! OK
  if (p% c% len  /= 42) stop 3 ! OK
  print *, n   ! ICE
end

I get:

pdt_33.f03:14:27:

   14 |   integer, parameter :: n = p% c% len
  |   1
Error: non-constant initialization expression at (1)
pdt_33.f03:20:31:

   20 |   print *, n   ! ICE
  |   1
internal compiler error: tree check: expected record_type or union_type
or qual_union_type, have integer_type in gfc_conv_component_ref, at
fortran/trans-expr.cc:2757
0x84286c tree_check_failed(tree_node const*, char const*, int, char
const*, ...)
../../gcc-trunk/gcc/tree.cc:8899
0xa6d6fb tree_check3(tree_node*, char const*, int, char const*,
tree_code, tree_code, tree_code)
../../gcc-trunk/gcc/tree.h:3617
0xa90847 gfc_conv_component_ref(gfc_se*, gfc_ref*)
../../gcc-trunk/gcc/fortran/trans-expr.cc:2757
0xa91bbc gfc_conv_variable
../../gcc-trunk/gcc/fortran/trans-expr.cc:3137
0xaa8e9c gfc_conv_expr(gfc_se*, gfc_expr*)
../../gcc-trunk/gcc/fortran/trans-expr.cc:9594
0xaa92ae gfc_conv_expr_reference(gfc_se*, gfc_expr*)
../../gcc-trunk/gcc/fortran/trans-expr.cc:9713
0xad67f6 gfc_trans_transfer(gfc_code*)
../../gcc-trunk/gcc/fortran/trans-io.cc:2607
0xa43cb7 trans_code
../../gcc-trunk/gcc/fortran/trans.cc:2449
0xad37c6 build_dt
../../gcc-trunk/gcc/fortran/trans-io.cc:2051
0xa43cd7 trans_code
../../gcc-trunk/gcc/fortran/trans.cc:2421
0xa84711 gfc_generate_function_code(gfc_namespace*)
../../gcc-trunk/gcc/fortran/trans-decl.cc:7762
0x9d9ca7 translate_all_program_units
../../gcc-trunk/gcc/fortran/parse.cc:6929
0x9d9ca7 gfc_parse_file()
../../gcc-trunk/gcc/fortran/parse.cc:7235
0xa40a1f gfc_be_parse_file
../../gcc-trunk/gcc/fortran/f95-lang.cc:229

The fortran-dump confirms that n is not simplified to a constant.
So while you're at it, do you also see a solution to this variant?

Harald


Am 10.07.23 um 17:48 schrieb Andre Vehreschild via Gcc-patches:

Hi all,

while browsing the pdt meta-bug I came across 102003 and thought to myself:
Well, that one is easy. How foolish of me...

Anyway, the solution attached prevents a pdt_len (or pdt_kind) expression in a
function call (e.g. len() or kind()) to mark the whole expression as a pdt one.
The second part of the patch in simplify.cc then takes care of either generating
the correct component ref or when a constant expression (i.e.
gfc_init_expr_flag is set) is required to look this up from the actual symbol
(not from the type, because there the default value is stored).

Regtested ok on x86_64-linux-gnu/Fedora 37.

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de




Re: [Patch, Fortran] Allow ref'ing PDT's len() in parameter-initializer [PR102003]

2023-07-10 Thread Andre Vehreschild via Fortran

Hi Harald,

I do get why this happens. I still don't get why I have to do this
'optimization' manually. I mean, this rewriting of expressions is needed in
more than one location and most probably already present somewhere. So who
can point me in the right direction?

Regards,
Andre

Andre Vehreschild


Present, Publish, Participate - 2023, Bulgaria

2023-07-10 Thread Science & Education Network via Fortran
Dear Colleagues,

I invite you to participate in six international scientific 
conferences ( https://sci-edu.org/2023 ) that will take place in 
the beautiful city of Burgas, Bulgaria, from August 14th to 
August 26th.

The conferences will cover various topics, including agriculture 
and food, ecology and safety, materials, methods, technology, 
economics and business, education and research, language, 
individual, and society.

These conferences have been held annually for the past 30 years, 
providing an excellent platform for specialists from different 
scientific fields to meet, exchange knowledge, and network with 
one another.

Our open-access scholarly journals (ISP) 
( https://sci-edu.org/publications ) promote interdisciplinary 
research, and your participation will undoubtedly contribute 
significantly to the conference's success.

Please register online ( https://sci-edu.org/2023 ) on the 
conference website to confirm your attendance. If you have any 
questions, please do not hesitate to contact us via email.

Thank you for considering this invitation, and we look forward to 
your participation.


Best regards,

Organizing Committee
International Scientific Events, Bulgaria

Not interested? Stop hearing from us 
( https://sci-edu.org/list ) .

-

© 2023 International Scientific Events, Bulgaria. All Rights 
Reserved.


Can't get the horse out of the gate

2023-07-10 Thread Guy Daniels III via Fortran
Hi and thx in adv. Started this tut
, have TDM-GCC 10.3.0-2 and
Notepad++, am trying diff extensions (.f90, .f03, etc) but nothing giving.
What am I missing?

-- 


*"Make the best of your time while you're here"*


Re: Can't get the horse out of the gate

2023-07-10 Thread Arjen Markus via Fortran
You might be better asking a question on comp.lang.fortran newsgroup or the
Fortran discourse site (https://fortran-lang.discourse.group/). This
mailing list is specifically for the gfortran compiler, not user questions.

Also, I might add, the title and the contents of your message may be
understandable for someone well-versed in your cultural context, but to me
as a mainland European it looked in first instance like spam.

I suggest you formulate more elaborately what you are trying to do and what
you expect to happen. I am not being cynical here, justtrying to help you
to get people interested in helping you out.

Regards,

Arjen

Op di 11 jul 2023 om 07:28 schreef Guy Daniels III via Fortran <
fortran@gcc.gnu.org>:

> Hi and thx in adv. Started this tut
> , have TDM-GCC 10.3.0-2 and
> Notepad++, am trying diff extensions (.f90, .f03, etc) but nothing giving.
> What am I missing?
>
> --
>
>
> *"Make the best of your time while you're here"*
>