public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value
@ 2023-04-13 13:24 leandro.lupori at linaro dot org
  2023-04-13 15:05 ` [Bug fortran/109500] " kargl at gcc dot gnu.org
                   ` (23 more replies)
  0 siblings, 24 replies; 25+ messages in thread
From: leandro.lupori at linaro dot org @ 2023-04-13 13:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

            Bug ID: 109500
           Summary: SIGABRT when calling a function that returns an
                    unallocated value
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: leandro.lupori at linaro dot org
  Target Milestone: ---

While doing some tests with functions that return an allocatable result, I
found out that the following program receives a SIGABRT:

program main
  print *, is_allocated(f())

contains
  function f()
    integer, allocatable :: f
  end function

  logical function is_allocated(p)
    integer, allocatable :: p

    is_allocated = allocated(p)
  end function
end program

This is the output (without the backtrace):
free(): invalid pointer

Program received signal SIGABRT: Process abort signal.

I tested it with gfortran 11.3.0 and 12.0.0 20220117 (experimental) [master
r12-6624-gb75aab194e3] (from gcc-snapshot).

The program above is a reduced version. I was actually trying to use a function
that could return either an allocated result or an unallocated one, depending
on the argument, such as:

function f(p)
  integer, allocatable :: f, p

  if (allocated(p)) then
    f = p
  endif
end function

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
@ 2023-04-13 15:05 ` kargl at gcc dot gnu.org
  2023-04-13 17:06 ` leandro.lupori at linaro dot org
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: kargl at gcc dot gnu.org @ 2023-04-13 15:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org

--- Comment #1 from kargl at gcc dot gnu.org ---
Fortunately, this is not a bug in gfortran.
Unfortunately, this is a bug in your program.
A function is required by the Fortran standard
to have its result variable assigned when it 
returns.  If you compile your code with the 
-Wall option, you'll see

gfortran -o z -Wall a.f90
a.f90:5:2:

    5 |   function f()
      |  1
Warning: Return value of function 'f' at (1) not set [-Wreturn-type]

On my system, 'z' either segfaults or prints 'T'.
For 'T' the function f() is pointing to whatever
is left on the stack.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
  2023-04-13 15:05 ` [Bug fortran/109500] " kargl at gcc dot gnu.org
@ 2023-04-13 17:06 ` leandro.lupori at linaro dot org
  2023-04-13 18:12 ` kargl at gcc dot gnu.org
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: leandro.lupori at linaro dot org @ 2023-04-13 17:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #2 from Leandro Lupori <leandro.lupori at linaro dot org> ---
Thanks for the quick response.

What if 'f' is changed to this:

function f()
  integer, allocatable :: f

  allocate(f)
  f = 123
  deallocate(f)
end function

Is the program still invalid? gfortran -Wall doesn't complain in this case, but
I get a SIGSEGV instead of SIGABRT.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
  2023-04-13 15:05 ` [Bug fortran/109500] " kargl at gcc dot gnu.org
  2023-04-13 17:06 ` leandro.lupori at linaro dot org
@ 2023-04-13 18:12 ` kargl at gcc dot gnu.org
  2023-04-13 18:32 ` anlauf at gcc dot gnu.org
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: kargl at gcc dot gnu.org @ 2023-04-13 18:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #3 from kargl at gcc dot gnu.org ---
(In reply to Leandro Lupori from comment #2)
> Thanks for the quick response.
> 
> What if 'f' is changed to this:
> 
> function f()
>   integer, allocatable :: f
> 
>   allocate(f)
>   f = 123
>   deallocate(f)
> end function
> 
> Is the program still invalid? gfortran -Wall doesn't complain in this case,
> but I get a SIGSEGV instead of SIGABRT.

Yes.  It is not valid Fortran.  You've deallocated 'f', which means
the function result is not set.

Your example is also likely why the warning is hidden 
behind -Wall.  I suspect there are too many false
positive and with your code you're getting a false
negative (ie., no warning).

  F2023, p. 331

  15.5.3 Function reference

  A function is invoked during expression evaluation by a
  function-reference or by a defined operation (10.1.6).
  When it is invoked, all actual argument expressions are
  evaluated, then the arguments are associated, and then
  the function is executed. When execution of the function
  is complete, the value of the function result is available
  for use in the expression that caused the function to be
  invoked.

In 'print *, is_allocated(f())', the function-reference is
evaluated.

  F2023, p. 336

  On completion of execution of the function, the value
  returned is that of its function result. ...
  If the function result is not a pointer, its value shall
  be defined by the function.


19.6.6 Events that cause variables to become undefined
...
(10) When an allocatable entity is deallocated, it becomes undefined.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (2 preceding siblings ...)
  2023-04-13 18:12 ` kargl at gcc dot gnu.org
@ 2023-04-13 18:32 ` anlauf at gcc dot gnu.org
  2023-04-13 19:44 ` leandro.lupori at linaro dot org
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-13 18:32 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #4 from anlauf at gcc dot gnu.org ---
I think one cannot achieve what the OP wants by using allocable function
results.  One should use a subroutine instead.

Compiling the code with the NAG compiler gives:

NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
Warning: pr109500.f90, line 7: Allocatable function F has not been allocated or
assigned a value
Error: pr109500.f90, line 2: Expected an ALLOCATABLE variable for argument P
(no. 1) of IS_ALLOCATED
[NAG Fortran Compiler error termination, 1 error, 1 warning]

Not perfect, but what you are seeing is an attempt by the compiler to do
argument association when you invoke function is_allocated.

Now look at the following variants in the main:

1)
  print *, allocated(f())

You'll get:

    2 |   print *, allocated(f())
      |                     1
Error: 'array' argument of 'allocated' intrinsic at (1) must be a variable

This is what the standard says.

2)
  integer, allocatable :: p
  p = f()
  print *, allocated(p)

This compiles, but you get a runtime error (SIGSEGV) with gfortran and ifort.

Why?  The assignment p=f() is invalid for unallocated r.h.s., and you are
hitting this.  The running program will never reach the allocated(p).

I don't see a legal way to use an allocatable function without allocating
the result.  So you should use a subroutine and allocate a result variable.

The only potential issue I see here with gfortran is that there is no working
runtime diagnostics for the non-allocated r.h.s. above.  But there is none
for current ifort/ifx either.

If the reporter agrees, we should close this PR as invalid.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (3 preceding siblings ...)
  2023-04-13 18:32 ` anlauf at gcc dot gnu.org
@ 2023-04-13 19:44 ` leandro.lupori at linaro dot org
  2023-04-13 21:28 ` anlauf at gcc dot gnu.org
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: leandro.lupori at linaro dot org @ 2023-04-13 19:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #5 from Leandro Lupori <leandro.lupori at linaro dot org> ---
Ok, thanks for the detailed explanations. Now I see that the standard doesn't
allow the return of an unallocated value. This can be closed as invalid.

But may I just ask a last related question? As mentioned in the last comment
and according to Note 1 in F2018 8.5.3 ALLOCATABLE attribute, the result of
referencing a function cannot be used as an allocatable argument. This is
however allowed by gfortran (and ifort), with the exception of intrinsic
procedures, and seems to work correctly. Should this be considered an extension
or does it just work by accident and there are no guarantees at all when using
it?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (4 preceding siblings ...)
  2023-04-13 19:44 ` leandro.lupori at linaro dot org
@ 2023-04-13 21:28 ` anlauf at gcc dot gnu.org
  2023-04-13 21:34 ` sgk at troutmask dot apl.washington.edu
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-13 21:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #6 from anlauf at gcc dot gnu.org ---
(In reply to Leandro Lupori from comment #5)
> Ok, thanks for the detailed explanations. Now I see that the standard
> doesn't allow the return of an unallocated value. This can be closed as
> invalid.
> 
> But may I just ask a last related question? As mentioned in the last comment
> and according to Note 1 in F2018 8.5.3 ALLOCATABLE attribute, the result of
> referencing a function cannot be used as an allocatable argument.

The precise text is:

"... The result of referencing a function whose result variable has the
ALLOCATABLE attribute is a value that does not itself have the
ALLOCATABLE attribute."

So you can add e.g.

    allocate (f, source=42)

to the body of f to define the result, and then use it as e.g.

  integer, allocatable :: p
  p = f()
  print *, allocated (p)

I am still trying to find the exact place in the standard that explains
whether - with the corrected f - the following is legal:

  print *, is_allocated(f())

> This is
> however allowed by gfortran (and ifort), with the exception of intrinsic
> procedures, and seems to work correctly. Should this be considered an
> extension or does it just work by accident and there are no guarantees at
> all when using it?

I think we are in dangerous waters here.  If something appears to work
empirically with one compiler, that does not guarantee anything.
So as already discussed, if the allocation status of the result cannot be
guaranteed, better use a subroutine.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (5 preceding siblings ...)
  2023-04-13 21:28 ` anlauf at gcc dot gnu.org
@ 2023-04-13 21:34 ` sgk at troutmask dot apl.washington.edu
  2023-04-14 19:24 ` anlauf at gcc dot gnu.org
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2023-04-13 21:34 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #7 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Thu, Apr 13, 2023 at 07:44:36PM +0000, leandro.lupori at linaro dot org
wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500
> 
> --- Comment #5 from Leandro Lupori <leandro.lupori at linaro dot org> ---
> Ok, thanks for the detailed explanations. Now I see that the standard doesn't
> allow the return of an unallocated value. This can be closed as invalid.
> 
> But may I just ask a last related question? As mentioned in the last comment
> and according to Note 1 in F2018 8.5.3 ALLOCATABLE attribute, the result of
> referencing a function cannot be used as an allocatable argument. This is
> however allowed by gfortran (and ifort), with the exception of intrinsic
> procedures, and seems to work correctly. Should this be considered an extension
> or does it just work by accident and there are no guarantees at all when using
> it?
> 

I suspect it works by accident, but I don't have enough
time at the moment to go read the gfortran source.  What 
is likely happening is gfortran checks that the actual
and dummy argument both have the allocatable attribute.
For the actual argument, the symbol is probably marked
an allocatable attribute and an internal attribute 
that designates this as a function-result, and gfortran
does not check for the latter.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (6 preceding siblings ...)
  2023-04-13 21:34 ` sgk at troutmask dot apl.washington.edu
@ 2023-04-14 19:24 ` anlauf at gcc dot gnu.org
  2023-04-16 19:42 ` anlauf at gcc dot gnu.org
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-14 19:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2023-04-14
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
           Keywords|                            |accepts-invalid, diagnostic
           Priority|P3                          |P5
           Severity|normal                      |enhancement

--- Comment #8 from anlauf at gcc dot gnu.org ---
(In reply to Steve Kargl from comment #7)
> I suspect it works by accident, but I don't have enough
> time at the moment to go read the gfortran source.  What 
> is likely happening is gfortran checks that the actual
> and dummy argument both have the allocatable attribute.
> For the actual argument, the symbol is probably marked
> an allocatable attribute and an internal attribute 
> that designates this as a function-result, and gfortran
> does not check for the latter.

So marking as a missed diagnostic for invalid code.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (7 preceding siblings ...)
  2023-04-14 19:24 ` anlauf at gcc dot gnu.org
@ 2023-04-16 19:42 ` anlauf at gcc dot gnu.org
  2023-04-17 12:14 ` leandro.lupori at linaro dot org
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-16 19:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #9 from anlauf at gcc dot gnu.org ---
The following patch rejects the code in comment#0 and regtests ok:

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index e9843e9549c..64a54c06800 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2195,6 +2214,8 @@ compare_allocatable (gfc_symbol *formal, gfc_expr
*actual)
        return true;
       else if (!attr.allocatable)
        return false;
+      else if (actual->expr_type != EXPR_VARIABLE)
+       return false;
     }

   return true;

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (8 preceding siblings ...)
  2023-04-16 19:42 ` anlauf at gcc dot gnu.org
@ 2023-04-17 12:14 ` leandro.lupori at linaro dot org
  2023-04-17 20:20 ` anlauf at gcc dot gnu.org
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: leandro.lupori at linaro dot org @ 2023-04-17 12:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #10 from Leandro Lupori <leandro.lupori at linaro dot org> ---
Wouldn't it be better to turn this into a warning?

Although using the result of a function as an allocatable argument doesn't
conform with Fortran standards, it has been supported by gfortran for quite
some time. This change may break existing code.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (9 preceding siblings ...)
  2023-04-17 12:14 ` leandro.lupori at linaro dot org
@ 2023-04-17 20:20 ` anlauf at gcc dot gnu.org
  2023-04-19 17:25 ` leandro.lupori at linaro dot org
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-17 20:20 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #11 from anlauf at gcc dot gnu.org ---
(In reply to Leandro Lupori from comment #10)
> Wouldn't it be better to turn this into a warning?
> 
> Although using the result of a function as an allocatable argument doesn't
> conform with Fortran standards, it has been supported by gfortran for quite
> some time. This change may break existing code.

Well, then the existing code seems to violate the Fortran standard,
and it seems it was a bug that gfortran accepted it silently.

The code in comment#0 seems to be silently accepted by the Intel classic
Fortran compiler (ifort), but crashes the new one (ifx).  I've asked
Intel on their opinion.

I've also learned that the same happens for the case of passing f() to
a subroutine, as in:

  call s(f())
[...]
contains
  subroutine s(p)
    integer, allocatable :: p
  end subroutine s
[...]

This is rejected by NAG and also Nvidia and AMD flang, and crashes ifx.

Do you have anybody else supporting the view that the code in question
should work as an extension?

As I said before, there are legal ways to return from a procedure with
the result variable either allocated or not, but this cannot be a function.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (10 preceding siblings ...)
  2023-04-17 20:20 ` anlauf at gcc dot gnu.org
@ 2023-04-19 17:25 ` leandro.lupori at linaro dot org
  2023-04-19 19:02 ` sgk at troutmask dot apl.washington.edu
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: leandro.lupori at linaro dot org @ 2023-04-19 17:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #12 from Leandro Lupori <leandro.lupori at linaro dot org> ---
(In reply to anlauf from comment #11)
> Do you have anybody else supporting the view that the code in question
> should work as an extension?
> 

I know there is some usage of this extension, in code similar to this (using a
function result as an allocatable argument), as it works with gfortran and
ifort (https://github.com/llvm/llvm-project/issues/60226).

Its inclusion in flang (with a portability warning) is being analyzed:
https://reviews.llvm.org/D147614

However, the main motivation was to improve compatibility with other compilers,
such as gfortran and ifort.

I'm trying to check with the issue reporter how extensive is his usage of this
extension and how much effort it would require for him to avoid using it.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (11 preceding siblings ...)
  2023-04-19 17:25 ` leandro.lupori at linaro dot org
@ 2023-04-19 19:02 ` sgk at troutmask dot apl.washington.edu
  2023-04-19 19:06 ` anlauf at gcc dot gnu.org
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2023-04-19 19:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #13 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Wed, Apr 19, 2023 at 05:25:20PM +0000, leandro.lupori at linaro dot org
wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500
> 
> I'm trying to check with the issue reporter how extensive is his usage of this
> extension and how much effort it would require for him to avoid using it.
> 

It's not an extension.  It is a bug in the original
Fortran code.  The Fortran standard requires a function
result to be available at the completion of execution
of a function reference.  The code in the original
bug report clearly violates this.

Note 1 in Fortran 2023, Sec. 8.5.3, p. 100, is non-normative
text.  I suppose one can claim that gfortran should throw an
error when a function result is marked with the allocatable
attribute.  Unfortunately, it is likely a catch-22 situation
in that gfortran needs to know the function result is allocatable
so it can do the allocaton within the function, but it is not
an allocatable outside of the function.  Not sure gfortran
can mark an internal symbol to do both.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (12 preceding siblings ...)
  2023-04-19 19:02 ` sgk at troutmask dot apl.washington.edu
@ 2023-04-19 19:06 ` anlauf at gcc dot gnu.org
  2023-04-19 19:15 ` anlauf at gcc dot gnu.org
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-19 19:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |anlauf at gcc dot gnu.org

--- Comment #14 from anlauf at gcc dot gnu.org ---
(In reply to Leandro Lupori from comment #12)
> Its inclusion in flang (with a portability warning) is being analyzed:
> https://reviews.llvm.org/D147614

Thanks for this link, which has pointers to the J3 list including:

https://mailman.j3-fortran.org/pipermail/j3/2012-April/005029.html

and the thread starting at

https://mailman.j3-fortran.org/pipermail/j3/2017-March/010158.html

with a clarification by Malcolm Cohen:

https://mailman.j3-fortran.org/pipermail/j3/2017-March/010181.html

> However, the main motivation was to improve compatibility with other
> compilers, such as gfortran and ifort.

Compatibility should be best for standard-conforming code... ;-)
I'm still waiting for a response from Intel.

> I'm trying to check with the issue reporter how extensive is his usage of
> this extension and how much effort it would require for him to avoid using
> it.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (13 preceding siblings ...)
  2023-04-19 19:06 ` anlauf at gcc dot gnu.org
@ 2023-04-19 19:15 ` anlauf at gcc dot gnu.org
  2023-04-19 19:42 ` sgk at troutmask dot apl.washington.edu
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-19 19:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #15 from anlauf at gcc dot gnu.org ---
(In reply to Steve Kargl from comment #13)
> Note 1 in Fortran 2023, Sec. 8.5.3, p. 100, is non-normative
> text.  I suppose one can claim that gfortran should throw an
> error when a function result is marked with the allocatable
> attribute.

You mean when the function result is not allocated in that case?

> Unfortunately, it is likely a catch-22 situation
> in that gfortran needs to know the function result is allocatable
> so it can do the allocaton within the function, but it is not
> an allocatable outside of the function.  Not sure gfortran
> can mark an internal symbol to do both.

I checked how to implement a run-time check for a non-allocated
function result, but did this in the wrong place - in the caller.
This did work when I did allocate and the deallocate before return,
otherwise the result variable is simply undefined, and the check does
not work.

So a run-time check needs to be put where the function return is generated.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (14 preceding siblings ...)
  2023-04-19 19:15 ` anlauf at gcc dot gnu.org
@ 2023-04-19 19:42 ` sgk at troutmask dot apl.washington.edu
  2023-04-19 21:03 ` anlauf at gcc dot gnu.org
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2023-04-19 19:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #16 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Wed, Apr 19, 2023 at 07:15:50PM +0000, anlauf at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500
> 
> --- Comment #15 from anlauf at gcc dot gnu.org ---
> (In reply to Steve Kargl from comment #13)
> > Note 1 in Fortran 2023, Sec. 8.5.3, p. 100, is non-normative
> > text.  I suppose one can claim that gfortran should throw an
> > error when a function result is marked with the allocatable
> > attribute.
> 
> You mean when the function result is not allocated in that case?


First, note, 'allocated(f())' throws an error.

Error: 'array' argument of 'allocated' intrinsic at (1) must be a variable

You get this error regardless of the allocation status of the 
function result.

Now, with the original code,

      is_allocated(f())

The function reference is evaluated, and then the function result
(aka it's value) is argument associated with an allocatable dummy
argument.  This is technically wrong as the actual argument (aka
value returned by the function reference) should not have the
allocatable attribute.

   Fortran 2018

   15.5.2.6 Allocatable dummy variables

   The requirements in this subclause apply to actual arguments
   that correspond to allocatable dummy data objects.

   The actual argument shall be allocatable.  It is permissible
   for the actual argument to have an allocation status of
   unallocated.

I'll repeat.  The actual argument is the value resulting from
the function reference.  The "shall" in "shall be allocatable"
applies to something the programmer must ensure.


> > Unfortunately, it is likely a catch-22 situation
> > in that gfortran needs to know the function result is allocatable
> > so it can do the allocaton within the function, but it is not
> > an allocatable outside of the function.  Not sure gfortran
> > can mark an internal symbol to do both.
> 
> I checked how to implement a run-time check for a non-allocated
> function result, but did this in the wrong place - in the caller.
> This did work when I did allocate and the deallocate before return,
> otherwise the result variable is simply undefined, and the check does
> not work.
> 
> So a run-time check needs to be put where the function return is generated.
> 

If we go back to the original code and modify to allocate
f by say doing 'f = 42' in f(), gfortran produces 

% gfcx -o z -Wall a.f90 && ./z
 T

This is the problem.  Yes, f is allocated and assigned 
42.  The printed 'T' is bogus because 42 is value of
the function.  42 is no allocatable.

One place to possibly check for an error is when 
gfortran resolves argument association.  If a dummy
argument is allocatable, the actual argument needs 
to be allocatable and cannot not also be a function
result variable.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (15 preceding siblings ...)
  2023-04-19 19:42 ` sgk at troutmask dot apl.washington.edu
@ 2023-04-19 21:03 ` anlauf at gcc dot gnu.org
  2023-04-20  5:22 ` kargl at gcc dot gnu.org
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-19 21:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #17 from anlauf at gcc dot gnu.org ---
(In reply to Steve Kargl from comment #16)
> First, note, 'allocated(f())' throws an error.

Agree.

> Now, with the original code,
> 
>       is_allocated(f())
> 
> The function reference is evaluated, and then the function result
> (aka it's value) is argument associated with an allocatable dummy
> argument.  This is technically wrong as the actual argument (aka
> value returned by the function reference) should not have the
> allocatable attribute.

Agree.  See also the discussion on the J3 mailing list.

> I'll repeat.  The actual argument is the value resulting from
> the function reference.  The "shall" in "shall be allocatable"
> applies to something the programmer must ensure.

Agree.

> If we go back to the original code and modify to allocate
> f by say doing 'f = 42' in f(), gfortran produces 
> 
> % gfcx -o z -Wall a.f90 && ./z
>  T
> 
> This is the problem.  Yes, f is allocated and assigned 
> 42.  The printed 'T' is bogus because 42 is value of
> the function.  42 is no allocatable.

Agree again.

The point is that there is a bug in gfortran which currently effectively
generates code which resembles

  integer, allocatable :: p
  p = f()
  print *, is_allocated(p)
  deallocate (p)

(of course with a temporary for the function result).
The technical reason for the crash is the copying of the function (non)result.

The patch in comment#9 rejects all related misuses.

Given the lengthy thread on the J3 mailing list, I am wondering whether there
ever was an explicit IR on the issue, or was it considered so obvious that
the clarification was deferred to the F2018 document.



> One place to possibly check for an error is when 
> gfortran resolves argument association.  If a dummy
> argument is allocatable, the actual argument needs 
> to be allocatable and cannot not also be a function
> result variable.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (16 preceding siblings ...)
  2023-04-19 21:03 ` anlauf at gcc dot gnu.org
@ 2023-04-20  5:22 ` kargl at gcc dot gnu.org
  2023-04-20 16:29 ` sgk at troutmask dot apl.washington.edu
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: kargl at gcc dot gnu.org @ 2023-04-20  5:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #18 from kargl at gcc dot gnu.org ---
(In reply to anlauf from comment #17)
> (In reply to Steve Kargl from comment #16)
> > First, note, 'allocated(f())' throws an error.
> 
> Agree.
> 
> > Now, with the original code,
> > 
> >       is_allocated(f())
> > 
> > The function reference is evaluated, and then the function result
> > (aka it's value) is argument associated with an allocatable dummy
> > argument.  This is technically wrong as the actual argument (aka
> > value returned by the function reference) should not have the
> > allocatable attribute.
> 
> Agree.  See also the discussion on the J3 mailing list.
> 
> > I'll repeat.  The actual argument is the value resulting from
> > the function reference.  The "shall" in "shall be allocatable"
> > applies to something the programmer must ensure.
> 
> Agree.
> 
> > If we go back to the original code and modify to allocate
> > f by say doing 'f = 42' in f(), gfortran produces 
> > 
> > % gfcx -o z -Wall a.f90 && ./z
> >  T
> > 
> > This is the problem.  Yes, f is allocated and assigned 
> > 42.  The printed 'T' is bogus because 42 is value of
> > the function.  42 is no allocatable.
> 
> Agree again.
> 
> The point is that there is a bug in gfortran which currently effectively
> generates code which resembles
> 
>   integer, allocatable :: p
>   p = f()
>   print *, is_allocated(p)
>   deallocate (p)
> 
> (of course with a temporary for the function result).
> The technical reason for the crash is the copying of the function
> (non)result.
> 
> The patch in comment#9 rejects all related misuses.
> 
> Given the lengthy thread on the J3 mailing list, I am wondering whether there
> ever was an explicit IR on the issue, or was it considered so obvious that
> the clarification was deferred to the F2018 document.
> 
> 
> 
> > One place to possibly check for an error is when 
> > gfortran resolves argument association.  If a dummy
> > argument is allocatable, the actual argument needs 
> > to be allocatable and cannot not also be a function
> > result variable.

I think we agree on all points.  Here's the diff I envision.
NOte, I've restricted it to user defined functions.  Remove 
the esym check will enable it for any subprogram.


diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index db79b104dc2..f3bcdd76d6a 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -3622,6 +3622,18 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap,
gfc_formal_arglist *formal,
          goto match;
        }

+      if (a->expr->expr_type == EXPR_FUNCTION
+         && a->expr->value.function.esym
+         && f->sym->attr.allocatable)
+       {
+         if (where)
+           gfc_error ("Actual argument for %qs at %L is a function result "
+                       "and the dummy argument is ALLOCATABLE",
+                       f->sym->name, &a->expr->where);
+         ok = false;
+         goto match;
+       }
+
       /* Check intent = OUT/INOUT for definable actual argument.  */
       if (!in_statement_function
          && (f->sym->attr.intent == INTENT_OUT

This gives

% gfcx -c a.f90
a.f90:5:25:

    5 |    print *, is_allocated(f())
      |                         1
Error: Actual argument for 'p' at (1) is a function result and the dummy
argument is ALLOCATABLE

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (17 preceding siblings ...)
  2023-04-20  5:22 ` kargl at gcc dot gnu.org
@ 2023-04-20 16:29 ` sgk at troutmask dot apl.washington.edu
  2023-04-20 19:02 ` anlauf at gcc dot gnu.org
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2023-04-20 16:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #19 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Thu, Apr 20, 2023 at 05:22:59AM +0000, kargl at gcc dot gnu.org wrote:
> 
> I think we agree on all points.  Here's the diff I envision.
> NOte, I've restricted it to user defined functions.  Remove 
> the esym check will enable it for any subprogram.
> 
> 
> diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
> index db79b104dc2..f3bcdd76d6a 100644
> --- a/gcc/fortran/interface.cc
> +++ b/gcc/fortran/interface.cc
> @@ -3622,6 +3622,18 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap,
> gfc_formal_arglist *formal,
>           goto match;
>         }
> 
> +      if (a->expr->expr_type == EXPR_FUNCTION
> +         && a->expr->value.function.esym
> +         && f->sym->attr.allocatable)
> +       {
> +         if (where)
> +           gfc_error ("Actual argument for %qs at %L is a function result "
> +                       "and the dummy argument is ALLOCATABLE",
> +                       f->sym->name, &a->expr->where);
> +         ok = false;
> +         goto match;
> +       }
> +
>        /* Check intent = OUT/INOUT for definable actual argument.  */
>        if (!in_statement_function
>           && (f->sym->attr.intent == INTENT_OUT
> 

The patch passes regtesting.

PS: I think what you want to with a runtime check and an undefine
function result is a good idea.  I haven't looked to see where
and how hard this might be to implement.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (18 preceding siblings ...)
  2023-04-20 16:29 ` sgk at troutmask dot apl.washington.edu
@ 2023-04-20 19:02 ` anlauf at gcc dot gnu.org
  2023-04-20 19:04 ` anlauf at gcc dot gnu.org
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-20 19:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #20 from anlauf at gcc dot gnu.org ---
Created attachment 54894
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54894&action=edit
Extended testcase

Testcase for Steve's variant of the diagnostic, checking that we also catch
procedure pointers with the same interface.

This testcase has been cross-checked with NAG.

The missing diagnostic with Intel has been acknowledged, see:

https://community.intel.com/t5/Intel-Fortran-Compiler/Allocatable-function-result-should-not-have-allocatable/m-p/1478494#M166138

I think we can proceed so that people can fix their codes in time for gcc-14.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (19 preceding siblings ...)
  2023-04-20 19:02 ` anlauf at gcc dot gnu.org
@ 2023-04-20 19:04 ` anlauf at gcc dot gnu.org
  2023-04-20 20:02 ` anlauf at gcc dot gnu.org
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-20 19:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #21 from anlauf at gcc dot gnu.org ---
(In reply to Steve Kargl from comment #19)
> PS: I think what you want to with a runtime check and an undefine
> function result is a good idea.  I haven't looked to see where
> and how hard this might be to implement.

I am considering to create a separate PR to track this.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (20 preceding siblings ...)
  2023-04-20 19:04 ` anlauf at gcc dot gnu.org
@ 2023-04-20 20:02 ` anlauf at gcc dot gnu.org
  2023-04-22 18:50 ` cvs-commit at gcc dot gnu.org
  2023-04-23 18:59 ` anlauf at gcc dot gnu.org
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-20 20:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |anlauf at gcc dot gnu.org

--- Comment #22 from anlauf at gcc dot gnu.org ---
Submitted: https://gcc.gnu.org/pipermail/fortran/2023-April/059202.html

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (21 preceding siblings ...)
  2023-04-20 20:02 ` anlauf at gcc dot gnu.org
@ 2023-04-22 18:50 ` cvs-commit at gcc dot gnu.org
  2023-04-23 18:59 ` anlauf at gcc dot gnu.org
  23 siblings, 0 replies; 25+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-04-22 18:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

--- Comment #23 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:eb385a4801c45a1c0574810b45fce9e712d34566

commit r14-167-geb385a4801c45a1c0574810b45fce9e712d34566
Author: Harald Anlauf <anlauf@gmx.de>
Date:   Thu Apr 20 21:47:34 2023 +0200

    Fortran: function results never have the ALLOCATABLE attribute [PR109500]

    Fortran 2018 8.5.3 (ALLOCATABLE attribute) explains in Note 1 that the
    result of referencing a function whose result variable has the ALLOCATABLE
    attribute is a value that does not itself have the ALLOCATABLE attribute.

    gcc/fortran/ChangeLog:

            PR fortran/109500
            * interface.cc (gfc_compare_actual_formal): Reject allocatable
            functions being used as actual argument for allocable dummy.

    gcc/testsuite/ChangeLog:

            PR fortran/109500
            * gfortran.dg/allocatable_function_11.f90: New test.

    Co-authored-by: Steven G. Kargl <kargl@gcc.gnu.org>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [Bug fortran/109500] SIGABRT when calling a function that returns an unallocated value
  2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
                   ` (22 preceding siblings ...)
  2023-04-22 18:50 ` cvs-commit at gcc dot gnu.org
@ 2023-04-23 18:59 ` anlauf at gcc dot gnu.org
  23 siblings, 0 replies; 25+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-04-23 18:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109500

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
   Target Milestone|---                         |14.0
             Status|ASSIGNED                    |RESOLVED

--- Comment #24 from anlauf at gcc dot gnu.org ---
The argument association issue is fixed for gcc-14.  Thanks for the report!

PR109575 tracks potential improvements of runtime diagnostics when the
function result is not set.

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2023-04-23 18:59 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-13 13:24 [Bug fortran/109500] New: SIGABRT when calling a function that returns an unallocated value leandro.lupori at linaro dot org
2023-04-13 15:05 ` [Bug fortran/109500] " kargl at gcc dot gnu.org
2023-04-13 17:06 ` leandro.lupori at linaro dot org
2023-04-13 18:12 ` kargl at gcc dot gnu.org
2023-04-13 18:32 ` anlauf at gcc dot gnu.org
2023-04-13 19:44 ` leandro.lupori at linaro dot org
2023-04-13 21:28 ` anlauf at gcc dot gnu.org
2023-04-13 21:34 ` sgk at troutmask dot apl.washington.edu
2023-04-14 19:24 ` anlauf at gcc dot gnu.org
2023-04-16 19:42 ` anlauf at gcc dot gnu.org
2023-04-17 12:14 ` leandro.lupori at linaro dot org
2023-04-17 20:20 ` anlauf at gcc dot gnu.org
2023-04-19 17:25 ` leandro.lupori at linaro dot org
2023-04-19 19:02 ` sgk at troutmask dot apl.washington.edu
2023-04-19 19:06 ` anlauf at gcc dot gnu.org
2023-04-19 19:15 ` anlauf at gcc dot gnu.org
2023-04-19 19:42 ` sgk at troutmask dot apl.washington.edu
2023-04-19 21:03 ` anlauf at gcc dot gnu.org
2023-04-20  5:22 ` kargl at gcc dot gnu.org
2023-04-20 16:29 ` sgk at troutmask dot apl.washington.edu
2023-04-20 19:02 ` anlauf at gcc dot gnu.org
2023-04-20 19:04 ` anlauf at gcc dot gnu.org
2023-04-20 20:02 ` anlauf at gcc dot gnu.org
2023-04-22 18:50 ` cvs-commit at gcc dot gnu.org
2023-04-23 18:59 ` anlauf at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).