diff mbox series

PR fortran/90166 -- Add check for module prefix

Message ID 20190502060608.GA53183@troutmask.apl.washington.edu
State New
Headers show
Series PR fortran/90166 -- Add check for module prefix | expand

Commit Message

Steve Kargl May 2, 2019, 6:06 a.m. UTC
The attach patch adds a check that a module prefix 
occurs only in a module, submodule, or interface.

C1547 (R1526) MODULE shall appear only in the function-stmt or
   subroutine-stmt of a module subprogram or of a nonabstract
   interface body that is declared in the scoping unit of a
   module or submodule.

The patch has been bootstrapped and regression
tested on x86_64-*-freebsd.  OK to commit?

2019-04-19  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/90166
	* decl.c (in_module_or_interface): New function to check that the
	current state is in a module, submodule, or interface.
	(gfc_match_prefix): Use it.

	PR fortran/90166
	* gfortran.dg/submodule_22.f08: Add additional dg-error comments.

Comments

Steve Kargl May 6, 2019, 11:17 p.m. UTC | #1
Ping.

On Wed, May 01, 2019 at 11:06:08PM -0700, Steve Kargl wrote:
> The attach patch adds a check that a module prefix 
> occurs only in a module, submodule, or interface.
> 
> C1547 (R1526) MODULE shall appear only in the function-stmt or
>    subroutine-stmt of a module subprogram or of a nonabstract
>    interface body that is declared in the scoping unit of a
>    module or submodule.
> 
> The patch has been bootstrapped and regression
> tested on x86_64-*-freebsd.  OK to commit?
> 
> 2019-04-19  Steven G. Kargl  <kargl@gcc.gnu.org>
> 
> 	PR fortran/90166
> 	* decl.c (in_module_or_interface): New function to check that the
> 	current state is in a module, submodule, or interface.
> 	(gfc_match_prefix): Use it.
> 
> 	PR fortran/90166
> 	* gfortran.dg/submodule_22.f08: Add additional dg-error comments.
> 
> -- 
> Steve

> Index: gcc/fortran/decl.c
> ===================================================================
> --- gcc/fortran/decl.c	(revision 270181)
> +++ gcc/fortran/decl.c	(working copy)
> @@ -6070,7 +6070,29 @@ cleanup:
>    return m;
>  }
>  
> +static bool
> +in_module_or_interface(void)
> +{
> +  if (gfc_current_state () == COMP_MODULE
> +      || gfc_current_state () == COMP_SUBMODULE 
> +      || gfc_current_state () == COMP_INTERFACE)
> +    return true;
>  
> +  if (gfc_state_stack->state == COMP_CONTAINS
> +      || gfc_state_stack->state == COMP_FUNCTION
> +      || gfc_state_stack->state == COMP_SUBROUTINE)
> +    {
> +      gfc_state_data *p;
> +      for (p = gfc_state_stack->previous; p ; p = p->previous)
> +	{
> +	  if (p->state == COMP_MODULE || p->state == COMP_SUBMODULE 
> +	      || p->state == COMP_INTERFACE)
> +	    return true;
> +	}
> +    }
> +    return false;
> +}
> +
>  /* Match a prefix associated with a function or subroutine
>     declaration.  If the typespec pointer is nonnull, then a typespec
>     can be matched.  Note that if nothing matches, MATCH_YES is
> @@ -6102,6 +6124,13 @@ gfc_match_prefix (gfc_typespec *ts)
>  	{
>  	  if (!gfc_notify_std (GFC_STD_F2008, "MODULE prefix at %C"))
>  	    goto error;
> +
> +	  if (!in_module_or_interface ())
> +	    {
> +	      gfc_error ("MODULE prefix at %C found outside of a module, "
> +			 "submodule, or INTERFACE");
> +	      goto error;
> +	    }
>  
>  	  current_attr.module_procedure = 1;
>  	  found_prefix = true;
> Index: gcc/testsuite/gfortran.dg/submodule_22.f08
> ===================================================================
> --- gcc/testsuite/gfortran.dg/submodule_22.f08	(revision 270181)
> +++ gcc/testsuite/gfortran.dg/submodule_22.f08	(working copy)
> @@ -40,8 +40,10 @@ end
>  
>  submodule (mtop:submod:subsubmod) subsubsubmod ! { dg-error "Syntax error in SUBMODULE statement" }
>  contains
> -  module subroutine sub3
> -    r = 2.0
> -    s = 2.0
> -  end subroutine sub3
> +  module subroutine sub3  ! { dg-error "found outside of a module" }
> +    r = 2.0               ! { dg-error "Unexpected assignment" }
> +    s = 2.0               ! { dg-error "Unexpected assignment" }
> +  end subroutine sub3     ! { dg-error "Expecting END PROGRAM statement" }
>  end
> +
> +found outside of a module
diff mbox series

Patch

Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 270181)
+++ gcc/fortran/decl.c	(working copy)
@@ -6070,7 +6070,29 @@  cleanup:
   return m;
 }
 
+static bool
+in_module_or_interface(void)
+{
+  if (gfc_current_state () == COMP_MODULE
+      || gfc_current_state () == COMP_SUBMODULE 
+      || gfc_current_state () == COMP_INTERFACE)
+    return true;
 
+  if (gfc_state_stack->state == COMP_CONTAINS
+      || gfc_state_stack->state == COMP_FUNCTION
+      || gfc_state_stack->state == COMP_SUBROUTINE)
+    {
+      gfc_state_data *p;
+      for (p = gfc_state_stack->previous; p ; p = p->previous)
+	{
+	  if (p->state == COMP_MODULE || p->state == COMP_SUBMODULE 
+	      || p->state == COMP_INTERFACE)
+	    return true;
+	}
+    }
+    return false;
+}
+
 /* Match a prefix associated with a function or subroutine
    declaration.  If the typespec pointer is nonnull, then a typespec
    can be matched.  Note that if nothing matches, MATCH_YES is
@@ -6102,6 +6124,13 @@  gfc_match_prefix (gfc_typespec *ts)
 	{
 	  if (!gfc_notify_std (GFC_STD_F2008, "MODULE prefix at %C"))
 	    goto error;
+
+	  if (!in_module_or_interface ())
+	    {
+	      gfc_error ("MODULE prefix at %C found outside of a module, "
+			 "submodule, or INTERFACE");
+	      goto error;
+	    }
 
 	  current_attr.module_procedure = 1;
 	  found_prefix = true;
Index: gcc/testsuite/gfortran.dg/submodule_22.f08
===================================================================
--- gcc/testsuite/gfortran.dg/submodule_22.f08	(revision 270181)
+++ gcc/testsuite/gfortran.dg/submodule_22.f08	(working copy)
@@ -40,8 +40,10 @@  end
 
 submodule (mtop:submod:subsubmod) subsubsubmod ! { dg-error "Syntax error in SUBMODULE statement" }
 contains
-  module subroutine sub3
-    r = 2.0
-    s = 2.0
-  end subroutine sub3
+  module subroutine sub3  ! { dg-error "found outside of a module" }
+    r = 2.0               ! { dg-error "Unexpected assignment" }
+    s = 2.0               ! { dg-error "Unexpected assignment" }
+  end subroutine sub3     ! { dg-error "Expecting END PROGRAM statement" }
 end
+
+found outside of a module