Bug 35203 - OPTIONAL, VALUE actual argument cannot be an INTEGER 0
Summary: OPTIONAL, VALUE actual argument cannot be an INTEGER 0
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 49802
  Show dependency treegraph
 
Reported: 2008-02-14 23:04 UTC by Toon Moene
Modified: 2013-03-29 22:35 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-02-15 01:06:23


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Toon Moene 2008-02-14 23:04:41 UTC
Run this program:

      INTERFACE
      SUBROUTINE AAP(I)
      INTEGER, OPTIONAL, VALUE :: I
      END SUBROUTINE
      END INTERFACE
      CALL AAP(0)
      END
      SUBROUTINE AAP(N)
      INTEGER, OPTIONAL, VALUE :: N
      IF (PRESENT(N)) THEN
         PRINT*,'PRESENT, WITH VALUE:',N
      ELSE
         PRINT*,'NOT PRESENT'
      ENDIF
      END

and get:

$ ./a.out
 NOT PRESENT
$

which should come to no surprise, if one glazes his/her eyes over trans_expr.c:gfc_conv_missing_dummy.
Comment 1 Tobias Burnus 2008-02-14 23:46:37 UTC
I think this is a defect in the standard; it should not be possible to combine VALUE with OPTIONAL; currently all my compilers fail like gfortran.

At the moment I do not see how one could implement this if WG5 insists that this is valid - except of passing a hidden argument.
Comment 2 Tobias Burnus 2008-02-15 00:03:04 UTC
I now checked the F2003 standard + the two corrigenda and it misses this clause. For TYPE such clauses were added in a corrigendum.

As you are a J3 member, can you create an interpretation request?

By the way, the right place for this edit would be the following:

C527 (R501) If the VALUE attribute is specified, the PARAMETER, EXTERNAL, 
            POINTER, ALLOCATABLE, DIMENSION, VOLATILE, INTENT(INOUT), or 
            INTENT(OUT) attribute shall not be specified.

One only needs to insert a "OPTIONAL, ". I think it is obvious why it should be invalid, isn't it?

For gfortran I would recommend:

Index: symbol.c
===================================================================
--- symbol.c    (revision 132324)
+++ symbol.c    (working copy)
@@ -519,6 +519,7 @@

   conf (value, pointer)
   conf (value, allocatable)
+  conf (value, optional)
   conf (value, subroutine)
   conf (value, function)
   conf (value, volatile_)
Comment 3 Toon Moene 2008-02-15 01:04:01 UTC
> At the moment I do not see how one could implement this if WG5 insists that
> this is valid - except of passing a hidden argument.

As I am at a WG5 just right now, I decided to ask.  Allowing OPTIONAL,VALUE was a conscious decision by the Committee (although not necessarily an unanimous one :-)
Comment 4 Jerry DeLisle 2008-02-15 06:11:24 UTC
Try this, seems to work, though I have not regression tested.

Index: trans-expr.c
===================================================================
--- trans-expr.c        (revision 132313)
+++ trans-expr.c        (working copy)
@@ -139,8 +139,13 @@ gfc_conv_expr_present (gfc_symbol * sym)
              || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
       decl = GFC_DECL_SAVED_DESCRIPTOR (decl);
     }
-  return build2 (NE_EXPR, boolean_type_node, decl,
-                fold_convert (TREE_TYPE (decl), null_pointer_node));
+
+  if (sym->attr.value)
+    return build2 (NE_EXPR, boolean_type_node, build_fold_addr_expr (decl),
+                  fold_convert (TREE_TYPE (decl), null_pointer_node));
+  else
+    return build2 (NE_EXPR, boolean_type_node, decl,
+                  fold_convert (TREE_TYPE (decl), null_pointer_node));
 }
 
Comment 5 Jerry DeLisle 2008-02-15 06:35:59 UTC
Scratch the patch in comment #4. When the argument is passed by value and is missing the call looks like:

  aap(0b)

So I was thinking we could build:

  if (&n != 0b)

Comment 6 Tobias Burnus 2008-02-15 07:17:17 UTC
> As I am at a WG5 just right now, I decided to ask.  Allowing OPTIONAL,VALUE
> was a conscious decision by the Committee (although not necessarily an
> unanimous one :-)

Can you ask the other vendors how they plan to implement it? Or if you find a non-vendor proponent, how he would implement it.

For a pointer (C sense) it is easy:

if (pointer == NULL) -> check for presence
if (*pointer == 0) -> check for its value

But if I have a value, there is no chance to check for it directly - except for passing a hidden argument; unless we can convince J3/WG5 to change their opinion, that is what I propose to do. The hidden argument would then be added after the character length arguments.

As written, I checked all my compilers and all get a wrong result
- gfortran, g95, NAG f95: NOT PRESENT
- ifort: PRESENT, WITH VALUE: 0   (even if not present)
  (ifort 10 and ifort 10.1 print a warning that present should not be used with 
  value; ifort 9 give the same run-time result, but does not have the warning)
- sunf95: Compile-time error: OPTIONAL and VALUE may not be used both

(While we are at it: Please make sure that OPTION + VALUE + BIND(C) will not be allowed in the upcoming interoperability TR; if it is included, there should be a note giving implementation suggestions. F2003 is unaffected by this as OPTIONAL is not allowed with BIND(C).)
Comment 7 Toon Moene 2008-02-15 18:15:15 UTC
> As written, I checked all my compilers and all get a wrong result
> - gfortran, g95, NAG f95: NOT PRESENT
> - ifort: PRESENT, WITH VALUE: 0   (even if not present)
>   (ifort 10 and ifort 10.1 print a warning that present should not be used with 
>   value; ifort 9 give the same run-time result, but does not have the warning)
> - sunf95: Compile-time error: OPTIONAL and VALUE may not be used both

I just asked Bill Long of Cray (who heads the subgroup that covers this) to try it on Cray's compiler - it ICE'd with a message that clearly showed that it didn't expect to be handed an OPTIONAL, VALUE argument (without flagging it as a not-legal construct, though).

I'm closing the PR as "WONTFIX".

> (While we are at it: Please make sure that OPTION + VALUE + BIND(C) will not be
> allowed in the upcoming interoperability TR; if it is included, there should be
> a note giving implementation suggestions. F2003 is unaffected by this as
> OPTIONAL is not allowed with BIND(C).)

You bet.  There was a heated discussion on this yesterday, which didn't result in any progress.   Bill will send out an e-mail with the issues.
Comment 8 Tobias Burnus 2008-02-15 20:04:15 UTC
(In reply to comment #7)
> I just asked Bill Long of Cray (who heads the subgroup that covers this) to
> try it on Cray's compiler - it ICE'd with a message that clearly showed that
> it didn't expect to be handed an OPTIONAL, VALUE argument (without flagging it
> as a not-legal construct, though).

What will happen now? Will anyone send an interpretation request, which will bring it up on the table again?

> > (While we are at it: Please make sure that OPTION + VALUE + BIND(C) will
> > not beallowed in the upcoming interoperability TR
>
> You bet.  There was a heated discussion on this yesterday, which didn't result
> in any progress.   Bill will send out an e-mail with the issues.

Thanks - as the TR has not been published yet, it should be easier to fix that the standard.

I intent to submit the following patch:

--- symbol.c    (revision 132332)
+++ symbol.c    (working copy)
@@ -535,2 +535,14 @@ check_conflict (symbol_attribute *attr,

+  if (attr->value && attr->optional)
+    {
+      if (name == NULL)
+       gfc_error ("GNU Fortran does not support dummy argument at %L with "
+                  "both VALUE and OPTIONAL attribute", where);
+      else
+       gfc_error ("GNU Fortran does not support dummy argument '%s' at %L "
+                  "with both VALUE and OPTIONAL attribute", name, where);
+
+      return FAILURE;
+    }
+
   conf (protected, intrinsic)
Comment 9 Toon Moene 2008-02-18 08:32:04 UTC
> What will happen now? Will anyone send an interpretation request, which will
> bring it up on the table again?

No, as it isn't *impossible* to implement it (with a hidden argument), an interp won't stand a chance.

> I intent to submit the following patch:

Yep, it's *much* better to say outright that we do not support it.  We will hear from people who actually need it :-)

Thanks.
Comment 10 Tobias Schlüter 2008-03-26 21:09:39 UTC
A lovely design by committee feature that is.

An alternative implementation strategy would be to use the same calling convention as for pass-by-reference arguments and then copy on entry (if present, and as an optimization, only if it is indeed written to in the procedure body).
Comment 11 Tobias Burnus 2013-03-21 18:07:18 UTC
Patch http://gcc.gnu.org/ml/fortran/2013-03/msg00102.html

(For value + array/derived type/class, w/ and w/o optional, see PR 49802.)
Comment 12 Tobias Burnus 2013-03-29 22:32:32 UTC
Author: burnus
Date: Fri Mar 29 22:26:17 2013
New Revision: 197252

URL: http://gcc.gnu.org/viewcvs?rev=197252&root=gcc&view=rev
Log:
2013-03-29  Tobias Burnus  <burnus@net-b.de>

        PR fortran/35203
        * trans-decl.c (create_function_arglist): Pass hidden argument
        for passed-by-value optional+value dummies.
        * trans-expr.c (gfc_conv_expr_present,
        gfc_conv_procedure_call): Handle those.

2013-03-29  Tobias Burnus  <burnus@net-b.de>

        PR fortran/35203
        * gfortran.dg/optional_absent_3.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/optional_absent_3.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 13 Tobias Burnus 2013-03-29 22:35:01 UTC
FIXED on the 4.9 trunk.

Thanks Toon for pointing out this feature. The feature is handled in the same way as IBM: The hidden present argument is passed before the hidden string-length arguments.