public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
@ 2016-06-30 17:47 Jakub Jelinek
  2016-07-08 16:13 ` Cesar Philippidis
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2016-06-30 17:47 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Cesar Philippidis

Hi!

The Fortran parser apparently relies in functions that have still undecided
kind of the result that ST_GET_FCN_CHARACTERISTICS artificial statement is
returned before any executable statements in the function.
In normal statements that is ensured through decode_statement calling
decode_specification_statement, which parses just a subset of statements,
but for OpenMP we need to do something similar.  If we figure out we want
only the case_omp_decl statements, for any other we just try to gfc_match
the keyword and if we match it, it means we'd be about to return an OpenMP
executable statement, so instead return ST_GET_FCN_CHARACTERISTICS.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
queued for 6.2 backport.

Cesar, note OpenACC will need something similar (though,
decode_acc_statement uses just the match macro, so you'll need another one
for the executable statements).

2016-06-30  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/71704
	* parse.c (matchs, matcho): Move right before decode_omp_directive.
	If spec_only, only gfc_match the keyword and if successful, goto
	do_spec_only.
	(matchds, matchdo): Define.
	(decode_omp_directive): Add spec_only local var and set it.
	Use matchds or matchdo macros instead of matchs or matcho
	for declare target, declare simd, declare reduction and threadprivate
	directives.  Return ST_GET_FCN_CHARACTERISTICS if a non-declarative
	directive could be matched.
	(next_statement): For ST_GET_FCN_CHARACTERISTICS restore
	gfc_current_locus from old_locus even if there is no label.

	* gfortran.dg/gomp/pr71704.f90: New test.

--- gcc/fortran/parse.c.jj	2016-06-01 14:20:51.000000000 +0200
+++ gcc/fortran/parse.c	2016-06-30 15:32:20.003410398 +0200
@@ -589,28 +589,6 @@ decode_statement (void)
   return ST_NONE;
 }
 
-/* Like match, but set a flag simd_matched if keyword matched.  */
-#define matchs(keyword, subr, st)				\
-    do {							\
-      if (match_word_omp_simd (keyword, subr, &old_locus,	\
-			       &simd_matched) == MATCH_YES)	\
-	return st;						\
-      else							\
-	undo_new_statement ();				  	\
-    } while (0);
-
-/* Like match, but don't match anything if not -fopenmp.  */
-#define matcho(keyword, subr, st)				\
-    do {							\
-      if (!flag_openmp)						\
-	;							\
-      else if (match_word (keyword, subr, &old_locus)		\
-	       == MATCH_YES)					\
-	return st;						\
-      else							\
-	undo_new_statement ();				  	\
-    } while (0);
-
 static gfc_statement
 decode_oacc_directive (void)
 {
@@ -702,12 +680,63 @@ decode_oacc_directive (void)
   return ST_NONE;
 }
 
+/* Like match, but set a flag simd_matched if keyword matched
+   and if spec_only, goto do_spec_only without actually matching.  */
+#define matchs(keyword, subr, st)				\
+    do {							\
+      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
+	goto do_spec_only;					\
+      if (match_word_omp_simd (keyword, subr, &old_locus,	\
+			       &simd_matched) == MATCH_YES)	\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
+/* Like match, but don't match anything if not -fopenmp
+   and if spec_only, goto do_spec_only without actually matching.  */
+#define matcho(keyword, subr, st)				\
+    do {							\
+      if (!flag_openmp)						\
+	;							\
+      else if (spec_only && gfc_match (keyword) == MATCH_YES)	\
+	goto do_spec_only;					\
+      else if (match_word (keyword, subr, &old_locus)		\
+	       == MATCH_YES)					\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
+/* Like match, but set a flag simd_matched if keyword matched.  */
+#define matchds(keyword, subr, st)				\
+    do {							\
+      if (match_word_omp_simd (keyword, subr, &old_locus,	\
+			       &simd_matched) == MATCH_YES)	\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
+/* Like match, but don't match anything if not -fopenmp.  */
+#define matchdo(keyword, subr, st)				\
+    do {							\
+      if (!flag_openmp)						\
+	;							\
+      else if (match_word (keyword, subr, &old_locus)		\
+	       == MATCH_YES)					\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
 static gfc_statement
 decode_omp_directive (void)
 {
   locus old_locus;
   char c;
   bool simd_matched = false;
+  bool spec_only = false;
 
   gfc_enforce_clean_symbol_state ();
 
@@ -722,6 +751,10 @@ decode_omp_directive (void)
       return ST_NONE;
     }
 
+  if (gfc_current_state () == COMP_FUNCTION
+      && gfc_current_block ()->result->ts.kind == -1)
+    spec_only = true;
+
   gfc_unset_implicit_pure (NULL);
 
   old_locus = gfc_current_locus;
@@ -750,12 +783,12 @@ decode_omp_directive (void)
       matcho ("critical", gfc_match_omp_critical, ST_OMP_CRITICAL);
       break;
     case 'd':
-      matchs ("declare reduction", gfc_match_omp_declare_reduction,
-	      ST_OMP_DECLARE_REDUCTION);
-      matchs ("declare simd", gfc_match_omp_declare_simd,
-	      ST_OMP_DECLARE_SIMD);
-      matcho ("declare target", gfc_match_omp_declare_target,
-	      ST_OMP_DECLARE_TARGET);
+      matchds ("declare reduction", gfc_match_omp_declare_reduction,
+	       ST_OMP_DECLARE_REDUCTION);
+      matchds ("declare simd", gfc_match_omp_declare_simd,
+	       ST_OMP_DECLARE_SIMD);
+      matchdo ("declare target", gfc_match_omp_declare_target,
+	       ST_OMP_DECLARE_TARGET);
       matchs ("distribute parallel do simd",
 	      gfc_match_omp_distribute_parallel_do_simd,
 	      ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD);
@@ -875,8 +908,8 @@ decode_omp_directive (void)
       matcho ("teams distribute", gfc_match_omp_teams_distribute,
 	      ST_OMP_TEAMS_DISTRIBUTE);
       matcho ("teams", gfc_match_omp_teams, ST_OMP_TEAMS);
-      matcho ("threadprivate", gfc_match_omp_threadprivate,
-	      ST_OMP_THREADPRIVATE);
+      matchdo ("threadprivate", gfc_match_omp_threadprivate,
+	       ST_OMP_THREADPRIVATE);
       break;
     case 'w':
       matcho ("workshare", gfc_match_omp_workshare, ST_OMP_WORKSHARE);
@@ -899,6 +932,13 @@ decode_omp_directive (void)
   gfc_error_recovery ();
 
   return ST_NONE;
+
+ do_spec_only:
+  reject_statement ();
+  gfc_clear_error ();
+  gfc_buffer_error (false);
+  gfc_current_locus = old_locus;
+  return ST_GET_FCN_CHARACTERISTICS;
 }
 
 static gfc_statement
@@ -1319,10 +1359,13 @@ next_statement (void)
 
   gfc_buffer_error (false);
 
-  if (st == ST_GET_FCN_CHARACTERISTICS && gfc_statement_label != NULL)
+  if (st == ST_GET_FCN_CHARACTERISTICS)
     {
-      gfc_free_st_label (gfc_statement_label);
-      gfc_statement_label = NULL;
+      if (gfc_statement_label != NULL)
+	{
+	  gfc_free_st_label (gfc_statement_label);
+	  gfc_statement_label = NULL;
+	}
       gfc_current_locus = old_locus;
     }
 
--- gcc/testsuite/gfortran.dg/gomp/pr71704.f90.jj	2016-06-30 15:26:45.920563584 +0200
+++ gcc/testsuite/gfortran.dg/gomp/pr71704.f90	2016-06-30 15:26:23.000000000 +0200
@@ -0,0 +1,58 @@
+! PR fortran/71704
+! { dg-do compile }
+
+real function f0 ()
+!$omp declare simd (f0)
+  f0 = 1
+end
+
+real function f1 ()
+!$omp declare target (f1)
+  f1 = 1
+end
+
+real function f2 ()
+!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in) &
+!$omp & initializer (omp_priv = 0)
+  f2 = 1
+end
+
+real function f3 ()
+  real, save :: t
+!$omp threadprivate (t)
+  f3 = 1
+end
+
+real function f4 ()
+!$omp taskwait
+  f4 = 1
+end
+
+real function f5 ()
+!$omp barrier
+  f5 = 1
+end
+
+real function f6 ()
+!$omp parallel
+!$omp end parallel
+  f6 = 1
+end
+
+real function f7 ()
+!$omp single
+!$omp end single
+  f7 = 1
+end
+
+real function f8 ()
+!$omp critical
+!$omp end critical
+  f8 = 1
+end
+
+real function f9 ()
+!$omp critical
+!$omp end critical
+  f9 = 1
+end

	Jakub

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-06-30 17:47 [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704) Jakub Jelinek
@ 2016-07-08 16:13 ` Cesar Philippidis
  2016-07-08 16:18   ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Cesar Philippidis @ 2016-07-08 16:13 UTC (permalink / raw)
  To: Jakub Jelinek, gcc-patches, fortran

On 06/30/2016 10:47 AM, Jakub Jelinek wrote:

> The Fortran parser apparently relies in functions that have still undecided
> kind of the result that ST_GET_FCN_CHARACTERISTICS artificial statement is
> returned before any executable statements in the function.
> In normal statements that is ensured through decode_statement calling
> decode_specification_statement, which parses just a subset of statements,
> but for OpenMP we need to do something similar.  If we figure out we want
> only the case_omp_decl statements, for any other we just try to gfc_match
> the keyword and if we match it, it means we'd be about to return an OpenMP
> executable statement, so instead return ST_GET_FCN_CHARACTERISTICS.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
> queued for 6.2 backport.
> 
> Cesar, note OpenACC will need something similar (though,
> decode_acc_statement uses just the match macro, so you'll need another one
> for the executable statements).

Here's the OpenACC followup for this patch. Is it OK for trunk and gcc6?

Cesar

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 16:13 ` Cesar Philippidis
@ 2016-07-08 16:18   ` Jakub Jelinek
  2016-07-08 16:19     ` Cesar Philippidis
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2016-07-08 16:18 UTC (permalink / raw)
  To: Cesar Philippidis; +Cc: gcc-patches, fortran

On Fri, Jul 08, 2016 at 09:13:50AM -0700, Cesar Philippidis wrote:
> On 06/30/2016 10:47 AM, Jakub Jelinek wrote:
> 
> > The Fortran parser apparently relies in functions that have still undecided
> > kind of the result that ST_GET_FCN_CHARACTERISTICS artificial statement is
> > returned before any executable statements in the function.
> > In normal statements that is ensured through decode_statement calling
> > decode_specification_statement, which parses just a subset of statements,
> > but for OpenMP we need to do something similar.  If we figure out we want
> > only the case_omp_decl statements, for any other we just try to gfc_match
> > the keyword and if we match it, it means we'd be about to return an OpenMP
> > executable statement, so instead return ST_GET_FCN_CHARACTERISTICS.
> > 
> > Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
> > queued for 6.2 backport.
> > 
> > Cesar, note OpenACC will need something similar (though,
> > decode_acc_statement uses just the match macro, so you'll need another one
> > for the executable statements).
> 
> Here's the OpenACC followup for this patch. Is it OK for trunk and gcc6?

ENOPATCH

	Jakub

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 16:18   ` Jakub Jelinek
@ 2016-07-08 16:19     ` Cesar Philippidis
  2016-07-08 16:31       ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Cesar Philippidis @ 2016-07-08 16:19 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran

[-- Attachment #1: Type: text/plain, Size: 1247 bytes --]

On 07/08/2016 09:18 AM, Jakub Jelinek wrote:
> On Fri, Jul 08, 2016 at 09:13:50AM -0700, Cesar Philippidis wrote:
>> On 06/30/2016 10:47 AM, Jakub Jelinek wrote:
>>
>>> The Fortran parser apparently relies in functions that have still undecided
>>> kind of the result that ST_GET_FCN_CHARACTERISTICS artificial statement is
>>> returned before any executable statements in the function.
>>> In normal statements that is ensured through decode_statement calling
>>> decode_specification_statement, which parses just a subset of statements,
>>> but for OpenMP we need to do something similar.  If we figure out we want
>>> only the case_omp_decl statements, for any other we just try to gfc_match
>>> the keyword and if we match it, it means we'd be about to return an OpenMP
>>> executable statement, so instead return ST_GET_FCN_CHARACTERISTICS.
>>>
>>> Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
>>> queued for 6.2 backport.
>>>
>>> Cesar, note OpenACC will need something similar (though,
>>> decode_acc_statement uses just the match macro, so you'll need another one
>>> for the executable statements).
>>
>> Here's the OpenACC followup for this patch. Is it OK for trunk and gcc6?
> 
> ENOPATCH

Sorry!

Cesar


[-- Attachment #2: fortran-oacc-directives.diff --]
[-- Type: text/x-patch, Size: 4978 bytes --]

2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* parse.c (matcha): Define.
	(decode_oacc_directive): Add spec_only local var and set it.  Use
	matcha to parse acc data, enter data, exit data, host_data, parallel,
	kernels, update and wait directives.  Return ST_GET_FCN_CHARACTERISTICS
	if a non-declarative directive could be matched.

	gcc/testsuite/
	* gfortran.dg/goacc/pr71704-acc.f90: New test.


diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index d795225..b1d9c00 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -589,11 +589,25 @@ decode_statement (void)
   return ST_NONE;
 }
 
+/* Like match, but don't match anything if not -fopenacc
+   and if spec_only, goto do_spec_only without actually matching.  */
+#define matcha(keyword, subr, st)				\
+    do {							\
+      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
+	goto do_spec_only;					\
+      else if (match_word (keyword, subr, &old_locus)		\
+	       == MATCH_YES)					\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
 static gfc_statement
 decode_oacc_directive (void)
 {
   locus old_locus;
   char c;
+  bool spec_only = false;
 
   gfc_enforce_clean_symbol_state ();
 
@@ -608,6 +622,10 @@ decode_oacc_directive (void)
       return ST_NONE;
     }
 
+  if (gfc_current_state () == COMP_FUNCTION
+      && gfc_current_block ()->result->ts.kind == -1)
+    spec_only = true;
+
   gfc_unset_implicit_pure (NULL);
 
   old_locus = gfc_current_locus;
@@ -627,7 +645,7 @@ decode_oacc_directive (void)
       match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
       break;
     case 'd':
-      match ("data", gfc_match_oacc_data, ST_OACC_DATA);
+      matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
       match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
       break;
     case 'e':
@@ -639,19 +657,19 @@ decode_oacc_directive (void)
       match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
       match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
       match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
-      match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
-      match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
+      matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
+      matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
       break;
     case 'h':
-      match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
+      matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
       break;
     case 'p':
       match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
-      match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
+      matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
       break;
     case 'k':
       match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
-      match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
+      matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
       break;
     case 'l':
       match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
@@ -660,10 +678,10 @@ decode_oacc_directive (void)
       match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
       break;
     case 'u':
-      match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
+      matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
       break;
     case 'w':
-      match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
+      matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
       break;
     }
 
@@ -678,6 +696,13 @@ decode_oacc_directive (void)
   gfc_error_recovery ();
 
   return ST_NONE;
+
+ do_spec_only:
+  reject_statement ();
+  gfc_clear_error ();
+  gfc_buffer_error (false);
+  gfc_current_locus = old_locus;
+  return ST_GET_FCN_CHARACTERISTICS;
 }
 
 /* Like match, but set a flag simd_matched if keyword matched
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr71704-acc.f90 b/gcc/testsuite/gfortran.dg/goacc/pr71704-acc.f90
new file mode 100644
index 0000000..0235e85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr71704-acc.f90
@@ -0,0 +1,60 @@
+! PR fortran/71704
+! { dg-do compile }
+
+real function f1 ()
+!$acc routine (f1)
+  f1 = 1
+end
+
+real function f2 (a)
+  integer a
+  !$acc enter data copyin(a)
+  f2 = 1
+end
+
+real function f3 (a)
+  integer a
+!$acc enter data copyin(a)
+  f3 = 1
+end
+
+real function f4 ()
+!$acc wait
+  f4 = 1
+end
+
+real function f5 (a)
+  integer a
+!$acc update device(a)
+  f5 = 1
+end
+
+real function f6 ()
+!$acc parallel
+!$acc end parallel
+  f6 = 1
+end
+
+real function f7 ()
+!$acc kernels
+!$acc end kernels
+  f7 = 1
+end
+
+real function f8 ()
+!$acc data
+!$acc end data
+  f8 = 1
+end
+
+real function f9 ()
+!$acc host_data
+!$acc end host_data
+  f8 = 1
+end
+
+real function f10 (a)
+  integer a
+!$acc declare present (a)
+  f8 = 1
+end

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 16:19     ` Cesar Philippidis
@ 2016-07-08 16:31       ` Jakub Jelinek
  2016-07-08 16:59         ` Cesar Philippidis
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2016-07-08 16:31 UTC (permalink / raw)
  To: Cesar Philippidis; +Cc: gcc-patches, fortran

On Fri, Jul 08, 2016 at 09:19:01AM -0700, Cesar Philippidis wrote:
> 2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>
> 
> 	gcc/fortran/
> 	* parse.c (matcha): Define.
> 	(decode_oacc_directive): Add spec_only local var and set it.  Use
> 	matcha to parse acc data, enter data, exit data, host_data, parallel,
> 	kernels, update and wait directives.  Return ST_GET_FCN_CHARACTERISTICS
> 	if a non-declarative directive could be matched.
> 
> 	gcc/testsuite/
> 	* gfortran.dg/goacc/pr71704-acc.f90: New test.

I'd drop the -acc suffix, the directory is enough to differentiate the gomp
vs. goacc test.

> --- a/gcc/fortran/parse.c
> +++ b/gcc/fortran/parse.c
> @@ -589,11 +589,25 @@ decode_statement (void)
>    return ST_NONE;
>  }
>  
> +/* Like match, but don't match anything if not -fopenacc
> +   and if spec_only, goto do_spec_only without actually matching.  */

The comment doesn't match what the macro does.  The whole
decode_oacc_directive function is only called if -fopenacc, so
it is really "Like a match and if spec_only, ..."

> +#define matcha(keyword, subr, st)				\
> +    do {							\
> +      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
> +	goto do_spec_only;					\
> +      else if (match_word (keyword, subr, &old_locus)		\
> +	       == MATCH_YES)					\
> +	return st;						\
> +      else							\
> +	undo_new_statement ();				  	\
> +    } while (0);
> +
>  static gfc_statement
>  decode_oacc_directive (void)
>  {
>    locus old_locus;
>    char c;
> +  bool spec_only = false;
>  
>    gfc_enforce_clean_symbol_state ();
>  
> @@ -608,6 +622,10 @@ decode_oacc_directive (void)
>        return ST_NONE;
>      }
>  
> +  if (gfc_current_state () == COMP_FUNCTION
> +      && gfc_current_block ()->result->ts.kind == -1)
> +    spec_only = true;
> +
>    gfc_unset_implicit_pure (NULL);
>  
>    old_locus = gfc_current_locus;
> @@ -627,7 +645,7 @@ decode_oacc_directive (void)
>        match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);

Why isn't ST_OACC_ATOMIC matcha?
At least from the case_executable/case_exec_markers vs.
case_decl defines, all directives but "routine" and "declare" should
be matcha IMHO.

Also, can you figure out in the OpenACC standard and/or discuss on lang
committee whether acc declare and/or acc routine can appear anywhere in the
specification part, or need to be ordered certain way?
If like in OpenMP they can appear anywhere, then
case ST_OACC_ROUTINE: case ST_OACC_DECLARE
should move from case_decl to case_omp_decl macro.

>        break;
>      case 'd':
> -      match ("data", gfc_match_oacc_data, ST_OACC_DATA);
> +      matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
>        match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
>        break;
>      case 'e':
> @@ -639,19 +657,19 @@ decode_oacc_directive (void)
>        match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
>        match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
>        match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
> -      match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
> -      match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
> +      matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
> +      matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
>        break;
>      case 'h':
> -      match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
> +      matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
>        break;
>      case 'p':
>        match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
> -      match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
> +      matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
>        break;
>      case 'k':
>        match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
> -      match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
> +      matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
>        break;
>      case 'l':
>        match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
> @@ -660,10 +678,10 @@ decode_oacc_directive (void)
>        match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
>        break;
>      case 'u':
> -      match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
> +      matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
>        break;
>      case 'w':
> -      match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
> +      matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
>        break;
>      }
>  
> @@ -678,6 +696,13 @@ decode_oacc_directive (void)
>    gfc_error_recovery ();
>  
>    return ST_NONE;
> +
> + do_spec_only:
> +  reject_statement ();
> +  gfc_clear_error ();
> +  gfc_buffer_error (false);
> +  gfc_current_locus = old_locus;
> +  return ST_GET_FCN_CHARACTERISTICS;
>  }
>  
>  /* Like match, but set a flag simd_matched if keyword matched

	Jakub

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 16:31       ` Jakub Jelinek
@ 2016-07-08 16:59         ` Cesar Philippidis
  2016-07-08 17:25           ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Cesar Philippidis @ 2016-07-08 16:59 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran

[-- Attachment #1: Type: text/plain, Size: 3095 bytes --]

On 07/08/2016 09:31 AM, Jakub Jelinek wrote:
> On Fri, Jul 08, 2016 at 09:19:01AM -0700, Cesar Philippidis wrote:
>> 2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>
>>
>> 	gcc/fortran/
>> 	* parse.c (matcha): Define.
>> 	(decode_oacc_directive): Add spec_only local var and set it.  Use
>> 	matcha to parse acc data, enter data, exit data, host_data, parallel,
>> 	kernels, update and wait directives.  Return ST_GET_FCN_CHARACTERISTICS
>> 	if a non-declarative directive could be matched.
>>
>> 	gcc/testsuite/
>> 	* gfortran.dg/goacc/pr71704-acc.f90: New test.
> 
> I'd drop the -acc suffix, the directory is enough to differentiate the gomp
> vs. goacc test.

Done.

>> --- a/gcc/fortran/parse.c
>> +++ b/gcc/fortran/parse.c
>> @@ -589,11 +589,25 @@ decode_statement (void)
>>    return ST_NONE;
>>  }
>>  
>> +/* Like match, but don't match anything if not -fopenacc
>> +   and if spec_only, goto do_spec_only without actually matching.  */
> 
> The comment doesn't match what the macro does.  The whole
> decode_oacc_directive function is only called if -fopenacc, so
> it is really "Like a match and if spec_only, ..."

The intent behind that comment was to note it shouldn't be used with the
OpenMP clauses. But I agree that the -fopenacc stuff isn't necessary.
This patch updates the comment.

>> +#define matcha(keyword, subr, st)				\
>> +    do {							\
>> +      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
>> +	goto do_spec_only;					\
>> +      else if (match_word (keyword, subr, &old_locus)		\
>> +	       == MATCH_YES)					\
>> +	return st;						\
>> +      else							\
>> +	undo_new_statement ();				  	\
>> +    } while (0);
>> +
>>  static gfc_statement
>>  decode_oacc_directive (void)
>>  {
>>    locus old_locus;
>>    char c;
>> +  bool spec_only = false;
>>  
>>    gfc_enforce_clean_symbol_state ();
>>  
>> @@ -608,6 +622,10 @@ decode_oacc_directive (void)
>>        return ST_NONE;
>>      }
>>  
>> +  if (gfc_current_state () == COMP_FUNCTION
>> +      && gfc_current_block ()->result->ts.kind == -1)
>> +    spec_only = true;
>> +
>>    gfc_unset_implicit_pure (NULL);
>>  
>>    old_locus = gfc_current_locus;
>> @@ -627,7 +645,7 @@ decode_oacc_directive (void)
>>        match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
> 
> Why isn't ST_OACC_ATOMIC matcha?
> At least from the case_executable/case_exec_markers vs.
> case_decl defines, all directives but "routine" and "declare" should
> be matcha IMHO.

Because the atomic directive must operate on a sequence of instructions,
otherwise it should generate a syntax error.

> Also, can you figure out in the OpenACC standard and/or discuss on lang
> committee whether acc declare and/or acc routine can appear anywhere in the
> specification part, or need to be ordered certain way?
> If like in OpenMP they can appear anywhere, then
> case ST_OACC_ROUTINE: case ST_OACC_DECLARE
> should move from case_decl to case_omp_decl macro.

OK, I'll check with them. Can that be a follow up patch, or would you
like to see it resolved in one patch?

Is this patch OK for trunk and gcc6?

Cesar


[-- Attachment #2: fortran-oacc-directives-a.diff --]
[-- Type: text/x-patch, Size: 4918 bytes --]

2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* parse.c (matcha): Define.
	(decode_oacc_directive): Add spec_only local var and set it.  Use
	matcha to parse acc data, enter data, exit data, host_data, parallel,
	kernels, update and wait directives.  Return ST_GET_FCN_CHARACTERISTICS
	if a non-declarative directive could be matched.

	gcc/testsuite/
	* gfortran.dg/goacc/pr71704.f90: New test.

diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index d795225..39fdd90 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -589,11 +589,25 @@ decode_statement (void)
   return ST_NONE;
 }
 
+/* Like match and if spec_only, goto do_spec_only without actually
+   matching.  */
+#define matcha(keyword, subr, st)				\
+    do {							\
+      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
+	goto do_spec_only;					\
+      else if (match_word (keyword, subr, &old_locus)		\
+	       == MATCH_YES)					\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
 static gfc_statement
 decode_oacc_directive (void)
 {
   locus old_locus;
   char c;
+  bool spec_only = false;
 
   gfc_enforce_clean_symbol_state ();
 
@@ -608,6 +622,10 @@ decode_oacc_directive (void)
       return ST_NONE;
     }
 
+  if (gfc_current_state () == COMP_FUNCTION
+      && gfc_current_block ()->result->ts.kind == -1)
+    spec_only = true;
+
   gfc_unset_implicit_pure (NULL);
 
   old_locus = gfc_current_locus;
@@ -627,7 +645,7 @@ decode_oacc_directive (void)
       match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
       break;
     case 'd':
-      match ("data", gfc_match_oacc_data, ST_OACC_DATA);
+      matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
       match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
       break;
     case 'e':
@@ -639,19 +657,19 @@ decode_oacc_directive (void)
       match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
       match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
       match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
-      match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
-      match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
+      matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
+      matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
       break;
     case 'h':
-      match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
+      matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
       break;
     case 'p':
       match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
-      match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
+      matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
       break;
     case 'k':
       match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
-      match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
+      matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
       break;
     case 'l':
       match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
@@ -660,10 +678,10 @@ decode_oacc_directive (void)
       match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
       break;
     case 'u':
-      match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
+      matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
       break;
     case 'w':
-      match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
+      matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
       break;
     }
 
@@ -678,6 +696,13 @@ decode_oacc_directive (void)
   gfc_error_recovery ();
 
   return ST_NONE;
+
+ do_spec_only:
+  reject_statement ();
+  gfc_clear_error ();
+  gfc_buffer_error (false);
+  gfc_current_locus = old_locus;
+  return ST_GET_FCN_CHARACTERISTICS;
 }
 
 /* Like match, but set a flag simd_matched if keyword matched
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr71704.f90 b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
new file mode 100644
index 0000000..0235e85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
@@ -0,0 +1,60 @@
+! PR fortran/71704
+! { dg-do compile }
+
+real function f1 ()
+!$acc routine (f1)
+  f1 = 1
+end
+
+real function f2 (a)
+  integer a
+  !$acc enter data copyin(a)
+  f2 = 1
+end
+
+real function f3 (a)
+  integer a
+!$acc enter data copyin(a)
+  f3 = 1
+end
+
+real function f4 ()
+!$acc wait
+  f4 = 1
+end
+
+real function f5 (a)
+  integer a
+!$acc update device(a)
+  f5 = 1
+end
+
+real function f6 ()
+!$acc parallel
+!$acc end parallel
+  f6 = 1
+end
+
+real function f7 ()
+!$acc kernels
+!$acc end kernels
+  f7 = 1
+end
+
+real function f8 ()
+!$acc data
+!$acc end data
+  f8 = 1
+end
+
+real function f9 ()
+!$acc host_data
+!$acc end host_data
+  f8 = 1
+end
+
+real function f10 (a)
+  integer a
+!$acc declare present (a)
+  f8 = 1
+end

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 16:59         ` Cesar Philippidis
@ 2016-07-08 17:25           ` Jakub Jelinek
  2016-07-08 18:26             ` Cesar Philippidis
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2016-07-08 17:25 UTC (permalink / raw)
  To: Cesar Philippidis; +Cc: gcc-patches, fortran

On Fri, Jul 08, 2016 at 09:58:57AM -0700, Cesar Philippidis wrote:
> >> +#define matcha(keyword, subr, st)				\
> >> +    do {							\
> >> +      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
> >> +	goto do_spec_only;					\
> >> +      else if (match_word (keyword, subr, &old_locus)		\
> >> +	       == MATCH_YES)					\
> >> +	return st;						\
> >> +      else							\
> >> +	undo_new_statement ();				  	\
> >> +    } while (0);
> >> +
> >>  static gfc_statement
> >>  decode_oacc_directive (void)
> >>  {
> >>    locus old_locus;
> >>    char c;
> >> +  bool spec_only = false;
> >>  
> >>    gfc_enforce_clean_symbol_state ();
> >>  
> >> @@ -608,6 +622,10 @@ decode_oacc_directive (void)
> >>        return ST_NONE;
> >>      }
> >>  
> >> +  if (gfc_current_state () == COMP_FUNCTION
> >> +      && gfc_current_block ()->result->ts.kind == -1)
> >> +    spec_only = true;
> >> +
> >>    gfc_unset_implicit_pure (NULL);
> >>  
> >>    old_locus = gfc_current_locus;
> >> @@ -627,7 +645,7 @@ decode_oacc_directive (void)
> >>        match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
> > 
> > Why isn't ST_OACC_ATOMIC matcha?
> > At least from the case_executable/case_exec_markers vs.
> > case_decl defines, all directives but "routine" and "declare" should
> > be matcha IMHO.
> 
> Because the atomic directive must operate on a sequence of instructions,
> otherwise it should generate a syntax error.

But you are then relying on a nested decode_statement to do something, it
works, but IMHO just rejecting them earlier is much cleaner and more
maintainable, with the simple rule that even can be documented that
declaration directives use match, all others use matcha (similarly how in
decode_omp_directive directives use the matchd[os] while executable directives
use match[os]).
What do you see as advantage of only marking some of the executable
directives?

> > Also, can you figure out in the OpenACC standard and/or discuss on lang
> > committee whether acc declare and/or acc routine can appear anywhere in the
> > specification part, or need to be ordered certain way?
> > If like in OpenMP they can appear anywhere, then
> > case ST_OACC_ROUTINE: case ST_OACC_DECLARE
> > should move from case_decl to case_omp_decl macro.
> 
> OK, I'll check with them. Can that be a follow up patch, or would you
> like to see it resolved in one patch?

Sure, that can be done incrementally.

	Jakub

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 17:25           ` Jakub Jelinek
@ 2016-07-08 18:26             ` Cesar Philippidis
  2016-07-08 18:31               ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Cesar Philippidis @ 2016-07-08 18:26 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches, fortran

[-- Attachment #1: Type: text/plain, Size: 2209 bytes --]

On 07/08/2016 10:25 AM, Jakub Jelinek wrote:
> On Fri, Jul 08, 2016 at 09:58:57AM -0700, Cesar Philippidis wrote:
>>>> +#define matcha(keyword, subr, st)				\
>>>> +    do {							\
>>>> +      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
>>>> +	goto do_spec_only;					\
>>>> +      else if (match_word (keyword, subr, &old_locus)		\
>>>> +	       == MATCH_YES)					\
>>>> +	return st;						\
>>>> +      else							\
>>>> +	undo_new_statement ();				  	\
>>>> +    } while (0);
>>>> +
>>>>  static gfc_statement
>>>>  decode_oacc_directive (void)
>>>>  {
>>>>    locus old_locus;
>>>>    char c;
>>>> +  bool spec_only = false;
>>>>  
>>>>    gfc_enforce_clean_symbol_state ();
>>>>  
>>>> @@ -608,6 +622,10 @@ decode_oacc_directive (void)
>>>>        return ST_NONE;
>>>>      }
>>>>  
>>>> +  if (gfc_current_state () == COMP_FUNCTION
>>>> +      && gfc_current_block ()->result->ts.kind == -1)
>>>> +    spec_only = true;
>>>> +
>>>>    gfc_unset_implicit_pure (NULL);
>>>>  
>>>>    old_locus = gfc_current_locus;
>>>> @@ -627,7 +645,7 @@ decode_oacc_directive (void)
>>>>        match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
>>>
>>> Why isn't ST_OACC_ATOMIC matcha?
>>> At least from the case_executable/case_exec_markers vs.
>>> case_decl defines, all directives but "routine" and "declare" should
>>> be matcha IMHO.
>>
>> Because the atomic directive must operate on a sequence of instructions,
>> otherwise it should generate a syntax error.
> 
> But you are then relying on a nested decode_statement to do something, it
> works, but IMHO just rejecting them earlier is much cleaner and more
> maintainable, with the simple rule that even can be documented that
> declaration directives use match, all others use matcha (similarly how in
> decode_omp_directive directives use the matchd[os] while executable directives
> use match[os]).
> What do you see as advantage of only marking some of the executable
> directives?

There's probably no advantage. I just didn't want to change something
that wasn't broken. But from a consistency standpoint, I agree that all
of the directives except for routine and declare could use matcha. This
patch makes that change.

Is this OK?

Cesar



[-- Attachment #2: fortran-oacc-directives-b.diff --]
[-- Type: text/x-patch, Size: 6249 bytes --]

2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* parse.c (matcha): Define.
	(decode_oacc_directive): Add spec_only local var and set it.  Use
	matcha to parse acc directives except for routine and declare.  Return
	ST_GET_FCN_CHARACTERISTICS if a non-declarative directive could be
	matched.

	gcc/testsuite/
	* gfortran.dg/goacc/pr71704.f90: New test.

diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index d795225..0aa736c 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -589,11 +589,25 @@ decode_statement (void)
   return ST_NONE;
 }
 
+/* Like match and if spec_only, goto do_spec_only without actually
+   matching.  */
+#define matcha(keyword, subr, st)				\
+    do {							\
+      if (spec_only && gfc_match (keyword) == MATCH_YES)	\
+	goto do_spec_only;					\
+      else if (match_word (keyword, subr, &old_locus)		\
+	       == MATCH_YES)					\
+	return st;						\
+      else							\
+	undo_new_statement ();				  	\
+    } while (0);
+
 static gfc_statement
 decode_oacc_directive (void)
 {
   locus old_locus;
   char c;
+  bool spec_only = false;
 
   gfc_enforce_clean_symbol_state ();
 
@@ -608,6 +622,10 @@ decode_oacc_directive (void)
       return ST_NONE;
     }
 
+  if (gfc_current_state () == COMP_FUNCTION
+      && gfc_current_block ()->result->ts.kind == -1)
+    spec_only = true;
+
   gfc_unset_implicit_pure (NULL);
 
   old_locus = gfc_current_locus;
@@ -621,49 +639,52 @@ decode_oacc_directive (void)
   switch (c)
     {
     case 'a':
-      match ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
+      matcha ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
       break;
     case 'c':
-      match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
+      matcha ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
       break;
     case 'd':
-      match ("data", gfc_match_oacc_data, ST_OACC_DATA);
+      matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
       match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
       break;
     case 'e':
-      match ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
-      match ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
-      match ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
-      match ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
-      match ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
-      match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
-      match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
-      match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
-      match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
-      match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
+      matcha ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
+      matcha ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
+      matcha ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
+      matcha ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
+      matcha ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
+      matcha ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
+      matcha ("end parallel loop", gfc_match_omp_eos,
+	      ST_OACC_END_PARALLEL_LOOP);
+      matcha ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
+      matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
+      matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
       break;
     case 'h':
-      match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
+      matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
       break;
     case 'p':
-      match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
-      match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
+      matcha ("parallel loop", gfc_match_oacc_parallel_loop,
+	      ST_OACC_PARALLEL_LOOP);
+      matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
       break;
     case 'k':
-      match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
-      match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
+      matcha ("kernels loop", gfc_match_oacc_kernels_loop,
+	      ST_OACC_KERNELS_LOOP);
+      matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
       break;
     case 'l':
-      match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
+      matcha ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
       break;
     case 'r':
       match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
       break;
     case 'u':
-      match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
+      matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
       break;
     case 'w':
-      match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
+      matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
       break;
     }
 
@@ -678,6 +699,13 @@ decode_oacc_directive (void)
   gfc_error_recovery ();
 
   return ST_NONE;
+
+ do_spec_only:
+  reject_statement ();
+  gfc_clear_error ();
+  gfc_buffer_error (false);
+  gfc_current_locus = old_locus;
+  return ST_GET_FCN_CHARACTERISTICS;
 }
 
 /* Like match, but set a flag simd_matched if keyword matched
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr71704.f90 b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
new file mode 100644
index 0000000..0235e85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
@@ -0,0 +1,60 @@
+! PR fortran/71704
+! { dg-do compile }
+
+real function f1 ()
+!$acc routine (f1)
+  f1 = 1
+end
+
+real function f2 (a)
+  integer a
+  !$acc enter data copyin(a)
+  f2 = 1
+end
+
+real function f3 (a)
+  integer a
+!$acc enter data copyin(a)
+  f3 = 1
+end
+
+real function f4 ()
+!$acc wait
+  f4 = 1
+end
+
+real function f5 (a)
+  integer a
+!$acc update device(a)
+  f5 = 1
+end
+
+real function f6 ()
+!$acc parallel
+!$acc end parallel
+  f6 = 1
+end
+
+real function f7 ()
+!$acc kernels
+!$acc end kernels
+  f7 = 1
+end
+
+real function f8 ()
+!$acc data
+!$acc end data
+  f8 = 1
+end
+
+real function f9 ()
+!$acc host_data
+!$acc end host_data
+  f8 = 1
+end
+
+real function f10 (a)
+  integer a
+!$acc declare present (a)
+  f8 = 1
+end

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

* Re: [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704)
  2016-07-08 18:26             ` Cesar Philippidis
@ 2016-07-08 18:31               ` Jakub Jelinek
  0 siblings, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2016-07-08 18:31 UTC (permalink / raw)
  To: Cesar Philippidis; +Cc: gcc-patches, fortran

On Fri, Jul 08, 2016 at 11:26:12AM -0700, Cesar Philippidis wrote:
> There's probably no advantage. I just didn't want to change something
> that wasn't broken. But from a consistency standpoint, I agree that all
> of the directives except for routine and declare could use matcha. This
> patch makes that change.
> 
> Is this OK?

Ok for trunk/6.2/5.5, thanks.

> 2016-07-08  Cesar Philippidis  <cesar@codesourcery.com>
> 
> 	gcc/fortran/
> 	* parse.c (matcha): Define.
> 	(decode_oacc_directive): Add spec_only local var and set it.  Use
> 	matcha to parse acc directives except for routine and declare.  Return
> 	ST_GET_FCN_CHARACTERISTICS if a non-declarative directive could be
> 	matched.
> 
> 	gcc/testsuite/
> 	* gfortran.dg/goacc/pr71704.f90: New test.

	Jakub

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

end of thread, other threads:[~2016-07-08 18:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-30 17:47 [committed] Fix OpenMP parsing of the specification part in functions (PR fortran/71704) Jakub Jelinek
2016-07-08 16:13 ` Cesar Philippidis
2016-07-08 16:18   ` Jakub Jelinek
2016-07-08 16:19     ` Cesar Philippidis
2016-07-08 16:31       ` Jakub Jelinek
2016-07-08 16:59         ` Cesar Philippidis
2016-07-08 17:25           ` Jakub Jelinek
2016-07-08 18:26             ` Cesar Philippidis
2016-07-08 18:31               ` Jakub Jelinek

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).