diff mbox

OpenACC fortran front end

Message ID 54655E88.2010502@codesourcery.com
State New
Headers show

Commit Message

Cesar Philippidis Nov. 14, 2014, 1:44 a.m. UTC
On 11/13/2014 08:43 AM, Jakub Jelinek wrote:

> On Thu, Nov 06, 2014 at 02:25:52PM -0800, Cesar Philippidis wrote:
>> 	* cpp.c (cpp_define_builtins): Conditionally define _OPENACC.
>> 	* dump-parse-tree.c
>> 	(show_omp_node): Dump also OpenACC executable statements.
> 
> Put (show_omp_node): ... and what fits on the same line as *
> dump-parse-tree.c, don't wrap prematurely.
> 
>> +#undef DEF_GOACC_BUILTIN_COMPILER
>> +      /* TODO: this is not doing the right thing.  */
> 
> Can you please avoid the TODOs in the source?  If it is not the right
> thing, either do something better, or file a PR to schedule such work for
> the future.
> 
>> +  struct gfc_expr *gang_expr;
>> +  struct gfc_expr *worker_expr;
>> +  struct gfc_expr *vector_expr;
>> +  struct gfc_expr *num_gangs_expr;
>> +  struct gfc_expr *num_workers_expr;
>> +  struct gfc_expr *vector_length_expr;
>> +  gfc_expr_list *wait_list;
>> +  gfc_expr_list *tile_list;
>> +  unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
>> +  unsigned wait:1, par_auto:1, gang_static:1;
>> +
>> +  /* Directive specific data.  */
>> +  union
>> +  {
>> +    /* !$ACC DECLARE locus.  */
>> +    locus loc;
>> +  }
>> +  ext;
> 
> Perhaps turn it into a union only when you have more than one field?
> And if we start to use unions, I bet we should do something with having
> such huge struct with most of the empty pointers anyway, add some hierarchy
> to those.
> 
>> --- a/gcc/fortran/match.c
>> +++ b/gcc/fortran/match.c
>> @@ -2491,7 +2491,7 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
>>  
>>    if (o != NULL)
>>      {
>> -      gfc_error ("%s statement at %C leaving OpenMP structured block",
>> +      gfc_error ("%s statement at %C leaving OpenMP or OpenACC structured block",
>>  		 gfc_ascii_statement (st));
>>        return MATCH_ERROR;
>>      }
> 
> I think it would be better to specify which (ie. compute
> is_oacc and have two different format strings, is_oacc ? " ... " : " ... ").
> 
>> -/* Match OpenMP directive clauses. MASK is a bitmask of
>> +/* OpenACC 2.0 clauses. */
>> +#define OMP_CLAUSE_ASYNC		(1ULL << 32)
> 
> As C++98 doesn't mandate long long type, I'm afraid we shouldn't use
> 1ULL; we require some 64-bit type though, so perhaps just use
> ((uint64_t) 1 << 32) etc.?
> 
>> +#define OMP_CLAUSE_NUM_GANGS		(1ULL << 33)
>> +#define OMP_CLAUSE_NUM_WORKERS		(1ULL << 34)
>> +#define OMP_CLAUSE_VECTOR_LENGTH	(1ULL << 35)
>> +#define OMP_CLAUSE_COPY			(1ULL << 36)
>> +#define OMP_CLAUSE_COPYOUT		(1ULL << 37)
>> +#define OMP_CLAUSE_CREATE		(1ULL << 38)
>> +#define OMP_CLAUSE_PRESENT		(1ULL << 39)
>> +#define OMP_CLAUSE_PRESENT_OR_COPY	(1ULL << 40)
>> +#define OMP_CLAUSE_PRESENT_OR_COPYIN	(1ULL << 41)
>> +#define OMP_CLAUSE_PRESENT_OR_COPYOUT	(1ULL << 42)
>> +#define OMP_CLAUSE_PRESENT_OR_CREATE	(1ULL << 43)
>> +#define OMP_CLAUSE_DEVICEPTR		(1ULL << 44)
>> +#define OMP_CLAUSE_GANG			(1ULL << 45)
>> +#define OMP_CLAUSE_WORKER		(1ULL << 46)
>> +#define OMP_CLAUSE_VECTOR		(1ULL << 47)
>> +#define OMP_CLAUSE_SEQ			(1ULL << 48)
>> +#define OMP_CLAUSE_INDEPENDENT		(1ULL << 49)
>> +#define OMP_CLAUSE_USE_DEVICE		(1ULL << 50)
>> +#define OMP_CLAUSE_DEVICE_RESIDENT	(1ULL << 51)
>> +#define OMP_CLAUSE_HOST_SELF		(1ULL << 52)
>> +#define OMP_CLAUSE_OACC_DEVICE		(1ULL << 53)
>> +#define OMP_CLAUSE_WAIT			(1ULL << 54)
>> +#define OMP_CLAUSE_DELETE		(1ULL << 55)
>> +#define OMP_CLAUSE_AUTO			(1ULL << 56)
>> +#define OMP_CLAUSE_TILE			(1ULL << 57)
> 
>>  static match
>> -gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned int mask,
>> -		       bool first = true, bool needs_space = true)
>> +gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask,
>> +		       bool first = true, bool needs_space = true,
> 
> See above, use uint64_t.
> 
>> +		c->async_expr = gfc_get_constant_expr (BT_INTEGER,
>> +						       gfc_default_integer_kind,
>> +						      &gfc_current_locus);
>> +		/* TODO XXX: FIX -1 (acc_async_noval).  */
> 
> Please use gomp-constants.h for this, or some other enum, and avoid
> TODO XXX comments in the source.

Thomas told me that he fix this when he updates gomp-constants.h.

>> +static gfc_statement
>> +omp_code_to_statement (gfc_code *code)
>> +{
>> +switch (code->op)
>> +  {
>> +  case EXEC_OMP_PARALLEL:
>> +    return ST_OMP_PARALLEL;
> 
> Wrong formatting.  switch should be indented by 2 spaces, { after it by 4,
> case by 4 too and return by 6 spaces.
> 
>> +  default:
>> +    gcc_unreachable ();
>> +  }
> ...
> 
>> +oacc_code_to_statement (gfc_code *code)
>> +{
>> +switch (code->op)
>> +  {
> 
> Likewise here.
> 
>> +static void
>> +resolve_oacc_loop(gfc_code *code)
> 
> Formatting - missing space before (, please check it everywhere.
> 
>> +static void
>> +resolve_oacc_cache (gfc_code *code)
>> +{
>> +  gfc_error ("Sorry, !$ACC cache unimplemented yet at %L", &code->loc);
> 
> Shouldn't this be sorry ("...") instead?

That introduced an ICE. I've created a PR for it here:

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

>> +}
>> +
>> +
>> +void
>> +gfc_resolve_oacc_declare (gfc_namespace *ns)
>> +{
>> +  int list;
>> +  gfc_omp_namelist *n;
>> +  locus loc;
>> +  static const char *clause_names[] = {"COPY", "COPYIN", "COPYOUT", "CREATE",
> 
> Missing space after { ?
> 
>> +	"DELETE", "PRESENT", "PRESENT_OR_COPY", "PRESENT_OR_COPYIN",
>> +	"PRESENT_OR_COPYOUT", "PRESENT_OR_CREATE", "DEVICEPTR",
>> +	"DEVICE_RESIDENT"};
> 
> and before }.
> 
>> +  /* FIXME: handle omp_list_map.  */
> 
> Please avoid fixmes, either fix it, or file a PR.

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

>> @@ -3568,9 +3813,13 @@ static void
>>  parse_critical_block (void)
>>  {
>>    gfc_code *top, *d;
>> -  gfc_state_data s;
>> +  gfc_state_data s, *sd;
>>    gfc_statement st;
>>  
>> +  for (sd = gfc_state_stack; sd; sd = sd->previous) 
>> +    if (sd->state == COMP_OMP_STRUCTURED_BLOCK)
>> +      gfc_error_now ("CRITICAL block inside of OpenMP or OpenACC region at %C");
> 
> Couldn't you determine which one and make the diagnostics explicit?
> 
>> --- a/gcc/fortran/scanner.c
>> +++ b/gcc/fortran/scanner.c
>> @@ -55,9 +55,11 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
>>  
>>  static gfc_file *file_head, *current_file;
>>  
>> -static int continue_flag, end_flag, openmp_flag, gcc_attribute_flag;
>> +static int continue_flag, end_flag, gcc_attribute_flag;
>> +static int openmp_flag, openacc_flag; /* If !$omp/!$acc occurred in current comment line */
> 
> Too long line.  Best put it above the two flags.
> End the comment with ".  */" (dot and one space missing).
> 
>> +	      gcc_assert(gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
> 
> Formatting, missing space before (.
> 
>>        /* See if this line is a continuation line.  */
>> -      if (openmp_flag != prev_openmp_flag)
>> -	{
>> -	  openmp_flag = prev_openmp_flag;
>> -	  goto not_continuation;
>> -	}
>> +      if (gfc_option.gfc_flag_openmp)
>> +	if (openmp_flag != prev_openmp_flag)
>> +	  {
>> +	    openmp_flag = prev_openmp_flag;
>> +	    goto not_continuation;
>> +	  }
>> +      if (gfc_option.gfc_flag_openacc)
>> +	if (openacc_flag != prev_openacc_flag)
>> +	  {
>> +	    openacc_flag = prev_openacc_flag;
>> +	    goto not_continuation;
>> +	  }
> 
> Why the guards by gfc_flag_open* ?  What happens
> if both -fopenmp -fopenacc is enabled?
> And, if it is right this way, the nested ifs are weird,
> use if (gfc_option.gfc_flag_openmp && openmp_flag != prev_openmp_flag)
> instead.

Using -fopenmp with -fopenacc is broken. See

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

>> +      if (clauses->async_expr)
>> +	OMP_CLAUSE_ASYNC_EXPR (c) =
>> +	    gfc_convert_expr_to_tree (block, clauses->async_expr);
> 
> = should be on the next line.
> 
>> +      tree num_gangs_var = 
>> +	  gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
> 
> Likewise and several times more.
> 
> LGTM otherwise.

Thanks. I couldn't figure out how to assign the bugs in the PR. Maybe my
account doesn't have permission to do so. Regardless, I'll work on them.

I've applied the attached patch to gomp-4_0-branch. It should address
all of your requests. I'll regenerate a complete patch later. Thomas
told me that he would merge the fortran FE along with the middle end
when the time comes.

This patch also includes a change to a gomp test. That change is
specific to gomp-4_0-branch, so if it looks out of place just ignore it.

Cesar

Comments

Jakub Jelinek Nov. 14, 2014, 6:52 a.m. UTC | #1
On Thu, Nov 13, 2014 at 05:44:40PM -0800, Cesar Philippidis wrote:
> Thanks. I couldn't figure out how to assign the bugs in the PR. Maybe my
> account doesn't have permission to do so. Regardless, I'll work on them.

Use your @gcc.gnu.org account instead, then you have far more permissions
in bugzilla.

> --- a/gcc/fortran/gfortran.h
> +++ b/gcc/fortran/gfortran.h
> @@ -1262,14 +1262,8 @@ typedef struct gfc_omp_clauses
>    gfc_expr_list *tile_list;
>    unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
>    unsigned wait:1, par_auto:1, gang_static:1;

The /* !$ACC DECLARE locus.  */ comment wouldn't hurt here.

> --- a/gcc/fortran/match.c
> +++ b/gcc/fortran/match.c
> @@ -2491,8 +2491,8 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
>  
>    if (o != NULL)
>      {
> -      gfc_error ("%s statement at %C leaving OpenMP or OpenACC structured block",
> -		 gfc_ascii_statement (st));
> +      gfc_error ("%s statement at %C leaving %s structured block",
> +		 gfc_ascii_statement (st), is_oacc (p) ? "OpenACC" : "OpenMP");

You want
	gfc_error (is_oacc (p)
		   ? "%s statement at %C leaving OpenACC structured block"
		   : "%s statement at %C leaving OpenMP structured block",
		   gfc_ascii_statement (st));
instead to be more translation friendly.

> @@ -5545,3 +5547,28 @@ duplicate_main:
>    gfc_done_2 ();
>    return true;
>  }
> +
> +/* Return true if this state data represents an OpenACC region.  */
> +bool
> +is_oacc (gfc_state_data *sd)
> +{
> +  switch (sd->construct->op)
> +    {
> +    case EXEC_OACC_PARALLEL_LOOP:break;
> +    case EXEC_OACC_PARALLEL:

What is that break; doing there?  Then you fall through into end of function
without return (and missing space before it).

> +    case EXEC_OACC_KERNELS_LOOP:
> +    case EXEC_OACC_KERNELS:
> +    case EXEC_OACC_DATA:
> +    case EXEC_OACC_HOST_DATA:
> +    case EXEC_OACC_LOOP:
> +    case EXEC_OACC_UPDATE:
> +    case EXEC_OACC_WAIT:
> +    case EXEC_OACC_CACHE:
> +    case EXEC_OACC_ENTER_DATA:
> +    case EXEC_OACC_EXIT_DATA:
> +      return true;
> +
> +    default:
> +      return false;
> +    }
> +}

	Jakub
Thomas Schwinge Nov. 14, 2014, 7:56 a.m. UTC | #2
Hi!

On Thu, 13 Nov 2014 17:44:40 -0800, Cesar Philippidis <cesar@codesourcery.com> wrote:
> On 11/13/2014 08:43 AM, Jakub Jelinek wrote:
> > Can you please avoid the TODOs in the source?  If it is not the right
> > thing, either do something better, or file a PR to schedule such work for
> > the future.

Should we use the existing openmp keyword for this,
<https://gcc.gnu.org/bugzilla/describekeywords.cgi>, or get a new openacc
keyword added?


> Using -fopenmp with -fopenacc is broken. See
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63858

Another issue: I noticed that when compiling fixed-form code such as
libgomp/testsuite/libgomp.oacc-fortran/data-already-2.f with both
-fopenacc -fopenmp, the data constructs "disappear" (see
-ftree-dump-original, for example).

We have a (tiny, addmittedly) little bit of testing for C/C++,
gcc/testsuite/*/*goacc-gomp, but should also to Fortran add a goacc-gomp
testsuite.


> 	gcc/fortran/
> 	* f95-lang.c (DEF_GOACC_BUILTIN_COMPILER): Remove bogus TODO.

> --- a/gcc/fortran/f95-lang.c
> +++ b/gcc/fortran/f95-lang.c
> @@ -1189,7 +1189,6 @@ gfc_init_builtin_functions (void)
>        gfc_define_builtin ("__builtin_" name, builtin_types[type], \
>  			  code, name, attr);
>  #undef DEF_GOACC_BUILTIN_COMPILER
> -      /* TODO: this is not doing the right thing.  */
>  #define DEF_GOACC_BUILTIN_COMPILER(code, name, type, attr) \
>        gfc_define_builtin (name, builtin_types[type], code, name, attr);
>  #include "../oacc-builtins.def"

(OK to not include the TODO marker in the trunk submission, but) I don't
think it's "bogus", but really doesn't work, as discussed before,
<http://news.gmane.org/find-root.php?message_id=%3C87k350n6zl.fsf%40schwinge.name%3E>.


> --- a/gcc/fortran/parse.c
> +++ b/gcc/fortran/parse.c
> @@ -3818,7 +3818,9 @@ parse_critical_block (void)
>  
>    for (sd = gfc_state_stack; sd; sd = sd->previous) 
>      if (sd->state == COMP_OMP_STRUCTURED_BLOCK)
> -      gfc_error_now ("CRITICAL block inside of OpenMP or OpenACC region at %C");
> +      gfc_error_now (is_oacc (sd)
> +		     ? "CRITICAL block inside of OpenACC region at %C"
> +		     : "CRITICAL block inside of OpenMP region at %C");

Can't use %s and »is_oacc () ? "OpenACC" : "OpenMP"« here, too?

> +/* Return true if this state data represents an OpenACC region.  */
> +bool
> +is_oacc (gfc_state_data *sd)
> +{
> +  switch (sd->construct->op)
> +    {
> +    case EXEC_OACC_PARALLEL_LOOP:break;

Misplaced break statement?  (Doesn't that result in a compiler warning,
"non-void function returns", or similar?)

> +    case EXEC_OACC_PARALLEL:
> +    case EXEC_OACC_KERNELS_LOOP:
> +    case EXEC_OACC_KERNELS:
> +    case EXEC_OACC_DATA:
> +    case EXEC_OACC_HOST_DATA:
> +    case EXEC_OACC_LOOP:
> +    case EXEC_OACC_UPDATE:
> +    case EXEC_OACC_WAIT:
> +    case EXEC_OACC_CACHE:
> +    case EXEC_OACC_ENTER_DATA:
> +    case EXEC_OACC_EXIT_DATA:
> +      return true;
> +
> +    default:
> +      return false;
> +    }
> +}


> --- a/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90
> +++ b/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90
> @@ -44,7 +44,7 @@ outer: do i = 1, 30
>    end do outer
>  last: do i = 1, 30
>  !$omp parallel
> -    if (i .eq. 21) exit last ! { dg-error "leaving OpenMP or OpenACC structured block" }
> +    if (i .eq. 21) exit last ! { dg-error "leaving OpenMP structured block" }
>  !$omp end parallel
>    end do last
>  !$omp parallel do shared (i)

Does that suggest that we have no corresponding testing for OpenACC?


A few more issues that I noted (but this is still not a comprehensive
code review).  Not knowing which of those you'd like to address right
now, I have not yet filed any PRs.


gcc/fortran/dump-parse-tree.c:show_omp_namelist only handles the OpenMP
gcc/fortran/gfortran.h:gfc_omp_map_op OMP_MAP_* but not those that we're
adding for the OpenACC interfaces.


Doesn't gcc/fortran/frontend-passes:gfc_code_walker need to be updated
for OpenACC?


I still think (as discussed before, at the end of
<http://news.gmane.org/find-root.php?message_id=%3C87a97yrjf7.fsf%40schwinge.name%3E>),
that the handling of the openacc flag in
gcc/fortran/openmp.c:resolve_omp_clauses with regard to »(list !=
OMP_LIST_MAP || openacc)«, and further down, resolve_oacc_data_clauses
and resolve_oacc_deviceptr_clause is strange.


What is the purpose of gcc/fortran/gfortran.h:OMP_LIST_FIRST?  In
gcc/fortran/gfortran.h, this is made an alias to OMP_LIST_PRIVATE, which
is then, by the OMP_LIST_FIRST name, used in
gcc/fortran/openmp.c:oacc_compatible_clauses.  Should the latter just use
the OMP_LIST_PRIVATE name, and OMP_LIST_FIRST be removed?


Grüße,
 Thomas
Jakub Jelinek Nov. 14, 2014, 8:33 a.m. UTC | #3
On Fri, Nov 14, 2014 at 08:56:53AM +0100, Thomas Schwinge wrote:
> Hi!
> 
> On Thu, 13 Nov 2014 17:44:40 -0800, Cesar Philippidis <cesar@codesourcery.com> wrote:
> > On 11/13/2014 08:43 AM, Jakub Jelinek wrote:
> > > Can you please avoid the TODOs in the source?  If it is not the right
> > > thing, either do something better, or file a PR to schedule such work for
> > > the future.
> 
> Should we use the existing openmp keyword for this,
> <https://gcc.gnu.org/bugzilla/describekeywords.cgi>, or get a new openacc
> keyword added?

Please add openacc.

	Jakub
Thomas Schwinge Nov. 14, 2014, 9:21 a.m. UTC | #4
Hi!

On Fri, 14 Nov 2014 09:33:13 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Nov 14, 2014 at 08:56:53AM +0100, Thomas Schwinge wrote:
> > On Thu, 13 Nov 2014 17:44:40 -0800, Cesar Philippidis <cesar@codesourcery.com> wrote:
> > > On 11/13/2014 08:43 AM, Jakub Jelinek wrote:
> > > > Can you please avoid the TODOs in the source?  If it is not the right
> > > > thing, either do something better, or file a PR to schedule such work for
> > > > the future.
> > 
> > Should we use the existing openmp keyword for this,
> > <https://gcc.gnu.org/bugzilla/describekeywords.cgi>, or get a new openacc
> > keyword added?
> 
> Please add openacc.

Turns out that I could do that myself --
<https://gcc.gnu.org/bugzilla/buglist.cgi?keywords=openacc> created.


Grüße,
 Thomas
Joseph Myers Nov. 14, 2014, 6:13 p.m. UTC | #5
On Fri, 14 Nov 2014, Jakub Jelinek wrote:

> You want
> 	gfc_error (is_oacc (p)
> 		   ? "%s statement at %C leaving OpenACC structured block"
> 		   : "%s statement at %C leaving OpenMP structured block",
> 		   gfc_ascii_statement (st));
> instead to be more translation friendly.

Does gettext now extract both halves of a conditional expression?  At 
least at one point it was necessary to use an if statement, or mark up 
both strings with G_() to get them extracted.
diff mbox

Patch

2014-11-13  Cesar Philippidis  <cesar@codesourcery.com>

	gcc/fortran/
	* f95-lang.c (DEF_GOACC_BUILTIN_COMPILER): Remove bogus TODO.
	* gfortran.h (gfc_omp_clauses): Move loc out of the ext union and
	remove the ext union.
	* match.c (match_exit_cycle): Make the error message specific to
	OpenMP/OpenACC.
	* openmp.c (OMP_CLAUSE_PRIVATE, OMP_CLAUSE_FIRSTPRIVATE,
	OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_COPYPRIVATE, OMP_CLAUSE_SHARED
	OMP_CLAUSE_COPYIN, OMP_CLAUSE_REDUCTION, OMP_CLAUSE_IF,
	OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_DEFAULT,
	OMP_CLAUSE_ORDERED, OMP_CLAUSE_COLLAPSE, OMP_CLAUSE_UNTIED,
	OMP_CLAUSE_FINAL, OMP_CLAUSE_MERGEABLE, OMP_CLAUSE_ALIGNED,
	OMP_CLAUSE_DEPEND, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_LINEAR,
	OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_SAFELEN,
	OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_DEVICE,
	OMP_CLAUSE_MAP, OMP_CLAUSE_TOOMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS,
	OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_DIST_SCHEDULE, OMP_CLAUSE_ASYNC,
	OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH,
	OMP_CLAUSE_COPY, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE,
	OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY,
	OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT,
	OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR,
	OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR,
	OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE,
	OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_HOST_SELF,
	OMP_CLAUSE_OACC_DEVICE, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE,
	OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): Use unit64_t for the bitmasks.
	(gfc_match_omp_clauses):  Use unit64_t for mask.
	(gfc_match_oacc_declare): Update usage of omp_clause->loc.
	(omp_code_to_statement): Fix whitespace.
	(oacc_code_to_statement): Likewise. 
	(resolve_oacc_loop):Likewise.
	(resolve_oacc_cache):  Replace gfc_error with a sorry for this
	unimplemented directive.
	(gfc_resolve_oacc_declare): Update usage of omp_clause->loc. Remove
	FIXME and TODO, see PR63869.
	* parse.c (parse_critical_block): Make the error message specific to
	OpenMP/OpenACC.
	(is_oacc): New function.
	* parse.h (is_oacc): Declare.
	* scanner.c (openmp_flag, openacc_flag): Move comment.
	(gfc_next_char_literal): Merge nested if stmts.
	* trans-openmp.c (gfc_trans_omp_clauses): Fix whitespace.
	(gfc_trans_oacc_declare): Fix whitespace.

	gcc/testsuite/
	* gfortran.dg/gomp/omp_do1.f90: Update expected error.


diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 4451c61..cd43112 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -1189,7 +1189,6 @@  gfc_init_builtin_functions (void)
       gfc_define_builtin ("__builtin_" name, builtin_types[type], \
 			  code, name, attr);
 #undef DEF_GOACC_BUILTIN_COMPILER
-      /* TODO: this is not doing the right thing.  */
 #define DEF_GOACC_BUILTIN_COMPILER(code, name, type, attr) \
       gfc_define_builtin (name, builtin_types[type], code, name, attr);
 #include "../oacc-builtins.def"
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index aed37d3..9624b3b 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1262,14 +1262,8 @@  typedef struct gfc_omp_clauses
   gfc_expr_list *tile_list;
   unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1;
   unsigned wait:1, par_auto:1, gang_static:1;
+  locus loc;
 
-  /* Directive specific data.  */
-  union
-  {
-    /* !$ACC DECLARE locus.  */
-    locus loc;
-  }
-  ext;
 }
 gfc_omp_clauses;
 
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index ba5f8ad..7d7982e 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2491,8 +2491,8 @@  match_exit_cycle (gfc_statement st, gfc_exec_op op)
 
   if (o != NULL)
     {
-      gfc_error ("%s statement at %C leaving OpenMP or OpenACC structured block",
-		 gfc_ascii_statement (st));
+      gfc_error ("%s statement at %C leaving %s structured block",
+		 gfc_ascii_statement (st), is_oacc (p) ? "OpenACC" : "OpenMP");
       return MATCH_ERROR;
     }
 
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 47c146e..15b221d 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -27,6 +27,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "match.h"
 #include "parse.h"
 #include "hash-set.h"
+#include "diagnostic.h"
 
 /* Match an end of OpenMP directive.  End of OpenMP directive is optional
    whitespace, followed by '\n' or comment '!'.  */
@@ -391,66 +392,66 @@  match_oacc_clause_gang (gfc_omp_clauses *cp)
   return gfc_match (" %e )", &cp->gang_expr);
 }
 
-#define OMP_CLAUSE_PRIVATE	(1U << 0)
-#define OMP_CLAUSE_FIRSTPRIVATE	(1U << 1)
-#define OMP_CLAUSE_LASTPRIVATE	(1U << 2)
-#define OMP_CLAUSE_COPYPRIVATE	(1U << 3)
-#define OMP_CLAUSE_SHARED	(1U << 4)
-#define OMP_CLAUSE_COPYIN	(1U << 5)
-#define OMP_CLAUSE_REDUCTION	(1U << 6)
-#define OMP_CLAUSE_IF		(1U << 7)
-#define OMP_CLAUSE_NUM_THREADS	(1U << 8)
-#define OMP_CLAUSE_SCHEDULE	(1U << 9)
-#define OMP_CLAUSE_DEFAULT	(1U << 10)
-#define OMP_CLAUSE_ORDERED	(1U << 11)
-#define OMP_CLAUSE_COLLAPSE	(1U << 12)
-#define OMP_CLAUSE_UNTIED	(1U << 13)
-#define OMP_CLAUSE_FINAL	(1U << 14)
-#define OMP_CLAUSE_MERGEABLE	(1U << 15)
-#define OMP_CLAUSE_ALIGNED	(1U << 16)
-#define OMP_CLAUSE_DEPEND	(1U << 17)
-#define OMP_CLAUSE_INBRANCH	(1U << 18)
-#define OMP_CLAUSE_LINEAR	(1U << 19)
-#define OMP_CLAUSE_NOTINBRANCH	(1U << 20)
-#define OMP_CLAUSE_PROC_BIND	(1U << 21)
-#define OMP_CLAUSE_SAFELEN	(1U << 22)
-#define OMP_CLAUSE_SIMDLEN	(1U << 23)
-#define OMP_CLAUSE_UNIFORM	(1U << 24)
-#define OMP_CLAUSE_DEVICE	(1U << 25)
-#define OMP_CLAUSE_MAP		(1U << 26)
-#define OMP_CLAUSE_TO		(1U << 27)
-#define OMP_CLAUSE_FROM		(1U << 28)
-#define OMP_CLAUSE_NUM_TEAMS	(1U << 29)
-#define OMP_CLAUSE_THREAD_LIMIT	(1U << 30)
-#define OMP_CLAUSE_DIST_SCHEDULE	(1U << 31)
+#define OMP_CLAUSE_PRIVATE		((uint64_t) 1 << 0)
+#define OMP_CLAUSE_FIRSTPRIVATE		((uint64_t) 1 << 1)
+#define OMP_CLAUSE_LASTPRIVATE		((uint64_t) 1 << 2)
+#define OMP_CLAUSE_COPYPRIVATE		((uint64_t) 1 << 3)
+#define OMP_CLAUSE_SHARED		((uint64_t) 1 << 4)
+#define OMP_CLAUSE_COPYIN		((uint64_t) 1 << 5)
+#define OMP_CLAUSE_REDUCTION		((uint64_t) 1 << 6)
+#define OMP_CLAUSE_IF			((uint64_t) 1 << 7)
+#define OMP_CLAUSE_NUM_THREADS		((uint64_t) 1 << 8)
+#define OMP_CLAUSE_SCHEDULE		((uint64_t) 1 << 9)
+#define OMP_CLAUSE_DEFAULT		((uint64_t) 1 << 10)
+#define OMP_CLAUSE_ORDERED		((uint64_t) 1 << 11)
+#define OMP_CLAUSE_COLLAPSE		((uint64_t) 1 << 12)
+#define OMP_CLAUSE_UNTIED		((uint64_t) 1 << 13)
+#define OMP_CLAUSE_FINAL		((uint64_t) 1 << 14)
+#define OMP_CLAUSE_MERGEABLE		((uint64_t) 1 << 15)
+#define OMP_CLAUSE_ALIGNED		((uint64_t) 1 << 16)
+#define OMP_CLAUSE_DEPEND		((uint64_t) 1 << 17)
+#define OMP_CLAUSE_INBRANCH		((uint64_t) 1 << 18)
+#define OMP_CLAUSE_LINEAR		((uint64_t) 1 << 19)
+#define OMP_CLAUSE_NOTINBRANCH		((uint64_t) 1 << 20)
+#define OMP_CLAUSE_PROC_BIND		((uint64_t) 1 << 21)
+#define OMP_CLAUSE_SAFELEN		((uint64_t) 1 << 22)
+#define OMP_CLAUSE_SIMDLEN		((uint64_t) 1 << 23)
+#define OMP_CLAUSE_UNIFORM		((uint64_t) 1 << 24)
+#define OMP_CLAUSE_DEVICE		((uint64_t) 1 << 25)
+#define OMP_CLAUSE_MAP			((uint64_t) 1 << 26)
+#define OMP_CLAUSE_TO			((uint64_t) 1 << 27)
+#define OMP_CLAUSE_FROM			((uint64_t) 1 << 28)
+#define OMP_CLAUSE_NUM_TEAMS		((uint64_t) 1 << 29)
+#define OMP_CLAUSE_THREAD_LIMIT		((uint64_t) 1 << 30)
+#define OMP_CLAUSE_DIST_SCHEDULE	((uint64_t) 1 << 31)
 
 /* OpenACC 2.0 clauses. */
-#define OMP_CLAUSE_ASYNC		(1ULL << 32)
-#define OMP_CLAUSE_NUM_GANGS		(1ULL << 33)
-#define OMP_CLAUSE_NUM_WORKERS		(1ULL << 34)
-#define OMP_CLAUSE_VECTOR_LENGTH	(1ULL << 35)
-#define OMP_CLAUSE_COPY			(1ULL << 36)
-#define OMP_CLAUSE_COPYOUT		(1ULL << 37)
-#define OMP_CLAUSE_CREATE		(1ULL << 38)
-#define OMP_CLAUSE_PRESENT		(1ULL << 39)
-#define OMP_CLAUSE_PRESENT_OR_COPY	(1ULL << 40)
-#define OMP_CLAUSE_PRESENT_OR_COPYIN	(1ULL << 41)
-#define OMP_CLAUSE_PRESENT_OR_COPYOUT	(1ULL << 42)
-#define OMP_CLAUSE_PRESENT_OR_CREATE	(1ULL << 43)
-#define OMP_CLAUSE_DEVICEPTR		(1ULL << 44)
-#define OMP_CLAUSE_GANG			(1ULL << 45)
-#define OMP_CLAUSE_WORKER		(1ULL << 46)
-#define OMP_CLAUSE_VECTOR		(1ULL << 47)
-#define OMP_CLAUSE_SEQ			(1ULL << 48)
-#define OMP_CLAUSE_INDEPENDENT		(1ULL << 49)
-#define OMP_CLAUSE_USE_DEVICE		(1ULL << 50)
-#define OMP_CLAUSE_DEVICE_RESIDENT	(1ULL << 51)
-#define OMP_CLAUSE_HOST_SELF		(1ULL << 52)
-#define OMP_CLAUSE_OACC_DEVICE		(1ULL << 53)
-#define OMP_CLAUSE_WAIT			(1ULL << 54)
-#define OMP_CLAUSE_DELETE		(1ULL << 55)
-#define OMP_CLAUSE_AUTO			(1ULL << 56)
-#define OMP_CLAUSE_TILE			(1ULL << 57)
+#define OMP_CLAUSE_ASYNC		((uint64_t) 1 << 32)
+#define OMP_CLAUSE_NUM_GANGS		((uint64_t) 1 << 33)
+#define OMP_CLAUSE_NUM_WORKERS		((uint64_t) 1 << 34)
+#define OMP_CLAUSE_VECTOR_LENGTH	((uint64_t) 1 << 35)
+#define OMP_CLAUSE_COPY			((uint64_t) 1 << 36)
+#define OMP_CLAUSE_COPYOUT		((uint64_t) 1 << 37)
+#define OMP_CLAUSE_CREATE		((uint64_t) 1 << 38)
+#define OMP_CLAUSE_PRESENT		((uint64_t) 1 << 39)
+#define OMP_CLAUSE_PRESENT_OR_COPY	((uint64_t) 1 << 40)
+#define OMP_CLAUSE_PRESENT_OR_COPYIN	((uint64_t) 1 << 41)
+#define OMP_CLAUSE_PRESENT_OR_COPYOUT	((uint64_t) 1 << 42)
+#define OMP_CLAUSE_PRESENT_OR_CREATE	((uint64_t) 1 << 43)
+#define OMP_CLAUSE_DEVICEPTR		((uint64_t) 1 << 44)
+#define OMP_CLAUSE_GANG			((uint64_t) 1 << 45)
+#define OMP_CLAUSE_WORKER		((uint64_t) 1 << 46)
+#define OMP_CLAUSE_VECTOR		((uint64_t) 1 << 47)
+#define OMP_CLAUSE_SEQ			((uint64_t) 1 << 48)
+#define OMP_CLAUSE_INDEPENDENT		((uint64_t) 1 << 49)
+#define OMP_CLAUSE_USE_DEVICE		((uint64_t) 1 << 50)
+#define OMP_CLAUSE_DEVICE_RESIDENT	((uint64_t) 1 << 51)
+#define OMP_CLAUSE_HOST_SELF		((uint64_t) 1 << 52)
+#define OMP_CLAUSE_OACC_DEVICE		((uint64_t) 1 << 53)
+#define OMP_CLAUSE_WAIT			((uint64_t) 1 << 54)
+#define OMP_CLAUSE_DELETE		((uint64_t) 1 << 55)
+#define OMP_CLAUSE_AUTO			((uint64_t) 1 << 56)
+#define OMP_CLAUSE_TILE			((uint64_t) 1 << 57)
 
 /* Helper function for OpenACC and OpenMP clauses involving memory
    mapping.  */
@@ -475,7 +476,7 @@  gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op)
    clauses that are allowed for a particular directive.  */
 
 static match
-gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask,
+gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask,
 		       bool first = true, bool needs_space = true,
 		       bool openacc = false)
 {
@@ -1294,7 +1295,7 @@  gfc_match_oacc_declare (void)
     return MATCH_ERROR;
 
   new_st.ext.omp_clauses = c;
-  new_st.ext.omp_clauses->ext.loc = gfc_current_locus;
+  new_st.ext.omp_clauses->loc = gfc_current_locus;
   return MATCH_YES;
 }
 
@@ -4267,57 +4268,57 @@  oacc_is_kernels (gfc_code *code)
 static gfc_statement
 omp_code_to_statement (gfc_code *code)
 {
-switch (code->op)
-  {
-  case EXEC_OMP_PARALLEL:
-    return ST_OMP_PARALLEL;
-  case EXEC_OMP_PARALLEL_SECTIONS:
-    return ST_OMP_PARALLEL_SECTIONS;
-  case EXEC_OMP_SECTIONS:
-    return ST_OMP_SECTIONS;
-  case EXEC_OMP_ORDERED:
-    return ST_OMP_ORDERED;
-  case EXEC_OMP_CRITICAL:
-    return ST_OMP_CRITICAL;
-  case EXEC_OMP_MASTER:
-    return ST_OMP_MASTER;
-  case EXEC_OMP_SINGLE:
-    return ST_OMP_SINGLE;
-  case EXEC_OMP_TASK:
-    return ST_OMP_TASK;
-  case EXEC_OMP_WORKSHARE:
-    return ST_OMP_WORKSHARE;
-  case EXEC_OMP_PARALLEL_WORKSHARE:
-    return ST_OMP_PARALLEL_WORKSHARE;
-  case EXEC_OMP_DO:
-    return ST_OMP_DO;
-  default:
-    gcc_unreachable ();
-  }
+  switch (code->op)
+    {
+    case EXEC_OMP_PARALLEL:
+      return ST_OMP_PARALLEL;
+    case EXEC_OMP_PARALLEL_SECTIONS:
+      return ST_OMP_PARALLEL_SECTIONS;
+    case EXEC_OMP_SECTIONS:
+      return ST_OMP_SECTIONS;
+    case EXEC_OMP_ORDERED:
+      return ST_OMP_ORDERED;
+    case EXEC_OMP_CRITICAL:
+      return ST_OMP_CRITICAL;
+    case EXEC_OMP_MASTER:
+      return ST_OMP_MASTER;
+    case EXEC_OMP_SINGLE:
+      return ST_OMP_SINGLE;
+    case EXEC_OMP_TASK:
+      return ST_OMP_TASK;
+    case EXEC_OMP_WORKSHARE:
+      return ST_OMP_WORKSHARE;
+    case EXEC_OMP_PARALLEL_WORKSHARE:
+      return ST_OMP_PARALLEL_WORKSHARE;
+    case EXEC_OMP_DO:
+      return ST_OMP_DO;
+    default:
+      gcc_unreachable ();
+    }
 }
 
 static gfc_statement
 oacc_code_to_statement (gfc_code *code)
 {
-switch (code->op)
-  {
-  case EXEC_OACC_PARALLEL:
-    return ST_OACC_PARALLEL;
-  case EXEC_OACC_KERNELS:
-    return ST_OACC_KERNELS;
-  case EXEC_OACC_DATA:
-    return ST_OACC_DATA;
-  case EXEC_OACC_HOST_DATA:
-    return ST_OACC_HOST_DATA;
-  case EXEC_OACC_PARALLEL_LOOP:
-    return ST_OACC_PARALLEL_LOOP;
-  case EXEC_OACC_KERNELS_LOOP:
-    return ST_OACC_KERNELS_LOOP;
-  case EXEC_OACC_LOOP:
-    return ST_OACC_LOOP;
-  default:
-    gcc_unreachable ();
-  }
+  switch (code->op)
+    {
+    case EXEC_OACC_PARALLEL:
+      return ST_OACC_PARALLEL;
+    case EXEC_OACC_KERNELS:
+      return ST_OACC_KERNELS;
+    case EXEC_OACC_DATA:
+      return ST_OACC_DATA;
+    case EXEC_OACC_HOST_DATA:
+      return ST_OACC_HOST_DATA;
+    case EXEC_OACC_PARALLEL_LOOP:
+      return ST_OACC_PARALLEL_LOOP;
+    case EXEC_OACC_KERNELS_LOOP:
+      return ST_OACC_KERNELS_LOOP;
+    case EXEC_OACC_LOOP:
+      return ST_OACC_LOOP;
+    default:
+      gcc_unreachable ();
+    }
 }
 
 static void
@@ -4581,7 +4582,7 @@  gfc_resolve_oacc_blocks (gfc_code *code, gfc_namespace *ns)
 
 
 static void
-resolve_oacc_loop(gfc_code *code)
+resolve_oacc_loop (gfc_code *code)
 {
   gfc_code *do_code;
   int collapse;
@@ -4601,7 +4602,7 @@  resolve_oacc_loop(gfc_code *code)
 static void
 resolve_oacc_cache (gfc_code *code)
 {
-  gfc_error ("Sorry, !$ACC cache unimplemented yet at %L", &code->loc);
+  sorry ("Sorry, !$ACC cache unimplemented yet");
 }
 
 
@@ -4615,10 +4616,9 @@  gfc_resolve_oacc_declare (gfc_namespace *ns)
   if (ns->oacc_declare_clauses == NULL)
     return;
 
-  loc = ns->oacc_declare_clauses->ext.loc;
+  loc = ns->oacc_declare_clauses->loc;
 
-  /* FIXME: handle omp_list_map.  */
-  for (/* TODO */ list = OMP_LIST_DEVICE_RESIDENT;
+  for (list = OMP_LIST_DEVICE_RESIDENT;
        list <= OMP_LIST_DEVICE_RESIDENT; list++)
     for (n = ns->oacc_declare_clauses->lists[list]; n; n = n->next)
       {
@@ -4627,7 +4627,7 @@  gfc_resolve_oacc_declare (gfc_namespace *ns)
 	  gfc_error ("PARAMETER object '%s' is not allowed at %L", n->sym->name, &loc);
       }
 
-  for (/* TODO */ list = OMP_LIST_DEVICE_RESIDENT;
+  for (list = OMP_LIST_DEVICE_RESIDENT;
        list <= OMP_LIST_DEVICE_RESIDENT; list++)
     for (n = ns->oacc_declare_clauses->lists[list]; n; n = n->next)
       {
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 33b10cd..15702b7 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -3818,7 +3818,9 @@  parse_critical_block (void)
 
   for (sd = gfc_state_stack; sd; sd = sd->previous) 
     if (sd->state == COMP_OMP_STRUCTURED_BLOCK)
-      gfc_error_now ("CRITICAL block inside of OpenMP or OpenACC region at %C");
+      gfc_error_now (is_oacc (sd)
+		     ? "CRITICAL block inside of OpenACC region at %C"
+		     : "CRITICAL block inside of OpenMP region at %C");
 
   s.ext.end_do_label = new_st.label1;
 
@@ -5545,3 +5547,28 @@  duplicate_main:
   gfc_done_2 ();
   return true;
 }
+
+/* Return true if this state data represents an OpenACC region.  */
+bool
+is_oacc (gfc_state_data *sd)
+{
+  switch (sd->construct->op)
+    {
+    case EXEC_OACC_PARALLEL_LOOP:break;
+    case EXEC_OACC_PARALLEL:
+    case EXEC_OACC_KERNELS_LOOP:
+    case EXEC_OACC_KERNELS:
+    case EXEC_OACC_DATA:
+    case EXEC_OACC_HOST_DATA:
+    case EXEC_OACC_LOOP:
+    case EXEC_OACC_UPDATE:
+    case EXEC_OACC_WAIT:
+    case EXEC_OACC_CACHE:
+    case EXEC_OACC_ENTER_DATA:
+    case EXEC_OACC_EXIT_DATA:
+      return true;
+
+    default:
+      return false;
+    }
+}
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
index be09a97..da7c4e1 100644
--- a/gcc/fortran/parse.h
+++ b/gcc/fortran/parse.h
@@ -69,4 +69,5 @@  match gfc_match_enumerator_def (void);
 void gfc_free_enum_history (void);
 extern bool gfc_matching_function;
 match gfc_match_prefix (gfc_typespec *);
+bool is_oacc (gfc_state_data *);
 #endif  /* GFC_PARSE_H  */
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 85ce3f8..fa9ebea 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -56,7 +56,8 @@  gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
 static gfc_file *file_head, *current_file;
 
 static int continue_flag, end_flag, gcc_attribute_flag;
-static int openmp_flag, openacc_flag; /* If !$omp/!$acc occurred in current comment line */
+/* If !$omp/!$acc occurred in current comment line.  */
+static int openmp_flag, openacc_flag;
 static int continue_count, continue_line;
 static locus openmp_locus;
 static locus openacc_locus;
@@ -1363,7 +1364,7 @@  restart:
 	{
 	  for (i = 0; i < 5; i++, c = next_char ())
 	    {
-	      gcc_assert(gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
+	      gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
 	      if (i == 4)
 		old_loc = gfc_current_locus;
 	    }
@@ -1431,18 +1432,16 @@  restart:
       skip_fixed_comments ();
 
       /* See if this line is a continuation line.  */
-      if (gfc_option.gfc_flag_openmp)
-	if (openmp_flag != prev_openmp_flag)
-	  {
-	    openmp_flag = prev_openmp_flag;
-	    goto not_continuation;
-	  }
-      if (gfc_option.gfc_flag_openacc)
-	if (openacc_flag != prev_openacc_flag)
-	  {
-	    openacc_flag = prev_openacc_flag;
-	    goto not_continuation;
-	  }
+      if (gfc_option.gfc_flag_openmp && openmp_flag != prev_openmp_flag)
+	{
+	  openmp_flag = prev_openmp_flag;
+	  goto not_continuation;
+	}
+      if (gfc_option.gfc_flag_openacc && openacc_flag != prev_openacc_flag)
+	{
+	  openacc_flag = prev_openacc_flag;
+	  goto not_continuation;
+	}
 
       if (!openmp_flag && !openacc_flag)
 	for (i = 0; i < 5; i++)
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 6967c4f..aec2ce7 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -2502,8 +2502,8 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
     {
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_ASYNC);
       if (clauses->async_expr)
-	OMP_CLAUSE_ASYNC_EXPR (c) =
-	    gfc_convert_expr_to_tree (block, clauses->async_expr);
+	OMP_CLAUSE_ASYNC_EXPR (c)
+	  = gfc_convert_expr_to_tree (block, clauses->async_expr);
       else
 	OMP_CLAUSE_ASYNC_EXPR (c) = NULL;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
@@ -2532,36 +2532,36 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
     }
   if (clauses->num_gangs_expr)
     {
-      tree num_gangs_var = 
-	  gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
+      tree num_gangs_var
+	= gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_GANGS);
       OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
   if (clauses->num_workers_expr)
     {
-      tree num_workers_var = 
-	  gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
+      tree num_workers_var
+	= gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_WORKERS);
-      OMP_CLAUSE_NUM_WORKERS_EXPR (c)= num_workers_var;
+      OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
   if (clauses->vector_length_expr)
     {
-      tree vector_length_var = 
-	  gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
+      tree vector_length_var
+	= gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR_LENGTH);
-      OMP_CLAUSE_VECTOR_LENGTH_EXPR (c)= vector_length_var;
+      OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
   if (clauses->vector)
     {
       if (clauses->vector_expr)
 	{
-	  tree vector_var = 
-	      gfc_convert_expr_to_tree (block, clauses->vector_expr);
+	  tree vector_var
+	    = gfc_convert_expr_to_tree (block, clauses->vector_expr);
 	  c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
-	  OMP_CLAUSE_VECTOR_EXPR (c)= vector_var;
+	  OMP_CLAUSE_VECTOR_EXPR (c) = vector_var;
 	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
 	}
       else
@@ -2574,10 +2574,10 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
     {
       if (clauses->worker_expr)
 	{
-	  tree worker_var = 
-	      gfc_convert_expr_to_tree (block, clauses->worker_expr);
+	  tree worker_var
+	    = gfc_convert_expr_to_tree (block, clauses->worker_expr);
 	  c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
-	  OMP_CLAUSE_WORKER_EXPR (c)= worker_var;
+	  OMP_CLAUSE_WORKER_EXPR (c) = worker_var;
 	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
 	}
       else
@@ -2590,10 +2590,10 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
     {
       if (clauses->gang_expr)
 	{
-	  tree gang_var = 
-	      gfc_convert_expr_to_tree (block, clauses->gang_expr);
+	  tree gang_var
+	    = gfc_convert_expr_to_tree (block, clauses->gang_expr);
 	  c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
-	  OMP_CLAUSE_GANG_EXPR (c)= gang_var;
+	  OMP_CLAUSE_GANG_EXPR (c) = gang_var;
 	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
 	}
       else
@@ -4323,8 +4323,8 @@  gfc_trans_oacc_declare (stmtblock_t *block, gfc_namespace *ns)
 {
   tree oacc_clauses;
   oacc_clauses = gfc_trans_omp_clauses (block, ns->oacc_declare_clauses,
-					ns->oacc_declare_clauses->ext.loc);
-  return build1_loc (ns->oacc_declare_clauses->ext.loc.lb->location, 
+					ns->oacc_declare_clauses->loc);
+  return build1_loc (ns->oacc_declare_clauses->loc.lb->location,
 		     OACC_DECLARE, void_type_node, oacc_clauses);
 }
 
diff --git a/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90 b/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90
index 7cfa3f0..c97af1d 100644
--- a/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90
@@ -44,7 +44,7 @@  outer: do i = 1, 30
   end do outer
 last: do i = 1, 30
 !$omp parallel
-    if (i .eq. 21) exit last ! { dg-error "leaving OpenMP or OpenACC structured block" }
+    if (i .eq. 21) exit last ! { dg-error "leaving OpenMP structured block" }
 !$omp end parallel
   end do last
 !$omp parallel do shared (i)