[Patch, committed] gfortran.dg/pr68078.f90: Avoid increasing RLIMIT_AS

2021-04-22 Thread Tobias Burnus

The test did fail when the virtual memory already had a hard limit !=
unlimited.

Committed as r12-57-gfaf7d413a3f3337be1a3ac5cdf33e0e3b87b426e

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
commit faf7d413a3f3337be1a3ac5cdf33e0e3b87b426e
Author: Tobias Burnus 
Date:   Thu Apr 22 11:05:17 2021 +0200

gfortran.dg/pr68078.f90: Avoid increasing RLIMIT_AS

pr68078.f90 tests out-of-memory handling and calls set_vm_limit to set the
soft limit.  However, setrlimit was then called with hard limit RLIM_INFINITY,
which failed when the current hard limit was lower.

gcc/testsuite/
* gfortran.dg/set_vm_limit.c (set_vm_limit): Call getrlimit, use
obtained hard limit, and only call setrlimit if new softlimit is lower.

diff --git a/gcc/testsuite/gfortran.dg/set_vm_limit.c b/gcc/testsuite/gfortran.dg/set_vm_limit.c
index 30c4b43e0ed..8344f6fd079 100644
--- a/gcc/testsuite/gfortran.dg/set_vm_limit.c
+++ b/gcc/testsuite/gfortran.dg/set_vm_limit.c
@@ -8,9 +8,20 @@
 void
 set_vm_limit (int vm_limit)
 {
-  struct rlimit rl = { vm_limit, RLIM_INFINITY };
+  struct rlimit rl;
   int r;
 
+  r = getrlimit (RLIMIT_AS, &rl);
+  if (r)
+{
+  perror ("get_vm_limit");
+  exit (1);
+}
+
+  if (vm_limit >= rl.rlim_cur)
+return;
+
+  rl.rlim_cur = vm_limit;
   r = setrlimit (RLIMIT_AS, &rl);
   if (r)
 {


testsuite/substr_{9,10}.f90: Move to gfortran.dg/

2021-04-22 Thread Tobias Burnus

The test was added in r11-6687-gbdd1b1f55529da00b867ef05a53a08fbfc3d1c2e 
(PR93340)
but placed into the wrong directly. Fixed by moving to gfortran.dg/
in commit r12-68-gac456fd981db6b0c2f7ee1ab0d17d36087a74dc2 after
confirming that the tests work.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
commit ac456fd981db6b0c2f7ee1ab0d17d36087a74dc2
Author: Tobias Burnus 
Date:   Thu Apr 22 19:14:58 2021 +0200

testsuite/substr_{9,10}.f90: Move to gfortran.dg/

gcc/testsuite/
* substr_9.f90: Move to ...
* gfortran.dg/substr_9.f90: ... here.
* substr_10.f90: Move to ...
* gfortran.dg/substr_10.f90: ... here.
---
 gcc/testsuite/{ => gfortran.dg}/substr_10.f90 | 0
 gcc/testsuite/{ => gfortran.dg}/substr_9.f90  | 0
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/gcc/testsuite/substr_10.f90 b/gcc/testsuite/gfortran.dg/substr_10.f90
similarity index 100%
rename from gcc/testsuite/substr_10.f90
rename to gcc/testsuite/gfortran.dg/substr_10.f90
diff --git a/gcc/testsuite/substr_9.f90 b/gcc/testsuite/gfortran.dg/substr_9.f90
similarity index 100%
rename from gcc/testsuite/substr_9.f90
rename to gcc/testsuite/gfortran.dg/substr_9.f90


[Patch, fortran] PR fortran/82376 - Duplicate function call using -fcheck=pointer

2021-04-22 Thread José Rui Faustino de Sousa via Fortran

Hi All!

Proposed patch to:

PR82376 - Duplicate function call using -fcheck=pointer

Patch tested only on x86_64-pc-linux-gnu.

Evaluate function result and then pass a pointer, instead of a reference 
to the function itself, thus avoiding multiple evaluations of the function.


Thank you very much.

Best regards,
José Rui

Fortran: Fix double function call with -fcheck=pointer [PR]

gcc/fortran/ChangeLog:

PR fortran/82376
* trans-expr.c (gfc_conv_procedure_call): Evaluate function result
and then pass a pointer.

gcc/testsuite/ChangeLog:

PR fortran/82376
* gfortran.dg/PR82376.f90: New test.

diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 213f32b0a67..b83b021755d 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6014,11 +6014,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 			|| (!e->value.function.esym
 && e->symtree->n.sym->attr.pointer))
 			&& fsym && fsym->attr.target)
-		{
-		  gfc_conv_expr (&parmse, e);
-		  parmse.expr = gfc_build_addr_expr (NULL_TREE, parmse.expr);
-		}
-
+		/* Make sure the function only gets called once.  */
+		gfc_conv_expr_reference (&parmse, e, false);
 	  else if (e->expr_type == EXPR_FUNCTION
 		   && e->symtree->n.sym->result
 		   && e->symtree->n.sym->result != e->symtree->n.sym
diff --git a/gcc/testsuite/gfortran.dg/PR82376.f90 b/gcc/testsuite/gfortran.dg/PR82376.f90
new file mode 100644
index 000..cea1c2ae211
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR82376.f90
@@ -0,0 +1,55 @@
+! { dg-do run }
+!
+! Test the fix for PR82376
+!
+
+program main_p
+
+  integer, parameter :: n = 10
+
+  type :: foo_t
+integer, pointer :: v =>null()
+  end type foo_t
+
+  integer, save :: pcnt = 0
+  
+  type(foo_t) :: int
+  integer :: i
+
+  do i = 1, n
+call init(int, i)
+if(.not.associated(int%v)) stop 1
+if(int%v/=i) stop 2
+if(pcnt/=i) stop 3
+  end do
+
+contains
+
+  function new(data) result(this)
+integer, target, intent(in) :: data
+
+integer, pointer :: this
+
+nullify(this)
+this => data
+pcnt = pcnt + 1
+return
+  end function new
+
+  subroutine init(this, data)
+type(foo_t), intent(out) :: this
+integer, intent(in)  :: data
+
+call set(this, new(data))
+return
+  end subroutine init
+
+  subroutine set(this, that)
+type(foo_t), intent(inout) :: this
+integer, target, intent(in):: that
+
+this%v => that
+return
+  end subroutine set
+  
+end program main_p


Re: Fix Fortran rounding issues, PR fortran/96983.

2021-04-22 Thread Michael Meissner via Fortran
On Wed, Apr 21, 2021 at 10:10:07AM +0200, Tobias Burnus wrote:
> On 20.04.21 08:58, Richard Biener via Fortran wrote:
> >On Mon, Apr 19, 2021 at 9:40 PM Michael Meissner via Fortran
> >  wrote:
> Is there any reason to not only send the email to fortran@ _and_
> gcc-patches@ but sending it to 13 Fortran maintainers explicitly? (Now
> removed)

Sorry about that.  With PowerPC backend changes, I generally do explicitly add
the maintainers so things don't get lost.


> >>Fix Fortran rounding issues, PR fortran/96983.
> >>
> >>Can I check this change into the GCC trunk?
> >The patch looks fine technically and is definitely an improvement since the
> >intermediate conversion looks odd.  But it might be that the standard
> >requires such dance though the preceeding cases handled don't seem to
> >care.  I'm thinking of a FP format where round(1.6) == 3 because of lack
> >of precision but using an intermediate FP format with higher precision
> >would "correctly" compute 2.
> 
> The patched build_round_expr is only called by ANINT / NINT;
> NINT is real → integer; ANINT is real → real
> [And the modified code is only called for NINT, reason: see comment far 
> below.]
> 
> NINT (A[, KIND]) is described (F2018) as "Nearest integer":
> * Result Characteristics. Integer. If KIND is present, the kind type parameter
>   is that specified by the value of KIND;
>   otherwise, the kind type parameter is that of default integer type.
> * The result is the integer nearest A, or if there are two
>   integers equally near A, the result is whichever such integer has the 
> greater
>   magnitude.
> * Example. NINT (2.783) has the value 3.
> 
> ANINT (A[, KIND]) as "Nearest whole number":
> * The result is of type real. If KIND is present, the kind type parameter is 
> that
>   specified by the value of KIND; otherwise, the kind type parameter is that 
> of A.
> * The result is the integer nearest A, or if there are two integers equally 
> near A,
>   the result is whichever such integer has the greater magnitude.
> * Examples. ANINT (2.783) has the value 3.0. ANINT (−2.783) has the value 
> −3.0.
> 
> >Of course the current code doesn't handle this correctly for the
> >case if llroundf either.
> >>I've not contributed to the Fortran front end before.  If the maintainers 
> >>like
> >>the patch, can somebody point out if I need to do additional things to 
> >>commit
> >>the patch?
> Nothing special: a testcase already exists, committing is done as usual
> and a PR to update you have as well.

Given GCC 11 has branched, is it ok to backport the patch to the GCC 11 branch
as well?  I assume it is, since it fixes a regression in the compiler.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: Fix Fortran rounding issues, PR fortran/96983.

2021-04-22 Thread Richard Biener via Fortran
On April 22, 2021 9:09:28 PM GMT+02:00, Michael Meissner 
 wrote:
>On Wed, Apr 21, 2021 at 10:10:07AM +0200, Tobias Burnus wrote:
>> On 20.04.21 08:58, Richard Biener via Fortran wrote:
>> >On Mon, Apr 19, 2021 at 9:40 PM Michael Meissner via Fortran
>> >  wrote:
>> Is there any reason to not only send the email to fortran@ _and_
>> gcc-patches@ but sending it to 13 Fortran maintainers explicitly?
>(Now
>> removed)
>
>Sorry about that.  With PowerPC backend changes, I generally do
>explicitly add
>the maintainers so things don't get lost.
>
>
>> >>Fix Fortran rounding issues, PR fortran/96983.
>> >>
>> >>Can I check this change into the GCC trunk?
>> >The patch looks fine technically and is definitely an improvement
>since the
>> >intermediate conversion looks odd.  But it might be that the
>standard
>> >requires such dance though the preceeding cases handled don't seem
>to
>> >care.  I'm thinking of a FP format where round(1.6) == 3 because of
>lack
>> >of precision but using an intermediate FP format with higher
>precision
>> >would "correctly" compute 2.
>> 
>> The patched build_round_expr is only called by ANINT / NINT;
>> NINT is real → integer; ANINT is real → real
>> [And the modified code is only called for NINT, reason: see comment
>far below.]
>> 
>> NINT (A[, KIND]) is described (F2018) as "Nearest integer":
>> * Result Characteristics. Integer. If KIND is present, the kind type
>parameter
>>   is that specified by the value of KIND;
>>   otherwise, the kind type parameter is that of default integer type.
>> * The result is the integer nearest A, or if there are two
>>   integers equally near A, the result is whichever such integer has
>the greater
>>   magnitude.
>> * Example. NINT (2.783) has the value 3.
>> 
>> ANINT (A[, KIND]) as "Nearest whole number":
>> * The result is of type real. If KIND is present, the kind type
>parameter is that
>>   specified by the value of KIND; otherwise, the kind type parameter
>is that of A.
>> * The result is the integer nearest A, or if there are two integers
>equally near A,
>>   the result is whichever such integer has the greater magnitude.
>> * Examples. ANINT (2.783) has the value 3.0. ANINT (−2.783) has the
>value −3.0.
>> 
>> >Of course the current code doesn't handle this correctly for the
>> >case if llroundf either.
>> >>I've not contributed to the Fortran front end before.  If the
>maintainers like
>> >>the patch, can somebody point out if I need to do additional things
>to commit
>> >>the patch?
>> Nothing special: a testcase already exists, committing is done as
>usual
>> and a PR to update you have as well.
>
>Given GCC 11 has branched, is it ok to backport the patch to the GCC 11
>branch
>as well?  I assume it is, since it fixes a regression in the compiler.

Please wait until after 11.1 is released. 

Thanks, 
Richard. 



[Patch] PR fortran/100218 - target of pointer from evaluation of function-reference

2021-04-22 Thread Harald Anlauf via Fortran
Dear Fortranners,

while analyzing a different PR (PR100154), Tobias pointed out that the
target of a pointer from the evaluation of function-reference is allowed
to be used in a variable definition context and thus as an actual
argument to a function or subroutine.

This seems to be a more general issue that seems to have been overlooked.
The attached simple patch allows to compile and run the attached example,
which is by the way already yet rejected with -std=f2003.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?
Shall we backport this to (at least) 11?

Thanks,
Harald


Fortran - allow target of pointer from evaluation of function-reference

Fortran allows the target of a pointer from the evaluation of a
function-reference in a variable definition context (e.g. F2018:R902).

gcc/fortran/ChangeLog:

PR fortran/100218
* expr.c (gfc_check_vardef_context): Extend check to allow pointer
from a function reference.

gcc/testsuite/ChangeLog:

PR fortran/100218
* gfortran.dg/pr100218.f90: New test.

diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 92a6700568d..696b9f1daac 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -6121,7 +6132,9 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj,
 }
   if (!pointer && sym->attr.flavor != FL_VARIABLE
   && !(sym->attr.flavor == FL_PROCEDURE && sym == sym->result)
-  && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer))
+  && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer)
+  && !(sym->attr.flavor == FL_PROCEDURE
+	   && sym->attr.function && sym->attr.pointer))
 {
   if (context)
 	gfc_error ("%qs in variable definition context (%s) at %L is not"
diff --git a/gcc/testsuite/gfortran.dg/pr100218.f90 b/gcc/testsuite/gfortran.dg/pr100218.f90
new file mode 100644
index 000..62b18f6a935
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr100218.f90
@@ -0,0 +1,19 @@
+! { dg-do run }
+! { dg-options "-O2 -std=f2008" }
+! PR fortran/100218 - target of pointer from evaluation of function-reference
+
+program p
+  implicit none
+  integer, target :: z = 0
+  call g (f ())
+  if (z /= 1) stop 1
+contains
+  function f () result (r)
+integer, pointer :: r
+r => z
+  end function f
+  subroutine g (x)
+integer, intent(out) :: x
+x = 1
+  end subroutine g
+end program p


[Patch] PR fortran/100154 - [9/10/11/12 Regression] ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

2021-04-22 Thread Harald Anlauf via Fortran
Dear Fortranners,

we need to check the arguments to the affected GNU intrinsic extensions
properly, and - as pointed out in the PR by Tobias - we need to allow
function references that have a data pointer result.  Also the argument
names of the character arguments of the subroutine versions needed a
fix ("c" instead of "count").

Regtested on x86_64-pc-linux-gnu.  OK for mainline (12)?
OK for backports after 11.1 release?

Thanks,
Harald


PR fortran/100154 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

Add appropriate static checks for the character and status arguments to
the GNU Fortran intrinsic extensions fget[c], fput[c].  Extend variable
check to allow a function reference having a data pointer result.

gcc/fortran/ChangeLog:

PR fortran/100154
* check.c (variable_check): Allow function reference having a data
pointer result.
(arg_strlen_is_zero): New function.
(gfc_check_fgetputc_sub): Add static check of character and status
arguments.
(gfc_check_fgetput_sub): Likewise.
* intrinsic.c (add_subroutines): Fix argument name for the
character argument to intrinsic subroutines fget[c], fput[c].

gcc/testsuite/ChangeLog:

PR fortran/100154
* gfortran.dg/pr100154.f90: New test.

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 82db8e4e1b2..1d30c93df82 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -5689,6 +5691,19 @@ gfc_check_spread (gfc_expr *source, gfc_expr *dim, gfc_expr *ncopies)
 /* Functions for checking FGETC, FPUTC, FGET and FPUT (subroutines and
functions).  */

+bool
+arg_strlen_is_zero (gfc_expr *c, int n)
+{
+  if (gfc_var_strlen (c) == 0)
+{
+  gfc_error ("%qs argument of %qs intrinsic at %L must have "
+		 "length at least 1", gfc_current_intrinsic_arg[n]->name,
+		 gfc_current_intrinsic, &c->where);
+  return true;
+}
+  return false;
+}
+
 bool
 gfc_check_fgetputc_sub (gfc_expr *unit, gfc_expr *c, gfc_expr *status)
 {
@@ -5702,13 +5717,19 @@ gfc_check_fgetputc_sub (gfc_expr *unit, gfc_expr *c, gfc_expr *status)
 return false;
   if (!kind_value_check (c, 1, gfc_default_character_kind))
 return false;
+  if (strcmp (gfc_current_intrinsic, "fgetc") == 0
+  && !variable_check (c, 1, false))
+return false;
+  if (arg_strlen_is_zero (c, 1))
+return false;

   if (status == NULL)
 return true;

   if (!type_check (status, 2, BT_INTEGER)
   || !kind_value_check (status, 2, gfc_default_integer_kind)
-  || !scalar_check (status, 2))
+  || !scalar_check (status, 2)
+  || !variable_check (status, 2, false))
 return false;

   return true;
@@ -5729,13 +5750,19 @@ gfc_check_fgetput_sub (gfc_expr *c, gfc_expr *status)
 return false;
   if (!kind_value_check (c, 0, gfc_default_character_kind))
 return false;
+  if (strcmp (gfc_current_intrinsic, "fget") == 0
+  && !variable_check (c, 0, false))
+return false;
+  if (arg_strlen_is_zero (c, 0))
+return false;

   if (status == NULL)
 return true;

   if (!type_check (status, 1, BT_INTEGER)
   || !kind_value_check (status, 1, gfc_default_integer_kind)
-  || !scalar_check (status, 1))
+  || !scalar_check (status, 1)
+  || !variable_check (status, 1, false))
 return false;

   return true;
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 17fd92eb462..219f04f2317 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -3460,7 +3460,7 @@ add_subroutines (void)
   /* Argument names.  These are used as argument keywords and so need to
  match the documentation.  Please keep this list in sorted order.  */
   static const char
-*a = "a", *c = "count", *cm = "count_max", *com = "command",
+*a = "a", *c_ = "c", *c = "count", *cm = "count_max", *com = "command",
 *cr = "count_rate", *dt = "date", *errmsg = "errmsg", *f = "from",
 *fp = "frompos", *gt = "get", *h = "harvest", *han = "handler",
 *length = "length", *ln = "len", *md = "mode", *msk = "mask",
@@ -3840,12 +3840,12 @@ add_subroutines (void)
   add_sym_3s ("fgetc", GFC_ISYM_FGETC, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
 	  gfc_check_fgetputc_sub, NULL, gfc_resolve_fgetc_sub,
 	  ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
-	  c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+	  c_, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
 	  st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);

   add_sym_2s ("fget", GFC_ISYM_FGET, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
 	  gfc_check_fgetput_sub, NULL, gfc_resolve_fget_sub,
-	  c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+	  c_, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
 	  st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);

   add_sym_1s ("flush", GFC_ISYM_FLUSH, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
@@ -3855,12 +3855,12 @@ add_subroutines (void)
   add_sym_3s ("fputc", GFC_ISYM_FPUTC, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
 	  gfc_check_fgetputc_sub, NULL,

[Patch] PR fortran/100154 - [9/10/11/12 Regression] ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

2021-04-22 Thread Harald Anlauf via Fortran
Now with the correct patch attached ...

Sorry for the confusion!

---

Dear Fortranners,

we need to check the arguments to the affected GNU intrinsic extensions
properly, and - as pointed out in the PR by Tobias - we need to allow
function references that have a data pointer result.  Also the argument
names of the character arguments of the subroutine versions needed a
fix ("c" instead of "count").

Regtested on x86_64-pc-linux-gnu.  OK for mainline (12)?
OK for backports after 11.1 release?

Thanks,
Harald


PR fortran/100154 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

Add appropriate static checks for the character and status arguments to
the GNU Fortran intrinsic extensions fget[c], fput[c].  Extend variable
check to allow a function reference having a data pointer result.

gcc/fortran/ChangeLog:

PR fortran/100154
* check.c (variable_check): Allow function reference having a data
pointer result.
(arg_strlen_is_zero): New function.
(gfc_check_fgetputc_sub): Add static check of character and status
arguments.
(gfc_check_fgetput_sub): Likewise.
* intrinsic.c (add_subroutines): Fix argument name for the
character argument to intrinsic subroutines fget[c], fput[c].

gcc/testsuite/ChangeLog:

PR fortran/100154
* gfortran.dg/pr100154.f90: New test.

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 82db8e4e1b2..1d30c93df82 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -1055,6 +1055,13 @@ variable_check (gfc_expr *e, int n, bool allow_proc)
  return true;
 }

+  /* F2018:R902: function reference having a data pointer result.  */
+  if (e->expr_type == EXPR_FUNCTION
+  && e->symtree->n.sym->attr.flavor == FL_PROCEDURE
+  && e->symtree->n.sym->attr.function
+  && e->symtree->n.sym->attr.pointer)
+return true;
+
   gfc_error ("%qs argument of %qs intrinsic at %L must be a variable",
 gfc_current_intrinsic_arg[n]->name, gfc_current_intrinsic, &e->where);

@@ -5689,6 +5691,19 @@ gfc_check_spread (gfc_expr *source, gfc_expr *dim, gfc_expr *ncopies)
 /* Functions for checking FGETC, FPUTC, FGET and FPUT (subroutines and
functions).  */

+bool
+arg_strlen_is_zero (gfc_expr *c, int n)
+{
+  if (gfc_var_strlen (c) == 0)
+{
+  gfc_error ("%qs argument of %qs intrinsic at %L must have "
+		 "length at least 1", gfc_current_intrinsic_arg[n]->name,
+		 gfc_current_intrinsic, &c->where);
+  return true;
+}
+  return false;
+}
+
 bool
 gfc_check_fgetputc_sub (gfc_expr *unit, gfc_expr *c, gfc_expr *status)
 {
@@ -5702,13 +5717,19 @@ gfc_check_fgetputc_sub (gfc_expr *unit, gfc_expr *c, gfc_expr *status)
 return false;
   if (!kind_value_check (c, 1, gfc_default_character_kind))
 return false;
+  if (strcmp (gfc_current_intrinsic, "fgetc") == 0
+  && !variable_check (c, 1, false))
+return false;
+  if (arg_strlen_is_zero (c, 1))
+return false;

   if (status == NULL)
 return true;

   if (!type_check (status, 2, BT_INTEGER)
   || !kind_value_check (status, 2, gfc_default_integer_kind)
-  || !scalar_check (status, 2))
+  || !scalar_check (status, 2)
+  || !variable_check (status, 2, false))
 return false;

   return true;
@@ -5729,13 +5750,19 @@ gfc_check_fgetput_sub (gfc_expr *c, gfc_expr *status)
 return false;
   if (!kind_value_check (c, 0, gfc_default_character_kind))
 return false;
+  if (strcmp (gfc_current_intrinsic, "fget") == 0
+  && !variable_check (c, 0, false))
+return false;
+  if (arg_strlen_is_zero (c, 0))
+return false;

   if (status == NULL)
 return true;

   if (!type_check (status, 1, BT_INTEGER)
   || !kind_value_check (status, 1, gfc_default_integer_kind)
-  || !scalar_check (status, 1))
+  || !scalar_check (status, 1)
+  || !variable_check (status, 1, false))
 return false;

   return true;
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 17fd92eb462..219f04f2317 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -3460,7 +3460,7 @@ add_subroutines (void)
   /* Argument names.  These are used as argument keywords and so need to
  match the documentation.  Please keep this list in sorted order.  */
   static const char
-*a = "a", *c = "count", *cm = "count_max", *com = "command",
+*a = "a", *c_ = "c", *c = "count", *cm = "count_max", *com = "command",
 *cr = "count_rate", *dt = "date", *errmsg = "errmsg", *f = "from",
 *fp = "frompos", *gt = "get", *h = "harvest", *han = "handler",
 *length = "length", *ln = "len", *md = "mode", *msk = "mask",
@@ -3840,12 +3840,12 @@ add_subroutines (void)
   add_sym_3s ("fgetc", GFC_ISYM_FGETC, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
 	  gfc_check_fgetputc_sub, NULL, gfc_resolve_fgetc_sub,
 	  ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
-	  c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+	  c_, BT_CHARACTER, dc, REQUIRED,