Re: *Ping**2 [Patch] Fortran: Fix bind(C) character length checks

2021-07-21 Thread Tobias Burnus

On 16.07.21 14:55, Jerry D wrote:

Good to go Tobias.


Thanks for the review!

I have committed it as
r12-2431-gb3d4011ba10275fbd5d6ec5a16d5aaebbdfb5d3c (+ cherry picked it
to OG11).

The attached and committed version has split the 'Allocatable and
pointer' in two separate gfc_error and removed the hyphen in the array
types as spotted and remarked by Sandra.

Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
commit b3d4011ba10275fbd5d6ec5a16d5aaebbdfb5d3c
Author: Tobias Burnus 
Date:   Wed Jul 21 09:36:48 2021 +0200

Fortran: Fix bind(C) character length checks

gcc/fortran/ChangeLog:

* decl.c (gfc_verify_c_interop_param): Update for F2008 + F2018
changes; reject unsupported bits with 'Error: Sorry,'.
* trans-expr.c (gfc_conv_procedure_call): Fix condition to
For using CFI descriptor with characters.

gcc/testsuite/ChangeLog:

* gfortran.dg/iso_c_binding_char_1.f90: Update dg-error.
* gfortran.dg/pr32599.f03: Use -std=-f2003 + update comment.
* gfortran.dg/bind_c_char_10.f90: New test.
* gfortran.dg/bind_c_char_6.f90: New test.
* gfortran.dg/bind_c_char_7.f90: New test.
* gfortran.dg/bind_c_char_8.f90: New test.
* gfortran.dg/bind_c_char_9.f90: New test.
---
 gcc/fortran/decl.c | 113 -
 gcc/fortran/trans-expr.c   |  18 +-
 gcc/testsuite/gfortran.dg/bind_c_char_10.f90   | 480 +
 gcc/testsuite/gfortran.dg/bind_c_char_6.f90| 262 +++
 gcc/testsuite/gfortran.dg/bind_c_char_7.f90| 261 +++
 gcc/testsuite/gfortran.dg/bind_c_char_8.f90| 249 +++
 gcc/testsuite/gfortran.dg/bind_c_char_9.f90| 188 
 gcc/testsuite/gfortran.dg/iso_c_binding_char_1.f90 |   2 +-
 gcc/testsuite/gfortran.dg/pr32599.f03  |   8 +-
 9 files changed, 1557 insertions(+), 24 deletions(-)

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 413c7a75e0c..05081c40f1e 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -1552,20 +1552,115 @@ gfc_verify_c_interop_param (gfc_symbol *sym)
 	}
 
   /* Character strings are only C interoperable if they have a
- length of 1.  */
-  if (sym->ts.type == BT_CHARACTER && !sym->attr.dimension)
+	 length of 1.  However, as argument they are either iteroperable
+	 when passed as descriptor (which requires len=: or len=*) or
+	 when having a constant length or are always passed by
+	 descriptor.  */
+	  if (sym->ts.type == BT_CHARACTER)
 	{
 	  gfc_charlen *cl = sym->ts.u.cl;
-	  if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT
-  || mpz_cmp_si (cl->length->value.integer, 1) != 0)
+
+	  if (sym->attr.allocatable || sym->attr.pointer)
 		{
-		  gfc_error ("Character argument %qs at %L "
-			 "must be length 1 because "
-			 "procedure %qs is BIND(C)",
-			 sym->name, &sym->declared_at,
-			 sym->ns->proc_name->name);
+		  /* F2018, 18.3.6 (6).  */
+		  if (!sym->ts.deferred)
+		{
+		  if (sym->attr.allocatable)
+			gfc_error ("Allocatable character dummy argument %qs "
+   "at %L must have deferred length as "
+   "procedure %qs is BIND(C)", sym->name,
+   &sym->declared_at, sym->ns->proc_name->name);
+		  else
+			gfc_error ("Pointer character dummy argument %qs at %L "
+   "must have deferred length as procedure %qs "
+   "is BIND(C)", sym->name, &sym->declared_at,
+   sym->ns->proc_name->name);
+		  retval = false;
+		}
+		  else if (!gfc_notify_std (GFC_STD_F2018,
+	"Deferred-length character dummy "
+	"argument %qs at %L of procedure "
+	"%qs with BIND(C) attribute",
+	sym->name, &sym->declared_at,
+	sym->ns->proc_name->name))
+		retval = false;
+		  else if (!sym->attr.dimension)
+		{
+		  /* FIXME: Use CFI array descriptor for scalars.  */
+		  gfc_error ("Sorry, deferred-length scalar character dummy "
+ "argument %qs at %L of procedure %qs with "
+ "BIND(C) not yet supported", sym->name,
+ &sym->declared_at, sym->ns->proc_name->name);
+		  retval = false;
+		}
+		}
+	  else if (sym->attr.value
+		   && (!cl || !cl->length
+			   || cl->length->expr_type != EXPR_CONSTANT
+			   || mpz_cmp_si (cl->length->value.integer, 1) != 0))
+		{
+		  gfc_error ("Character dummy argument %qs at %L must be "
+			 "of length 1 as it has the VALUE attribute",
+			 sym->name, &sym->declared_at);
 		  retval = false;
 		}
+	  else if (!cl || !cl->length)
+		{
+		  /* Assumed length; F2018, 18.3.6 (5)(2).
+		 Uses the CFI array

Re: *Ping**2 [Patch] Fortran: Fix bind(C) character length checks

2021-07-16 Thread Jerry D via Gcc-patches

Good to go Tobias.

Jerry

On 7/14/21 5:50 AM, Burnus, Tobias wrote:

Ping**2

On Juli 8, 2021 I wrote:

*Ping*

I intent to incorporate Sandra's suggestions, except for the beginning of line 
spacing - that's needed to avoid exceeding the 80 character line limit. I did 
not include an updated patch as just pinging is easier on a mobile during 
vacation :-)

Thanks,

Tobias

Loosemore, Sandra wrote:

On 7/1/21 11:08 AM, Tobias Burnus wrote:

Hi all,

this patch came up when discussing Sandra's TS29113 patch internally.
There is presumably also some overlap with José's patches.

This patch tries to rectify the BIND(C) CHARACTER handling on the
diagnostic side, only. That is: what to accept and what
to reject for which Fortran standard.


The rules are:

* [F2003-F2018] Interoperable is character(len=1)
→ F2018, 18.3.1  Interoperability of intrinsic types
(General, unchanged)

* Fortran 2008: In some cases, const-length chars are
permitted as well:
→ F2018, 18.3.4  Interoperability of scalar variables
→ F2018, 18.3.5  Interoperability of array variables
→ F2018, 18.3.6  Interoperability of procedures and procedure interfaces
   [= F2008, 15.3.{4,5,6}
For global vars with bind(C), 18.3.4 + 18.3.5 applies directly (TODO:
Add support, not in this patch)
For passed-by ref dummy arguments, 18.3.4 + 18.3.5 are referenced in
- F2008: R1229  proc-language-binding-spec is language-binding-spec
   C1255 (R1229) 
- F2018, F2018, C1554

While it is not very clearly spelt out, I regard 'char parm[4]'
interoperable with 'character(len=4) :: a', 'character(len=2) :: b(2)'
and 'character(len=1) :: c(4)' for both global variables and for
dummy arguments.

* Fortran 2018/TS29113:  Uses additionally CFI array descriptor
- allocatable, pointer:  must be len=:
- nonallocatable/nonpointer: len=* → implies array descriptor also
  for assumed-size/explicit-size/scalar arguments.
- All which all passed by an array descriptor already without further
  restrictions: assumed-shape, assumed-rank, i.e. len= seems
  to be also fine
→ 18.3.6 under item (5) bullet point 2 and 3 plus (6).


I hope I got the conditions right. I also fixed an issue with
character(len=5) :: str – the code in trans-expr.c did crash for
scalars  (decl.c did not check any constraints for arrays).
I believe the condition is wrong and for len= no descriptor
is used.

Any comments, remarks?

I gave this patch a try on my TS 29113 last night.  Changing the error
messages kind of screwed up my list of FAILs, but I did see that it also
caught some invalid character arguments in
interoperability/typecodes-scalar.f90 and
interoperability/typecodes-scalar-ext.f90 (which are already broken by 2
other major gfortran bugs I still need to file PRs for).  :-S

I haven't tried to review the patch WRT correctness with the
requirements of the standard yet, but I have a few nits about error
messages


+   /* F2018, 18.3.6 (6).  */
+   if (!sym->ts.deferred)
+ {
+   gfc_error ("Allocatable and pointer character dummy "
+  "argument %qs at %L must have deferred length "
+  "as procedure %qs is BIND(C)", sym->name,
+  &sym->declared_at, sym->ns->proc_name->name);
+   retval = false;
+ }

This is the error the two aforementioned test cases started giving, but
message is confusing and doesn't read well (it was a pointer dummy, not
"allocatable and pointer").  Maybe just s/and/or/, or customize the
message depending on which one it is?


+   gfc_error ("Character dummy argument %qs at %L must be "
+  "of constant length or assumed length, "
+  "unless it has assumed-shape or assumed-rank, "
+  "as procedure %qs has the BIND(C) attribute",
+  sym->name, &sym->declared_at,
+  sym->ns->proc_name->name);

I don't think either "assumed-shape" or "assumed-rank" should be
hyphenated in this context unless that exact hyphenation is a term of
art in the Fortran standard or other technical documentation.  In normal
English, adjective phrases are usually only hyphenated when they appear
immediately before the noun they modify; "assumed-shape array", but "an
array with assumed shape".


+   else if (!gfc_notify_std (GFC_STD_F2018,
+ "Character dummy argument %qs at %L"
+ " with nonconstant length as "
+ "procedure %qs is BIND(C)",
+ sym->name, &sym->declared_at,
+ sym->ns->proc_name->name))
+ retval = false;
+ }

Elsewhere the convention seems to be to format strings split across
mu

*Ping**2 [Patch] Fortran: Fix bind(C) character length checks

2021-07-14 Thread Burnus, Tobias
Ping**2

On Juli 8, 2021 I wrote:

*Ping*

I intent to incorporate Sandra's suggestions, except for the beginning of line 
spacing - that's needed to avoid exceeding the 80 character line limit. I did 
not include an updated patch as just pinging is easier on a mobile during 
vacation :-)

Thanks,

Tobias

Loosemore, Sandra wrote:

On 7/1/21 11:08 AM, Tobias Burnus wrote:
> Hi all,
>
> this patch came up when discussing Sandra's TS29113 patch internally.
> There is presumably also some overlap with José's patches.
>
> This patch tries to rectify the BIND(C) CHARACTER handling on the
> diagnostic side, only. That is: what to accept and what
> to reject for which Fortran standard.
>
>
> The rules are:
>
> * [F2003-F2018] Interoperable is character(len=1)
>→ F2018, 18.3.1  Interoperability of intrinsic types
>(General, unchanged)
>
> * Fortran 2008: In some cases, const-length chars are
>permitted as well:
>→ F2018, 18.3.4  Interoperability of scalar variables
>→ F2018, 18.3.5  Interoperability of array variables
>→ F2018, 18.3.6  Interoperability of procedures and procedure interfaces
>   [= F2008, 15.3.{4,5,6}
> For global vars with bind(C), 18.3.4 + 18.3.5 applies directly (TODO:
> Add support, not in this patch)
> For passed-by ref dummy arguments, 18.3.4 + 18.3.5 are referenced in
> - F2008: R1229  proc-language-binding-spec is language-binding-spec
>   C1255 (R1229) 
> - F2018, F2018, C1554
>
> While it is not very clearly spelt out, I regard 'char parm[4]'
> interoperable with 'character(len=4) :: a', 'character(len=2) :: b(2)'
> and 'character(len=1) :: c(4)' for both global variables and for
> dummy arguments.
>
> * Fortran 2018/TS29113:  Uses additionally CFI array descriptor
>- allocatable, pointer:  must be len=:
>- nonallocatable/nonpointer: len=* → implies array descriptor also
>  for assumed-size/explicit-size/scalar arguments.
>- All which all passed by an array descriptor already without further
>  restrictions: assumed-shape, assumed-rank, i.e. len= seems
>  to be also fine
> → 18.3.6 under item (5) bullet point 2 and 3 plus (6).
>
>
> I hope I got the conditions right. I also fixed an issue with
> character(len=5) :: str – the code in trans-expr.c did crash for
> scalars  (decl.c did not check any constraints for arrays).
> I believe the condition is wrong and for len= no descriptor
> is used.
>
> Any comments, remarks?

I gave this patch a try on my TS 29113 last night.  Changing the error
messages kind of screwed up my list of FAILs, but I did see that it also
caught some invalid character arguments in
interoperability/typecodes-scalar.f90 and
interoperability/typecodes-scalar-ext.f90 (which are already broken by 2
other major gfortran bugs I still need to file PRs for).  :-S

I haven't tried to review the patch WRT correctness with the
requirements of the standard yet, but I have a few nits about error
messages

> +   /* F2018, 18.3.6 (6).  */
> +   if (!sym->ts.deferred)
> + {
> +   gfc_error ("Allocatable and pointer character dummy "
> +  "argument %qs at %L must have deferred length "
> +  "as procedure %qs is BIND(C)", sym->name,
> +  &sym->declared_at, sym->ns->proc_name->name);
> +   retval = false;
> + }

This is the error the two aforementioned test cases started giving, but
message is confusing and doesn't read well (it was a pointer dummy, not
"allocatable and pointer").  Maybe just s/and/or/, or customize the
message depending on which one it is?

> +   gfc_error ("Character dummy argument %qs at %L must be "
> +  "of constant length or assumed length, "
> +  "unless it has assumed-shape or assumed-rank, "
> +  "as procedure %qs has the BIND(C) attribute",
> +  sym->name, &sym->declared_at,
> +  sym->ns->proc_name->name);

I don't think either "assumed-shape" or "assumed-rank" should be
hyphenated in this context unless that exact hyphenation is a term of
art in the Fortran standard or other technical documentation.  In normal
English, adjective phrases are usually only hyphenated when they appear
immediately before the noun they modify; "assumed-shape array", but "an
array with assumed shape".

> +   else if (!gfc_notify_std (GFC_STD_F2018,
> + "Character dummy argument %qs at %L"
> + " with nonconstant length as "
> + "procedure %qs is BIND(C)",
> + sym->name, &sym->declared_at,
> + sym->ns->proc_name->name))
> + retval = false;
> + }

Elsewhere the conventi

*Ping* [Patch] Fortran: Fix bind(C) character length checks

2021-07-07 Thread Burnus, Tobias
*Ping*

I intent to incorporate Sandra's suggestions, except for the beginning of line 
spacing - that's needed to avoid exceeding the 80 character line limit. I did 
not include an updated patch as just pinging is easier on a mobile during 
vacation :-)

Thanks,

Tobias

Loosemore, Sandra wrote:

On 7/1/21 11:08 AM, Tobias Burnus wrote:
> Hi all,
>
> this patch came up when discussing Sandra's TS29113 patch internally.
> There is presumably also some overlap with José's patches.
>
> This patch tries to rectify the BIND(C) CHARACTER handling on the
> diagnostic side, only. That is: what to accept and what
> to reject for which Fortran standard.
>
>
> The rules are:
>
> * [F2003-F2018] Interoperable is character(len=1)
>→ F2018, 18.3.1  Interoperability of intrinsic types
>(General, unchanged)
>
> * Fortran 2008: In some cases, const-length chars are
>permitted as well:
>→ F2018, 18.3.4  Interoperability of scalar variables
>→ F2018, 18.3.5  Interoperability of array variables
>→ F2018, 18.3.6  Interoperability of procedures and procedure interfaces
>   [= F2008, 15.3.{4,5,6}
> For global vars with bind(C), 18.3.4 + 18.3.5 applies directly (TODO:
> Add support, not in this patch)
> For passed-by ref dummy arguments, 18.3.4 + 18.3.5 are referenced in
> - F2008: R1229  proc-language-binding-spec is language-binding-spec
>   C1255 (R1229) 
> - F2018, F2018, C1554
>
> While it is not very clearly spelt out, I regard 'char parm[4]'
> interoperable with 'character(len=4) :: a', 'character(len=2) :: b(2)'
> and 'character(len=1) :: c(4)' for both global variables and for
> dummy arguments.
>
> * Fortran 2018/TS29113:  Uses additionally CFI array descriptor
>- allocatable, pointer:  must be len=:
>- nonallocatable/nonpointer: len=* → implies array descriptor also
>  for assumed-size/explicit-size/scalar arguments.
>- All which all passed by an array descriptor already without further
>  restrictions: assumed-shape, assumed-rank, i.e. len= seems
>  to be also fine
> → 18.3.6 under item (5) bullet point 2 and 3 plus (6).
>
>
> I hope I got the conditions right. I also fixed an issue with
> character(len=5) :: str – the code in trans-expr.c did crash for
> scalars  (decl.c did not check any constraints for arrays).
> I believe the condition is wrong and for len= no descriptor
> is used.
>
> Any comments, remarks?

I gave this patch a try on my TS 29113 last night.  Changing the error
messages kind of screwed up my list of FAILs, but I did see that it also
caught some invalid character arguments in
interoperability/typecodes-scalar.f90 and
interoperability/typecodes-scalar-ext.f90 (which are already broken by 2
other major gfortran bugs I still need to file PRs for).  :-S

I haven't tried to review the patch WRT correctness with the
requirements of the standard yet, but I have a few nits about error
messages

> +   /* F2018, 18.3.6 (6).  */
> +   if (!sym->ts.deferred)
> + {
> +   gfc_error ("Allocatable and pointer character dummy "
> +  "argument %qs at %L must have deferred length "
> +  "as procedure %qs is BIND(C)", sym->name,
> +  &sym->declared_at, sym->ns->proc_name->name);
> +   retval = false;
> + }

This is the error the two aforementioned test cases started giving, but
message is confusing and doesn't read well (it was a pointer dummy, not
"allocatable and pointer").  Maybe just s/and/or/, or customize the
message depending on which one it is?

> +   gfc_error ("Character dummy argument %qs at %L must be "
> +  "of constant length or assumed length, "
> +  "unless it has assumed-shape or assumed-rank, "
> +  "as procedure %qs has the BIND(C) attribute",
> +  sym->name, &sym->declared_at,
> +  sym->ns->proc_name->name);

I don't think either "assumed-shape" or "assumed-rank" should be
hyphenated in this context unless that exact hyphenation is a term of
art in the Fortran standard or other technical documentation.  In normal
English, adjective phrases are usually only hyphenated when they appear
immediately before the noun they modify; "assumed-shape array", but "an
array with assumed shape".

> +   else if (!gfc_notify_std (GFC_STD_F2018,
> + "Character dummy argument %qs at %L"
> + " with nonconstant length as "
> + "procedure %qs is BIND(C)",
> + sym->name, &sym->declared_at,
> + sym->ns->proc_name->name))
> + retval = false;
> + }

Elsewhere the convention seems to be to format strings sp

Re: [Patch] Fortran: Fix bind(C) character length checks

2021-07-02 Thread Sandra Loosemore

On 7/1/21 11:08 AM, Tobias Burnus wrote:

Hi all,

this patch came up when discussing Sandra's TS29113 patch internally.
There is presumably also some overlap with José's patches.

This patch tries to rectify the BIND(C) CHARACTER handling on the
diagnostic side, only. That is: what to accept and what
to reject for which Fortran standard.


The rules are:

* [F2003-F2018] Interoperable is character(len=1)
   → F2018, 18.3.1  Interoperability of intrinsic types
   (General, unchanged)

* Fortran 2008: In some cases, const-length chars are
   permitted as well:
   → F2018, 18.3.4  Interoperability of scalar variables
   → F2018, 18.3.5  Interoperability of array variables
   → F2018, 18.3.6  Interoperability of procedures and procedure interfaces
  [= F2008, 15.3.{4,5,6}
For global vars with bind(C), 18.3.4 + 18.3.5 applies directly (TODO: 
Add support, not in this patch)

For passed-by ref dummy arguments, 18.3.4 + 18.3.5 are referenced in
- F2008: R1229  proc-language-binding-spec is language-binding-spec
  C1255 (R1229) 
- F2018, F2018, C1554

While it is not very clearly spelt out, I regard 'char parm[4]'
interoperable with 'character(len=4) :: a', 'character(len=2) :: b(2)'
and 'character(len=1) :: c(4)' for both global variables and for
dummy arguments.

* Fortran 2018/TS29113:  Uses additionally CFI array descriptor
   - allocatable, pointer:  must be len=:
   - nonallocatable/nonpointer: len=* → implies array descriptor also
     for assumed-size/explicit-size/scalar arguments.
   - All which all passed by an array descriptor already without further
     restrictions: assumed-shape, assumed-rank, i.e. len= seems
     to be also fine
→ 18.3.6 under item (5) bullet point 2 and 3 plus (6).


I hope I got the conditions right. I also fixed an issue with
character(len=5) :: str – the code in trans-expr.c did crash for
scalars  (decl.c did not check any constraints for arrays).
I believe the condition is wrong and for len= no descriptor
is used.

Any comments, remarks?


I gave this patch a try on my TS 29113 last night.  Changing the error 
messages kind of screwed up my list of FAILs, but I did see that it also 
caught some invalid character arguments in 
interoperability/typecodes-scalar.f90 and 
interoperability/typecodes-scalar-ext.f90 (which are already broken by 2 
other major gfortran bugs I still need to file PRs for).  :-S


I haven't tried to review the patch WRT correctness with the 
requirements of the standard yet, but I have a few nits about error 
messages



+ /* F2018, 18.3.6 (6).  */
+ if (!sym->ts.deferred)
+   {
+ gfc_error ("Allocatable and pointer character dummy "
+"argument %qs at %L must have deferred length "
+"as procedure %qs is BIND(C)", sym->name,
+&sym->declared_at, sym->ns->proc_name->name);
+ retval = false;
+   }


This is the error the two aforementioned test cases started giving, but 
message is confusing and doesn't read well (it was a pointer dummy, not 
"allocatable and pointer").  Maybe just s/and/or/, or customize the 
message depending on which one it is?



+ gfc_error ("Character dummy argument %qs at %L must be "
+"of constant length or assumed length, "
+"unless it has assumed-shape or assumed-rank, "
+"as procedure %qs has the BIND(C) attribute",
+sym->name, &sym->declared_at,
+sym->ns->proc_name->name);


I don't think either "assumed-shape" or "assumed-rank" should be 
hyphenated in this context unless that exact hyphenation is a term of 
art in the Fortran standard or other technical documentation.  In normal 
English, adjective phrases are usually only hyphenated when they appear 
immediately before the noun they modify; "assumed-shape array", but "an 
array with assumed shape".



+ else if (!gfc_notify_std (GFC_STD_F2018,
+   "Character dummy argument %qs at %L"
+   " with nonconstant length as "
+   "procedure %qs is BIND(C)",
+   sym->name, &sym->declared_at,
+   sym->ns->proc_name->name))
+   retval = false;
+   }


Elsewhere the convention seems to be to format strings split across 
multiple lines with a space at the end of each chunk rather than at the 
beginning.


-Sandra


Re: [Patch] Fortran: Fix bind(C) character length checks

2021-07-01 Thread Sandra Loosemore

On 7/1/21 11:08 AM, Tobias Burnus wrote:

Hi all,

this patch came up when discussing Sandra's TS29113 patch internally.
There is presumably also some overlap with José's patches.

This patch tries to rectify the BIND(C) CHARACTER handling on the
diagnostic side, only. That is: what to accept and what
to reject for which Fortran standard.


FAOD, my TS29113 testsuite just posted includes only tests for bind(c) 
character features that were added by TS29113, which are all failing 
(without this new patch from Tobias) due to the incorrect compile-time 
error.  Those places in the tests are all currently marked with dg-bogus 
referencing PR 92482.


I've been thinking we need to add a further large batch of tests to 
systematically exercise all the other character-related bind(c) 
functionality; all the combinations of character type, character length, 
dummy argument flavor, call direction, and in/out add up to perhaps 600 
more things that need to be tested.  :-(  Of course a single testcase 
can test multiple things so it wouldn't require 600 actual new 
testcases.  Anyway, I thought there was little point in starting work on 
that until the compiler was actually accepting the more complicated 
dummy argument forms.


I'm a bit backlogged on other things right now but I'll give this patch 
a spin when I have time and if it's approved I'll adjust the TS29113 
testsuite dg-bogus patterns or whatever accordingly, before reposting a 
cleaned-up version.


-Sandra


[Patch] Fortran: Fix bind(C) character length checks

2021-07-01 Thread Tobias Burnus

Hi all,

this patch came up when discussing Sandra's TS29113 patch internally.
There is presumably also some overlap with José's patches.

This patch tries to rectify the BIND(C) CHARACTER handling on the
diagnostic side, only. That is: what to accept and what
to reject for which Fortran standard.


The rules are:

* [F2003-F2018] Interoperable is character(len=1)
  → F2018, 18.3.1  Interoperability of intrinsic types
  (General, unchanged)

* Fortran 2008: In some cases, const-length chars are
  permitted as well:
  → F2018, 18.3.4  Interoperability of scalar variables
  → F2018, 18.3.5  Interoperability of array variables
  → F2018, 18.3.6  Interoperability of procedures and procedure interfaces
 [= F2008, 15.3.{4,5,6}
For global vars with bind(C), 18.3.4 + 18.3.5 applies directly (TODO: Add 
support, not in this patch)
For passed-by ref dummy arguments, 18.3.4 + 18.3.5 are referenced in
- F2008: R1229  proc-language-binding-spec is language-binding-spec
 C1255 (R1229) 
- F2018, F2018, C1554

While it is not very clearly spelt out, I regard 'char parm[4]'
interoperable with 'character(len=4) :: a', 'character(len=2) :: b(2)'
and 'character(len=1) :: c(4)' for both global variables and for
dummy arguments.

* Fortran 2018/TS29113:  Uses additionally CFI array descriptor
  - allocatable, pointer:  must be len=:
  - nonallocatable/nonpointer: len=* → implies array descriptor also
for assumed-size/explicit-size/scalar arguments.
  - All which all passed by an array descriptor already without further
restrictions: assumed-shape, assumed-rank, i.e. len= seems
to be also fine
→ 18.3.6 under item (5) bullet point 2 and 3 plus (6).


I hope I got the conditions right. I also fixed an issue with
character(len=5) :: str – the code in trans-expr.c did crash for
scalars  (decl.c did not check any constraints for arrays).
I believe the condition is wrong and for len= no descriptor
is used.

Any comments, remarks?
OK for mainline?

Tobias

PS: To do are global variables, the implementation of the sorries;
PPS: At other places like with VALUE or for function return values,
Fortran still requires len=1 with Bind(C).

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Fortran: Fix bind(C) character length checks

gcc/fortran/ChangeLog:

	* decl.c (gfc_verify_c_interop_param): Update for F2008 + F2018
	changes; reject unsupported bits with 'Error: Sorry,'.
	* trans-expr.c (gfc_conv_procedure_call): Fix condition to
	For using CFI descriptor with characters.

gcc/testsuite/ChangeLog:

	* gfortran.dg/iso_c_binding_char_1.f90: Update dg-error.
	* gfortran.dg/pr32599.f03: Use -std=-f2003 + update comment.
	* gfortran.dg/bind_c_char_10.f90: New test.
	* gfortran.dg/bind_c_char_6.f90: New test.
	* gfortran.dg/bind_c_char_7.f90: New test.
	* gfortran.dg/bind_c_char_8.f90: New test.
	* gfortran.dg/bind_c_char_9.f90: New test.

 gcc/fortran/decl.c | 107 -
 gcc/fortran/trans-expr.c   |  18 +-
 gcc/testsuite/gfortran.dg/bind_c_char_10.f90   | 480 +
 gcc/testsuite/gfortran.dg/bind_c_char_6.f90| 262 +++
 gcc/testsuite/gfortran.dg/bind_c_char_7.f90| 261 +++
 gcc/testsuite/gfortran.dg/bind_c_char_8.f90| 249 +++
 gcc/testsuite/gfortran.dg/bind_c_char_9.f90| 188 
 gcc/testsuite/gfortran.dg/iso_c_binding_char_1.f90 |   2 +-
 gcc/testsuite/gfortran.dg/pr32599.f03  |   8 +-
 9 files changed, 1551 insertions(+), 24 deletions(-)

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 413c7a75e0c..4a9f74306ff 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -1552,20 +1552,109 @@ gfc_verify_c_interop_param (gfc_symbol *sym)
 	}
 
   /* Character strings are only C interoperable if they have a
- length of 1.  */
-  if (sym->ts.type == BT_CHARACTER && !sym->attr.dimension)
+	 length of 1.  However, as argument they are either iteroperable
+	 when passed as descriptor (which requires len=: or len=*) or
+	 when having a constant length or are always passed by
+	 descriptor.  */
+	  if (sym->ts.type == BT_CHARACTER)
 	{
 	  gfc_charlen *cl = sym->ts.u.cl;
-	  if (!cl || !cl->length || cl->length->expr_type != EXPR_CONSTANT
-  || mpz_cmp_si (cl->length->value.integer, 1) != 0)
+
+	  if (sym->attr.allocatable || sym->attr.pointer)
 		{
-		  gfc_error ("Character argument %qs at %L "
-			 "must be length 1 because "
-			 "procedure %qs is BIND(C)",
-			 sym->name, &sym->declared_at,
-			 sym->ns->proc_name->name);
+		  /* F2018, 18.3.6 (6).  */
+		  if (!sym->ts.deferred)
+		{
+		  gfc_error ("Allocatable and pointer character dummy "
+ "argument %qs at %L must have deferred length "
+ "as procedure %qs is BIND(C)", sym->name,
+