Re: [PATCH, Fortran] Bind(c): CFI_signed_char is not a Fortran character type

2021-07-16 Thread Thomas Koenig via Fortran



Hi Sandra,

The part of the patch to add tests for this goes on top of my base 
TS29113 testsuite patch, which hasn't been reviewed or committed yet.


It is my understanding that it is not gcc policy to add xfailed test
cases for things that do not yet work. Rather, xfail is for tests that
later turn out not to work, especially on certain architectures.

I have added Toon in CC, maybe he can explain a bit more on that.

Regards

Thomas


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

2021-07-16 Thread Jerry D via Fortran

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

Pushing XFAILed test cases (was: [PATCH, Fortran] Bind(c): CFI_signed_char is not a Fortran character type)

2021-07-16 Thread Thomas Schwinge
[Also including  for guidance.]


Hi!

(I'm not involved in or familiar with Sandra's Fortran TS29113 work, just
commenting generally here.)


On 2021-07-16T09:52:28+0200, Thomas Koenig via Gcc-patches 
 wrote:
> It is my understanding that it is not gcc policy to add xfailed test
> cases for things that do not yet work. Rather, xfail is for tests that
> later turn out not to work, especially on certain architectures.

That's not current practice, as far as I can tell.  I'm certainly
"guilty" of pushing lots of XFAILed test cases (or, most often,
individual XFAILed DejaGnu directives), and I see a good number of others
GCC folks do that, too.  Ideally with but casually also without
corresponding GCC PRs filed.  If without, then of course should have
suitable commentary inside the test case file.  Time span of addressing
the XFAILs ranging between days and years.

In my opinion, if a test case has been written and analyzed, why
shouldn't you push it, even if (parts of) it don't quite work yet?  (If
someone -- at another time, possibly -- then implements the missing
functionality/fixes the bugs, the XFAILs turn into XPASSes, thus serving
to demonstrate the effect of code changes.

Otherwise -- and I've run into that just yesterday... -- effort spent on
such test cases simply gets lost "in the noise of the mailing list
archives", until re-discovered, or -- in my case -- re-implemented and
then re-discovered by chance.

We nowadays even have a way to mark up ICEing test cases ('dg-ice'),
which has been used to push test cases that ICE for '{ target *-*-* }'.


Of course, we shall assume a certain level of quality in the XFAILed test
cases: I'm certainly not suggesting we put any random junk into the
testsuite, coarsely XFAILed.  (I have not reviewed Sandra's test cases to
that effect, but knowing here, I'd be surprised if that were the problem
here.)


Not trying to overrule you, just sharing my opinion -- now happy to hear
others.  :-)


Grüße
 Thomas
-
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


Re: Pushing XFAILed test cases

2021-07-16 Thread Martin Sebor via Fortran

On 7/16/21 9:32 AM, Thomas Schwinge wrote:

[Also including  for guidance.]


Hi!

(I'm not involved in or familiar with Sandra's Fortran TS29113 work, just
commenting generally here.)


On 2021-07-16T09:52:28+0200, Thomas Koenig via Gcc-patches 
 wrote:

It is my understanding that it is not gcc policy to add xfailed test
cases for things that do not yet work. Rather, xfail is for tests that
later turn out not to work, especially on certain architectures.


That's not current practice, as far as I can tell.  I'm certainly
"guilty" of pushing lots of XFAILed test cases (or, most often,
individual XFAILed DejaGnu directives), and I see a good number of others
GCC folks do that, too.  Ideally with but casually also without
corresponding GCC PRs filed.  If without, then of course should have
suitable commentary inside the test case file.  Time span of addressing
the XFAILs ranging between days and years.

In my opinion, if a test case has been written and analyzed, why
shouldn't you push it, even if (parts of) it don't quite work yet?  (If
someone -- at another time, possibly -- then implements the missing
functionality/fixes the bugs, the XFAILs turn into XPASSes, thus serving
to demonstrate the effect of code changes.

Otherwise -- and I've run into that just yesterday... -- effort spent on
such test cases simply gets lost "in the noise of the mailing list
archives", until re-discovered, or -- in my case -- re-implemented and
then re-discovered by chance.

We nowadays even have a way to mark up ICEing test cases ('dg-ice'),
which has been used to push test cases that ICE for '{ target *-*-* }'.


Of course, we shall assume a certain level of quality in the XFAILed test
cases: I'm certainly not suggesting we put any random junk into the
testsuite, coarsely XFAILed.  (I have not reviewed Sandra's test cases to
that effect, but knowing here, I'd be surprised if that were the problem
here.)


Not trying to overrule you, just sharing my opinion -- now happy to hear
others.  :-)


I've also been xfailing individual directives in new tests, with
or without PRs tracking the corresponding limitations (not so much
outright bugs as future enhancements).  The practice has been
discussed in the past and (IIRC) there was general agreement with
it.  Marek even formalized some of it for the C++ front end by
adding support for one or more dg- directives (I think dg-ice was
one of them). The discussion I recall is here:

https://gcc.gnu.org/pipermail/gcc-patches/2020-July/550913.html

Martin


Re: Pushing XFAILed test cases

2021-07-16 Thread Sandra Loosemore

On 7/16/21 9:32 AM, Thomas Schwinge wrote:


[much snipped]

Of course, we shall assume a certain level of quality in the XFAILed test
cases: I'm certainly not suggesting we put any random junk into the
testsuite, coarsely XFAILed.  (I have not reviewed Sandra's test cases to
that effect, but knowing here, I'd be surprised if that were the problem
here.)


FWIW, Tobias already did an extensive review of an early version of the 
testsuite patches in question and pointed out several cases where 
failures were due to my misunderstanding of the language standard or 
general confusion about what the expected behavior was supposed to be 
when gfortran wasn't implementing it or was tripping over other bugs. 
:-S  I hope I incorporated all his suggestions and rewrote the 
previously-bogus tests to be more useful for the version I posted for 
review on the Fortran list, but shouldn't the normal patch review 
process be adequate to take care of any additional concerns about quality?


My previous understanding of the development process and testsuite 
conventions is that adding tests that FAIL is bad, but XFAILing them 
with reference to a PR is OK, and certainly much better than simply not 
having test coverage of those things at all.  Especially in the case of 
something like the TS29113 testsuite where the explicit goal is to track 
standards compliance and/or the completeness of the existing 
implementation.  :-S  So it seems to me rather surprising to take the 
position that we should not be committing any new test cases that need 
to be XFAILed.  :-S


-Sandra


[PATCH, Fortran] [PR libfortran/101317] Bind(c): Improve error checking in CFI_* functions

2021-07-16 Thread Sandra Loosemore
This patch is for PR101317, one of the bugs uncovered by the TS29113 
testsuite.  Here I'd observed that CFI_establish, etc was not diagnosing 
some invalid-argument situations documented in the standard, although it 
was properly catching others.  After fixing those I discovered a couple 
small mistakes in the test cases and fixed those too.


The testsuite fixes can either be committed with this patch or rolled 
into the TS29113 testsuite, depending on the order in which things are 
approved/committed.


OK?

-Sandra
commit 6cecb3e3625072c7846434df9dcd8db5e6f66432
Author: Sandra Loosemore 
Date:   Thu Jul 15 08:48:45 2021 -0700

[PR libfortran/101317] Bind(c): Improve error checking in CFI_* functions

This patch adds additional run-time checking for invalid arguments to
CFI_allocate, CFI_establish, CFI_select_part, and CFI_setpointer.

It also includes some minor fixes for signed/unsigned confusion in the
TS29113 testsuite.

2021-07-16  Sandra Loosemore  

	PR libfortran/101317

libgfortran/
	* runtime/ISO_Fortran_binding.c (CFI_allocate): Check elem_len
	for validity when it's used.
	(CFI_establish): Likewise.  Also check type argument and extents.
	(CFI_select_part): Check elem_len.
	(CFI_setpointer): Check that source is not an unallocated
	allocatable array or an assumed-size array.  Minor formatting
	cleanup.

gcc/testsuite/
	* gfortran.dg/ts29113/library/establish-errors-c.c (ctest):
	Correct unsigned argument to CFI_establish.
	* gfortran.dg/ts29113/library/setpointer-errors-c.c (ctest):
	Bypass CFI_establish to create an assumed-size array.

diff --git a/gcc/testsuite/gfortran.dg/ts29113/library/establish-errors-c.c b/gcc/testsuite/gfortran.dg/ts29113/library/establish-errors-c.c
index b55362a..ae02b46 100644
--- a/gcc/testsuite/gfortran.dg/ts29113/library/establish-errors-c.c
+++ b/gcc/testsuite/gfortran.dg/ts29113/library/establish-errors-c.c
@@ -57,7 +57,7 @@ ctest (void)
  character type, elem_len shall be greater than zero and equal to
  the storage size in bytes of an element of the object.  */
   status = CFI_establish (a, (void *)buf, CFI_attribute_other,
-			  CFI_type_struct, -5, 2, extents);
+			  CFI_type_struct, 0, 2, extents);
   if (status == CFI_SUCCESS)
 {
   fprintf (stderr,
diff --git a/gcc/testsuite/gfortran.dg/ts29113/library/setpointer-errors-c.c b/gcc/testsuite/gfortran.dg/ts29113/library/setpointer-errors-c.c
index eec96e6..670d360 100644
--- a/gcc/testsuite/gfortran.dg/ts29113/library/setpointer-errors-c.c
+++ b/gcc/testsuite/gfortran.dg/ts29113/library/setpointer-errors-c.c
@@ -8,7 +8,6 @@
 
 static int a[10][5][3];
 static CFI_index_t extents[] = {3, 5, 10};
-static CFI_index_t badextents[] = {3, 5, -1};
 
 /* External entry point.  */
 extern void ctest (void);
@@ -69,9 +68,12 @@ ctest (void)
   bad ++;
 }
 
+  /* CFI_establish rejects negative extents, so we can't use it to make
+ an assumed-size array, so hack the descriptor by hand.  Yuck.  */
   check_CFI_status ("CFI_establish",
 		CFI_establish (source, (void *)a, CFI_attribute_other,
-   CFI_type_int, 0, 3, badextents));
+   CFI_type_int, 0, 3, extents));
+  source->dim[2].extent = -1;
   status = CFI_setpointer (result, source, NULL);
   if (status == CFI_SUCCESS)
 {
diff --git a/libgfortran/runtime/ISO_Fortran_binding.c b/libgfortran/runtime/ISO_Fortran_binding.c
index 79bb377..38e1b6e 100644
--- a/libgfortran/runtime/ISO_Fortran_binding.c
+++ b/libgfortran/runtime/ISO_Fortran_binding.c
@@ -232,7 +232,16 @@ CFI_allocate (CFI_cdesc_t *dv, const CFI_index_t lower_bounds[],
   /* If the type is a Fortran character type, the descriptor's element
  length is replaced by the elem_len argument. */
   if (dv->type == CFI_type_char || dv->type == CFI_type_ucs4_char)
-dv->elem_len = elem_len;
+{
+  if (unlikely (compile_options.bounds_check) && elem_len == 0)
+	{
+	  fprintf ("CFI_allocate: The supplied elem_len must be "
+		   "greater than zero (elem_len = %d).\n",
+		   (int) elem_len);
+	  return CFI_INVALID_ELEM_LEN;
+	}
+  dv->elem_len = elem_len;
+}
 
   /* Dimension information and calculating the array length. */
   size_t arr_len = 1;
@@ -342,11 +351,28 @@ int CFI_establish (CFI_cdesc_t *dv, void *base_addr, CFI_attribute_t attribute,
 
   if (type == CFI_type_char || type == CFI_type_ucs4_char
   || type == CFI_type_struct || type == CFI_type_other)
-dv->elem_len = elem_len;
+{
+  /* Note that elem_len has type size_t, which is unsigned.  */
+  if (unlikely (compile_options.bounds_check) && elem_len == 0)
+	{
+	  fprintf ("CFI_establish: The supplied elem_len must be "
+		   "greater than zero (elem_len = %d).\n",
+		   (int) elem_len);
+	  return CFI_INVALID_ELEM_LEN;
+	}
+  dv->elem_len = elem_len;
+}
   else if (type == CFI_type_cptr)
 dv->elem_len = sizeof (void *);
   else if (type == CFI_type_cfunptr)