diff mbox

[gomp4] OpenACC structured blocks (was: PING: Fwd: Re: [patch] implement Cilk Plus simd loops on trunk)

Message ID 87r49kuass.fsf@kepler.schwinge.homeip.net
State New
Headers show

Commit Message

Thomas Schwinge Dec. 10, 2013, 12:53 p.m. UTC
Hi!

At the end of this email you can find the patch that I'd like to apply to
gomp-4_0-branch for OpenACC structured blocks, after the following two
have been approved:

On Fri, 06 Dec 2013 19:33:35 +0100, I wrote:
> On Fri, 15 Nov 2013 14:44:45 -0700, Aldy Hernandez <aldyh@redhat.com> wrote:
> > --- a/gcc/omp-low.c
> > +++ b/gcc/omp-low.c
> > @@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >      error ("invalid entry to OpenMP structured block");
> >  #endif
> >  
> > +  bool cilkplus_block = false;
> > +  if (flag_enable_cilkplus)
> > +    {
> > +      if ((branch_ctx
> > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > +	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > +	cilkplus_block = true;
> > +    }
> 
> There is one issue here: consider the following code:
> 
>     void baz()
>     {
>       bad1:
>       #pragma omp parallel
>         goto bad1;
>     }
> 
> Then, if both -fcilkplus and -fopenmp are specified, that will run into a
> SIGSEGV/ICE because of label_ctx == NULL.  The fix is simple enough; OK
> for trunk and gomp-4_0-branch (after full testing)?

Testing looks good.

> The testcase is
> basically a concatenation of gcc.dg/cilk-plus/jump.c and
> gcc.dg/gomp/block-1.c -- should this be done differently/better?
> 
> commit eee16f8aad4527b705d327476b00bf9f5ba6dcce
> Author: Thomas Schwinge <thomas@codesourcery.com>
> Date:   Fri Dec 6 18:55:41 2013 +0100
> 
>     Fix possible ICE (null pointer dereference) introduced in r204863.
>     
>     	gcc/
>     	* omp-low.c (diagnose_sb_0): Make sure label_ctx is valid to
>     	dereference.
>     	gcc/testsuite/
>     	* gcc.dg/cilk-plus/jump-openmp.c: New file.
> 
> diff --git gcc/omp-low.c gcc/omp-low.c
> index e0f7d1d..91221c0 100644
> --- gcc/omp-low.c
> +++ gcc/omp-low.c
> @@ -10865,7 +10865,8 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
>        if ((branch_ctx
>  	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
>  	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> -	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> +	  || (label_ctx
> +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
>  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
>  	cilkplus_block = true;
>      }
> diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> new file mode 100644
> index 0000000..95e6b2d
> --- /dev/null
> +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> @@ -0,0 +1,49 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fcilkplus -fopenmp" } */
> +/* { dg-require-effective-target fopenmp } */
> +
> +int *a, *b, c;
> +
> +void foo()
> +{
> +#pragma simd
> +  for (int i=0; i < 1000; ++i)
> +    {
> +      a[i] = b[i];
> +      if (c == 5)
> +	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> +    }
> +}
> +
> +void bar()
> +{
> +#pragma simd
> +  for (int i=0; i < 1000; ++i)
> +    {
> +    lab:
> +      a[i] = b[i];
> +    }
> +  if (c == 6)
> +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> +}
> +
> +void baz()
> +{
> +  bad1:
> +  #pragma omp parallel
> +    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> +
> +  goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> +  #pragma omp parallel
> +    {
> +      bad2: ;
> +    }
> +
> +  #pragma omp parallel
> +    {
> +      int i;
> +      goto ok1;
> +      for (i = 0; i < 10; ++i)
> +	{ ok1: break; }
> +    }
> +}
> 
> 
> >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> >    if (branch_ctx == NULL)
> > -    error ("invalid entry to OpenMP structured block");
> > +    {
> > +      if (cilkplus_block)
> > +	error ("invalid entry to Cilk Plus structured block");
> > +      else
> > +	error ("invalid entry to OpenMP structured block");
> > +    }
> >    else
> > -    /* Otherwise, be vague and lazy, but efficient.  */
> > -    error ("invalid branch to/from an OpenMP structured block");
> > +    {
> > +      /* Otherwise, be vague and lazy, but efficient.  */
> > +      if (cilkplus_block)
> > +	error ("invalid branch to/from a Cilk Plus structured block");
> > +      else
> > +	error ("invalid branch to/from an OpenMP structured block");
> > +    }
> 
> In fact, and keeping in mind that we're currently adding OpenACC support,
> I'd suggest to do this differently; OK for trunk and gomp-4_0-branch?

Testing looks good.

> commit 367dabfcc94a3e96d63b48c38d0dd94ca9f517f8
> Author: Thomas Schwinge <thomas@codesourcery.com>
> Date:   Fri Dec 6 19:23:47 2013 +0100
> 
>     Generalize diagnose_omp_blocks' structured block logic.
>     
>     	gcc/
>     	* omp-low.c (diagnose_sb_0): Generalize detection which kind of
>     	structured block we're in.
>     	gcc/testsuite/
>     	* g++.dg/gomp/block-1.C: Adjust to changed error message and/or
>     	be tighten matching rules.
>     	* g++.dg/gomp/block-2.C: Likewise.
>     	* g++.dg/gomp/block-3.C: Likewise.
>     	* g++.dg/gomp/block-5.C: Likewise.
>     	* g++.dg/gomp/target-1.C: Likewise.
>     	* g++.dg/gomp/target-2.C: Likewise.
>     	* g++.dg/gomp/taskgroup-1.C: Likewise.
>     	* g++.dg/gomp/teams-1.C: Likewise.
>     	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
>     	* gcc.dg/cilk-plus/jump.c: Likewise.
>     	* gcc.dg/gomp/block-1.c: Likewise.
>     	* gcc.dg/gomp/block-10.c: Likewise.
>     	* gcc.dg/gomp/block-2.c: Likewise.
>     	* gcc.dg/gomp/block-3.c: Likewise.
>     	* gcc.dg/gomp/block-4.c: Likewise.
>     	* gcc.dg/gomp/block-5.c: Likewise.
>     	* gcc.dg/gomp/block-6.c: Likewise.
>     	* gcc.dg/gomp/block-7.c: Likewise.
>     	* gcc.dg/gomp/block-8.c: Likewise.
>     	* gcc.dg/gomp/block-9.c: Likewise.
>     	* gcc.dg/gomp/target-1.c: Likewise.
>     	* gcc.dg/gomp/target-2.c: Likewise.
>     	* gcc.dg/gomp/taskgroup-1.c: Likewise.
>     	* gcc.dg/gomp/teams-1.c: Likewise.
> 
> diff --git gcc/omp-low.c gcc/omp-low.c
> index 91221c0..f55a1ea 100644
> --- gcc/omp-low.c
> +++ gcc/omp-low.c
> @@ -10822,6 +10822,23 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
>    if (label_ctx == branch_ctx)
>      return false;
>  
> +  const char* kind = NULL;
> +
> +  if (flag_enable_cilkplus)
> +    {
> +      if ((branch_ctx
> +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> +	  || (label_ctx
> +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> +	kind = "Cilk Plus";
> +    }
> +  if (kind == NULL)
> +    {
> +      gcc_assert (flag_openmp);
> +      kind = "OpenMP";
> +    }
>  
>    /*
>       Previously we kept track of the label's entire context in diagnose_sb_[12]
> @@ -10854,38 +10871,18 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
>      }
>  
>    if (exit_p)
> -    error ("invalid exit from OpenMP structured block");
> +    error ("invalid exit from %s structured block", kind);
>    else
> -    error ("invalid entry to OpenMP structured block");
> +    error ("invalid entry to %s structured block", kind);
>  #endif
>  
> -  bool cilkplus_block = false;
> -  if (flag_enable_cilkplus)
> -    {
> -      if ((branch_ctx
> -	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> -	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> -	  || (label_ctx
> -	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> -	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> -	cilkplus_block = true;
> -    }
> -
>    /* If it's obvious we have an invalid entry, be specific about the error.  */
>    if (branch_ctx == NULL)
> -    {
> -      if (cilkplus_block)
> -	error ("invalid entry to Cilk Plus structured block");
> -      else
> -	error ("invalid entry to OpenMP structured block");
> -    }
> +    error ("invalid entry to %s structured block", kind);
>    else
>      {
>        /* Otherwise, be vague and lazy, but efficient.  */
> -      if (cilkplus_block)
> -	error ("invalid branch to/from a Cilk Plus structured block");
> -      else
> -	error ("invalid branch to/from an OpenMP structured block");
> +      error ("invalid branch to/from %s structured block", kind);
>      }
>  
>    gsi_replace (gsi_p, gimple_build_nop (), false);
> diff --git gcc/testsuite/g++.dg/gomp/block-1.C gcc/testsuite/g++.dg/gomp/block-1.C
> index d2b8664..f4badaf 100644
> --- gcc/testsuite/g++.dg/gomp/block-1.C
> +++ gcc/testsuite/g++.dg/gomp/block-1.C
> @@ -21,5 +21,5 @@ void foo()
>      }
>  }
>  
> -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
>  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
> diff --git gcc/testsuite/g++.dg/gomp/block-2.C gcc/testsuite/g++.dg/gomp/block-2.C
> index 17d98d8..02f5f83d 100644
> --- gcc/testsuite/g++.dg/gomp/block-2.C
> +++ gcc/testsuite/g++.dg/gomp/block-2.C
> @@ -31,5 +31,5 @@ void foo()
>      continue;
>  }
>  
> -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
> +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 14 }
>  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
> diff --git gcc/testsuite/g++.dg/gomp/block-3.C gcc/testsuite/g++.dg/gomp/block-3.C
> index ff28175..bb54166 100644
> --- gcc/testsuite/g++.dg/gomp/block-3.C
> +++ gcc/testsuite/g++.dg/gomp/block-3.C
> @@ -58,6 +58,6 @@ void foo()
>      }
>  }
>  
> -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
> -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
> +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 21 }
> +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 26 }
>  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
> diff --git gcc/testsuite/g++.dg/gomp/block-5.C gcc/testsuite/g++.dg/gomp/block-5.C
> index 391f8b6..0aa23a4 100644
> --- gcc/testsuite/g++.dg/gomp/block-5.C
> +++ gcc/testsuite/g++.dg/gomp/block-5.C
> @@ -14,4 +14,4 @@ void foo()
>      }
>  }
>  
> -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> diff --git gcc/testsuite/g++.dg/gomp/target-1.C gcc/testsuite/g++.dg/gomp/target-1.C
> index b6ed4f8..767661f 100644
> --- gcc/testsuite/g++.dg/gomp/target-1.C
> +++ gcc/testsuite/g++.dg/gomp/target-1.C
> @@ -28,5 +28,5 @@ foo (int x)
>    }
>  }
>  
> -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
>  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> diff --git gcc/testsuite/g++.dg/gomp/target-2.C gcc/testsuite/g++.dg/gomp/target-2.C
> index 6a14f53..5a40dd4 100644
> --- gcc/testsuite/g++.dg/gomp/target-2.C
> +++ gcc/testsuite/g++.dg/gomp/target-2.C
> @@ -28,5 +28,5 @@ foo (int x, int y)
>    }
>  }
>  
> -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
>  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> diff --git gcc/testsuite/g++.dg/gomp/taskgroup-1.C gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> index dcab0bb..a06edf1 100644
> --- gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> +++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> @@ -28,5 +28,5 @@ foo (int x)
>    }
>  }
>  
> -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
>  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> diff --git gcc/testsuite/g++.dg/gomp/teams-1.C gcc/testsuite/g++.dg/gomp/teams-1.C
> index ce40b55..05f1a7e 100644
> --- gcc/testsuite/g++.dg/gomp/teams-1.C
> +++ gcc/testsuite/g++.dg/gomp/teams-1.C
> @@ -60,7 +60,7 @@ bar (int x)
>    }
>  }
>  
> -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
>  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
> +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 37 }
>  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }
> diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> index 95e6b2d..6adabf4 100644
> --- gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> @@ -11,7 +11,7 @@ void foo()
>      {
>        a[i] = b[i];
>        if (c == 5)
> -	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
>      }
>  }
>  
> @@ -31,7 +31,7 @@ void baz()
>  {
>    bad1:
>    #pragma omp parallel
> -    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> +    goto bad1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
>  
>    goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
>    #pragma omp parallel
> diff --git gcc/testsuite/gcc.dg/cilk-plus/jump.c gcc/testsuite/gcc.dg/cilk-plus/jump.c
> index 9ec3293..1ca886a 100644
> --- gcc/testsuite/gcc.dg/cilk-plus/jump.c
> +++ gcc/testsuite/gcc.dg/cilk-plus/jump.c
> @@ -10,7 +10,7 @@ void foo()
>      {
>        a[i] = b[i];
>        if (c == 5)
> -	return;	 /* { dg-error "invalid branch to.from a Cilk" } */
> +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
>      }
>  }
>  
> @@ -23,5 +23,5 @@ void bar()
>        a[i] = b[i];
>      }
>    if (c == 6)
> -    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
> +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-1.c gcc/testsuite/gcc.dg/gomp/block-1.c
> index dd7fe77..e67e6c3 100644
> --- gcc/testsuite/gcc.dg/gomp/block-1.c
> +++ gcc/testsuite/gcc.dg/gomp/block-1.c
> @@ -4,9 +4,9 @@ void foo()
>  {
>    bad1:
>    #pragma omp parallel
> -    goto bad1;			// { dg-error "invalid branch" }
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			// { dg-error "invalid entry" }
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp parallel
>      {
>        bad2: ;
> diff --git gcc/testsuite/gcc.dg/gomp/block-10.c gcc/testsuite/gcc.dg/gomp/block-10.c
> index 76ee397..69ae3c0 100644
> --- gcc/testsuite/gcc.dg/gomp/block-10.c
> +++ gcc/testsuite/gcc.dg/gomp/block-10.c
> @@ -3,28 +3,28 @@
>  void foo(int i)
>  {
>    int j;
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp parallel
>      { case 0:; }
>    }
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp for
>      for (j = 0; j < 10; ++ j)
>        { case 1:; }
>    }
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp critical
>      { case 2:; }
>    }
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp master
>      { case 3:; }
>    }
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp sections
>      { case 4:;
> @@ -32,7 +32,7 @@ void foo(int i)
>         { case 5:; }
>      }
>    }
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp ordered
>      { default:; }
> diff --git gcc/testsuite/gcc.dg/gomp/block-2.c gcc/testsuite/gcc.dg/gomp/block-2.c
> index 4c56add..5c01463 100644
> --- gcc/testsuite/gcc.dg/gomp/block-2.c
> +++ gcc/testsuite/gcc.dg/gomp/block-2.c
> @@ -11,9 +11,9 @@ void foo()
>    bad1:
>    #pragma omp for
>    for (i = 0; i < 10; ++i)
> -    goto bad1;			// { dg-error "invalid branch" }
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			// { dg-error "invalid entry" }
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp for
>    for (i = 0; i < 10; ++i)
>      {
> diff --git gcc/testsuite/gcc.dg/gomp/block-3.c gcc/testsuite/gcc.dg/gomp/block-3.c
> index b4530e9..3be15fb 100644
> --- gcc/testsuite/gcc.dg/gomp/block-3.c
> +++ gcc/testsuite/gcc.dg/gomp/block-3.c
> @@ -18,16 +18,16 @@ void foo()
>      #pragma omp section
>        { bad1: ; }
>      #pragma omp section
> -      goto bad1;		// { dg-error "invalid branch" }
> +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>  
>    #pragma omp sections
>      {
> -      goto bad2;		// { dg-error "invalid branch" }
> +      goto bad2; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>    bad2:;
>  
> -  goto bad3;			// { dg-error "invalid entry" }
> +  goto bad3; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp sections
>      {
>        bad3: ;
> diff --git gcc/testsuite/gcc.dg/gomp/block-4.c gcc/testsuite/gcc.dg/gomp/block-4.c
> index 61f490c..b2ef9b1 100644
> --- gcc/testsuite/gcc.dg/gomp/block-4.c
> +++ gcc/testsuite/gcc.dg/gomp/block-4.c
> @@ -4,6 +4,6 @@ void foo()
>  {
>    #pragma omp critical
>      {
> -      return;		// { dg-error "invalid branch" }
> +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-5.c gcc/testsuite/gcc.dg/gomp/block-5.c
> index 741049f..7f3b37c 100644
> --- gcc/testsuite/gcc.dg/gomp/block-5.c
> +++ gcc/testsuite/gcc.dg/gomp/block-5.c
> @@ -4,12 +4,12 @@ void foo()
>  {
>    #pragma omp master
>      {
> -      goto bad1;	// { dg-error "invalid branch" }
> +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>  
>    #pragma omp master
>      {
>      bad1:
> -      return;		// { dg-error "invalid branch" }
> +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-6.c gcc/testsuite/gcc.dg/gomp/block-6.c
> index 87e6392..fc9fdc8 100644
> --- gcc/testsuite/gcc.dg/gomp/block-6.c
> +++ gcc/testsuite/gcc.dg/gomp/block-6.c
> @@ -4,6 +4,6 @@ void foo()
>  {
>    #pragma omp ordered
>      {
> -      return;		// { dg-error "invalid branch" }
> +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
>      }
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-7.c gcc/testsuite/gcc.dg/gomp/block-7.c
> index 2bc1cdb..6219e7e 100644
> --- gcc/testsuite/gcc.dg/gomp/block-7.c
> +++ gcc/testsuite/gcc.dg/gomp/block-7.c
> @@ -6,15 +6,15 @@ void foo()
>    for (i = 0; i < 10; ++i)
>      {
>        #pragma omp for
> -      for (j = ({ continue; 0; });	// { dg-error "invalid branch" }
> -	   j < ({ continue; 10; });	// { dg-error "invalid branch" }
> -	   j += ({ continue; 1; }))	// { dg-error "invalid branch" }
> +      for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> +	   j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> +	   j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
>  	continue;
>  
>        #pragma omp for
> -      for (j = ({ break; 0; });		// { dg-error "invalid branch" }
> -	   j < ({ break; 10; });	// { dg-error "invalid branch" }
> -	   j += ({ break; 1; }))	// { dg-error "invalid branch" }
> +      for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> +	   j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> +	   j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
>  	break;				// { dg-error "break" }
>      }
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-8.c gcc/testsuite/gcc.dg/gomp/block-8.c
> index 3c717d9..f410070 100644
> --- gcc/testsuite/gcc.dg/gomp/block-8.c
> +++ gcc/testsuite/gcc.dg/gomp/block-8.c
> @@ -7,5 +7,5 @@ int foo()
>  
>    #pragma omp parallel for
>    for (i = 0; i < 10; ++i)
> -    return 0;			// { dg-error "invalid branch" }
> +    return 0; // { dg-error "invalid branch to/from OpenMP structured block" }
>  }
> diff --git gcc/testsuite/gcc.dg/gomp/block-9.c gcc/testsuite/gcc.dg/gomp/block-9.c
> index 9217cb7..2fae3de 100644
> --- gcc/testsuite/gcc.dg/gomp/block-9.c
> +++ gcc/testsuite/gcc.dg/gomp/block-9.c
> @@ -3,7 +3,7 @@
>  void foo(int i)
>  {
>    int j;
> -  switch (i)			// { dg-error "invalid entry" }
> +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp parallel
>      { case 0:; }
> diff --git gcc/testsuite/gcc.dg/gomp/target-1.c gcc/testsuite/gcc.dg/gomp/target-1.c
> index 09e65bd..aaa6a14 100644
> --- gcc/testsuite/gcc.dg/gomp/target-1.c
> +++ gcc/testsuite/gcc.dg/gomp/target-1.c
> @@ -5,9 +5,9 @@ foo (int x)
>  {
>    bad1:
>    #pragma omp target
> -    goto bad1;			/* { dg-error "invalid branch" } */
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			/* { dg-error "invalid entry" } */
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp target
>      {
>        bad2: ;
> @@ -21,7 +21,7 @@ foo (int x)
>  	{ ok1: break; }
>      }
>  
> -  switch (x)			/* { dg-error "invalid entry" } */
> +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp target
>      { case 0:; }
> diff --git gcc/testsuite/gcc.dg/gomp/target-2.c gcc/testsuite/gcc.dg/gomp/target-2.c
> index 546a1d0..3a7afc4 100644
> --- gcc/testsuite/gcc.dg/gomp/target-2.c
> +++ gcc/testsuite/gcc.dg/gomp/target-2.c
> @@ -5,9 +5,9 @@ foo (int x, int y)
>  {
>    bad1:
>    #pragma omp target data map(tofrom: y)
> -    goto bad1;			/* { dg-error "invalid branch" } */
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			/* { dg-error "invalid entry" } */
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp target data map(tofrom: y)
>      {
>        bad2: ;
> @@ -21,7 +21,7 @@ foo (int x, int y)
>  	{ ok1: break; }
>      }
>  
> -  switch (x)			/* { dg-error "invalid entry" } */
> +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp target data map(tofrom: y)
>      { case 0:; }
> diff --git gcc/testsuite/gcc.dg/gomp/taskgroup-1.c gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> index e301efc..1997e0c 100644
> --- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> +++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> @@ -5,9 +5,9 @@ foo (int x)
>  {
>    bad1:
>    #pragma omp taskgroup
> -    goto bad1;			/* { dg-error "invalid branch" } */
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			/* { dg-error "invalid entry" } */
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp taskgroup
>      {
>        bad2: ;
> @@ -21,7 +21,7 @@ foo (int x)
>  	{ ok1: break; }
>      }
>  
> -  switch (x)			/* { dg-error "invalid entry" } */
> +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp taskgroup
>      { case 0:; }
> diff --git gcc/testsuite/gcc.dg/gomp/teams-1.c gcc/testsuite/gcc.dg/gomp/teams-1.c
> index 73c00de..ad5b100 100644
> --- gcc/testsuite/gcc.dg/gomp/teams-1.c
> +++ gcc/testsuite/gcc.dg/gomp/teams-1.c
> @@ -5,9 +5,9 @@ foo (int x)
>  {
>    bad1:
>    #pragma omp target teams
> -    goto bad1;			/* { dg-error "invalid branch" } */
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			/* { dg-error "invalid entry" } */
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp target teams
>      {
>        bad2: ;
> @@ -21,7 +21,7 @@ foo (int x)
>  	{ ok1: break; }
>      }
>  
> -  switch (x)			/* { dg-error "invalid entry" } */
> +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp target teams
>      { case 0:; }
> @@ -34,9 +34,9 @@ bar (int x)
>    bad1:
>    #pragma omp target
>    #pragma omp teams
> -    goto bad1;			/* { dg-error "invalid branch" } */
> +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
>  
> -  goto bad2;			/* { dg-error "invalid entry" } */
> +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
>    #pragma omp target
>    #pragma omp teams
>      {
> @@ -52,7 +52,7 @@ bar (int x)
>  	{ ok1: break; }
>      }
>  
> -  switch (x)			/* { dg-error "invalid entry" } */
> +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
>    {
>    #pragma omp target
>    #pragma omp teams


OpenACC structured blocks; OK for gomp-4_0-branch?

commit 58c24ac3e22a5b050227c44e97faf478f8b9f591
Author: Thomas Schwinge <thomas@codesourcery.com>
Date:   Tue Dec 10 13:10:24 2013 +0100

    OpenACC parallel structured blocks.
    
    	gcc/
    	* gcc/omp-low.c (diagnose_sb_0, diagnose_sb_1, diagnose_sb_2):
    	Handle GIMPLE_OACC_PARALLEL.
    	* gimplify.c (gimplify_case_label_expr): Update comment.
    	gcc/testsuite/
    	* gcc.dg/goacc/parallel-sb-1.c: New file.
    	* gcc.dg/goacc/parallel-sb-2.c: Likewise.



Grüße,
 Thomas

Comments

Thomas Schwinge Dec. 19, 2013, 4:49 p.m. UTC | #1
Hi!

Ping.

On Tue, 10 Dec 2013 13:53:39 +0100, I wrote:
> At the end of this email you can find the patch that I'd like to apply to
> gomp-4_0-branch for OpenACC structured blocks, after the following two
> have been approved:

> On Fri, 06 Dec 2013 19:33:35 +0100, I wrote:
> > On Fri, 15 Nov 2013 14:44:45 -0700, Aldy Hernandez <aldyh@redhat.com> wrote:
> > > --- a/gcc/omp-low.c
> > > +++ b/gcc/omp-low.c
> > > @@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >      error ("invalid entry to OpenMP structured block");
> > >  #endif
> > >  
> > > +  bool cilkplus_block = false;
> > > +  if (flag_enable_cilkplus)
> > > +    {
> > > +      if ((branch_ctx
> > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > +	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > +	cilkplus_block = true;
> > > +    }
> > 
> > There is one issue here: consider the following code:
> > 
> >     void baz()
> >     {
> >       bad1:
> >       #pragma omp parallel
> >         goto bad1;
> >     }
> > 
> > Then, if both -fcilkplus and -fopenmp are specified, that will run into a
> > SIGSEGV/ICE because of label_ctx == NULL.  The fix is simple enough; OK
> > for trunk and gomp-4_0-branch (after full testing)?
> 
> Testing looks good.
> 
> > The testcase is
> > basically a concatenation of gcc.dg/cilk-plus/jump.c and
> > gcc.dg/gomp/block-1.c -- should this be done differently/better?
> > 
> > commit eee16f8aad4527b705d327476b00bf9f5ba6dcce
> > Author: Thomas Schwinge <thomas@codesourcery.com>
> > Date:   Fri Dec 6 18:55:41 2013 +0100
> > 
> >     Fix possible ICE (null pointer dereference) introduced in r204863.
> >     
> >     	gcc/
> >     	* omp-low.c (diagnose_sb_0): Make sure label_ctx is valid to
> >     	dereference.
> >     	gcc/testsuite/
> >     	* gcc.dg/cilk-plus/jump-openmp.c: New file.
> > 
> > diff --git gcc/omp-low.c gcc/omp-low.c
> > index e0f7d1d..91221c0 100644
> > --- gcc/omp-low.c
> > +++ gcc/omp-low.c
> > @@ -10865,7 +10865,8 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >        if ((branch_ctx
> >  	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> >  	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > -	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > +	  || (label_ctx
> > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> >  	cilkplus_block = true;
> >      }
> > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > new file mode 100644
> > index 0000000..95e6b2d
> > --- /dev/null
> > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > @@ -0,0 +1,49 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-fcilkplus -fopenmp" } */
> > +/* { dg-require-effective-target fopenmp } */
> > +
> > +int *a, *b, c;
> > +
> > +void foo()
> > +{
> > +#pragma simd
> > +  for (int i=0; i < 1000; ++i)
> > +    {
> > +      a[i] = b[i];
> > +      if (c == 5)
> > +	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > +    }
> > +}
> > +
> > +void bar()
> > +{
> > +#pragma simd
> > +  for (int i=0; i < 1000; ++i)
> > +    {
> > +    lab:
> > +      a[i] = b[i];
> > +    }
> > +  if (c == 6)
> > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > +}
> > +
> > +void baz()
> > +{
> > +  bad1:
> > +  #pragma omp parallel
> > +    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > +
> > +  goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > +  #pragma omp parallel
> > +    {
> > +      bad2: ;
> > +    }
> > +
> > +  #pragma omp parallel
> > +    {
> > +      int i;
> > +      goto ok1;
> > +      for (i = 0; i < 10; ++i)
> > +	{ ok1: break; }
> > +    }
> > +}
> > 
> > 
> > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > >    if (branch_ctx == NULL)
> > > -    error ("invalid entry to OpenMP structured block");
> > > +    {
> > > +      if (cilkplus_block)
> > > +	error ("invalid entry to Cilk Plus structured block");
> > > +      else
> > > +	error ("invalid entry to OpenMP structured block");
> > > +    }
> > >    else
> > > -    /* Otherwise, be vague and lazy, but efficient.  */
> > > -    error ("invalid branch to/from an OpenMP structured block");
> > > +    {
> > > +      /* Otherwise, be vague and lazy, but efficient.  */
> > > +      if (cilkplus_block)
> > > +	error ("invalid branch to/from a Cilk Plus structured block");
> > > +      else
> > > +	error ("invalid branch to/from an OpenMP structured block");
> > > +    }

> > In fact, and keeping in mind that we're currently adding OpenACC support,
> > I'd suggest to do this differently; OK for trunk and gomp-4_0-branch?
> 
> Testing looks good.
> 
> > commit 367dabfcc94a3e96d63b48c38d0dd94ca9f517f8
> > Author: Thomas Schwinge <thomas@codesourcery.com>
> > Date:   Fri Dec 6 19:23:47 2013 +0100
> > 
> >     Generalize diagnose_omp_blocks' structured block logic.
> >     
> >     	gcc/
> >     	* omp-low.c (diagnose_sb_0): Generalize detection which kind of
> >     	structured block we're in.
> >     	gcc/testsuite/
> >     	* g++.dg/gomp/block-1.C: Adjust to changed error message and/or
> >     	be tighten matching rules.
> >     	* g++.dg/gomp/block-2.C: Likewise.
> >     	* g++.dg/gomp/block-3.C: Likewise.
> >     	* g++.dg/gomp/block-5.C: Likewise.
> >     	* g++.dg/gomp/target-1.C: Likewise.
> >     	* g++.dg/gomp/target-2.C: Likewise.
> >     	* g++.dg/gomp/taskgroup-1.C: Likewise.
> >     	* g++.dg/gomp/teams-1.C: Likewise.
> >     	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
> >     	* gcc.dg/cilk-plus/jump.c: Likewise.
> >     	* gcc.dg/gomp/block-1.c: Likewise.
> >     	* gcc.dg/gomp/block-10.c: Likewise.
> >     	* gcc.dg/gomp/block-2.c: Likewise.
> >     	* gcc.dg/gomp/block-3.c: Likewise.
> >     	* gcc.dg/gomp/block-4.c: Likewise.
> >     	* gcc.dg/gomp/block-5.c: Likewise.
> >     	* gcc.dg/gomp/block-6.c: Likewise.
> >     	* gcc.dg/gomp/block-7.c: Likewise.
> >     	* gcc.dg/gomp/block-8.c: Likewise.
> >     	* gcc.dg/gomp/block-9.c: Likewise.
> >     	* gcc.dg/gomp/target-1.c: Likewise.
> >     	* gcc.dg/gomp/target-2.c: Likewise.
> >     	* gcc.dg/gomp/taskgroup-1.c: Likewise.
> >     	* gcc.dg/gomp/teams-1.c: Likewise.
> > 
> > diff --git gcc/omp-low.c gcc/omp-low.c
> > index 91221c0..f55a1ea 100644
> > --- gcc/omp-low.c
> > +++ gcc/omp-low.c
> > @@ -10822,6 +10822,23 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >    if (label_ctx == branch_ctx)
> >      return false;
> >  
> > +  const char* kind = NULL;
> > +
> > +  if (flag_enable_cilkplus)
> > +    {
> > +      if ((branch_ctx
> > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > +	  || (label_ctx
> > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > +	kind = "Cilk Plus";
> > +    }
> > +  if (kind == NULL)
> > +    {
> > +      gcc_assert (flag_openmp);
> > +      kind = "OpenMP";
> > +    }
> >  
> >    /*
> >       Previously we kept track of the label's entire context in diagnose_sb_[12]
> > @@ -10854,38 +10871,18 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >      }
> >  
> >    if (exit_p)
> > -    error ("invalid exit from OpenMP structured block");
> > +    error ("invalid exit from %s structured block", kind);
> >    else
> > -    error ("invalid entry to OpenMP structured block");
> > +    error ("invalid entry to %s structured block", kind);
> >  #endif
> >  
> > -  bool cilkplus_block = false;
> > -  if (flag_enable_cilkplus)
> > -    {
> > -      if ((branch_ctx
> > -	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > -	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > -	  || (label_ctx
> > -	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > -	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > -	cilkplus_block = true;
> > -    }
> > -
> >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> >    if (branch_ctx == NULL)
> > -    {
> > -      if (cilkplus_block)
> > -	error ("invalid entry to Cilk Plus structured block");
> > -      else
> > -	error ("invalid entry to OpenMP structured block");
> > -    }
> > +    error ("invalid entry to %s structured block", kind);
> >    else
> >      {
> >        /* Otherwise, be vague and lazy, but efficient.  */
> > -      if (cilkplus_block)
> > -	error ("invalid branch to/from a Cilk Plus structured block");
> > -      else
> > -	error ("invalid branch to/from an OpenMP structured block");
> > +      error ("invalid branch to/from %s structured block", kind);
> >      }
> >  
> >    gsi_replace (gsi_p, gimple_build_nop (), false);
> > diff --git gcc/testsuite/g++.dg/gomp/block-1.C gcc/testsuite/g++.dg/gomp/block-1.C
> > index d2b8664..f4badaf 100644
> > --- gcc/testsuite/g++.dg/gomp/block-1.C
> > +++ gcc/testsuite/g++.dg/gomp/block-1.C
> > @@ -21,5 +21,5 @@ void foo()
> >      }
> >  }
> >  
> > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
> > diff --git gcc/testsuite/g++.dg/gomp/block-2.C gcc/testsuite/g++.dg/gomp/block-2.C
> > index 17d98d8..02f5f83d 100644
> > --- gcc/testsuite/g++.dg/gomp/block-2.C
> > +++ gcc/testsuite/g++.dg/gomp/block-2.C
> > @@ -31,5 +31,5 @@ void foo()
> >      continue;
> >  }
> >  
> > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
> > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 14 }
> >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
> > diff --git gcc/testsuite/g++.dg/gomp/block-3.C gcc/testsuite/g++.dg/gomp/block-3.C
> > index ff28175..bb54166 100644
> > --- gcc/testsuite/g++.dg/gomp/block-3.C
> > +++ gcc/testsuite/g++.dg/gomp/block-3.C
> > @@ -58,6 +58,6 @@ void foo()
> >      }
> >  }
> >  
> > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
> > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
> > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 21 }
> > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 26 }
> >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
> > diff --git gcc/testsuite/g++.dg/gomp/block-5.C gcc/testsuite/g++.dg/gomp/block-5.C
> > index 391f8b6..0aa23a4 100644
> > --- gcc/testsuite/g++.dg/gomp/block-5.C
> > +++ gcc/testsuite/g++.dg/gomp/block-5.C
> > @@ -14,4 +14,4 @@ void foo()
> >      }
> >  }
> >  
> > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > diff --git gcc/testsuite/g++.dg/gomp/target-1.C gcc/testsuite/g++.dg/gomp/target-1.C
> > index b6ed4f8..767661f 100644
> > --- gcc/testsuite/g++.dg/gomp/target-1.C
> > +++ gcc/testsuite/g++.dg/gomp/target-1.C
> > @@ -28,5 +28,5 @@ foo (int x)
> >    }
> >  }
> >  
> > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > diff --git gcc/testsuite/g++.dg/gomp/target-2.C gcc/testsuite/g++.dg/gomp/target-2.C
> > index 6a14f53..5a40dd4 100644
> > --- gcc/testsuite/g++.dg/gomp/target-2.C
> > +++ gcc/testsuite/g++.dg/gomp/target-2.C
> > @@ -28,5 +28,5 @@ foo (int x, int y)
> >    }
> >  }
> >  
> > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > diff --git gcc/testsuite/g++.dg/gomp/taskgroup-1.C gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > index dcab0bb..a06edf1 100644
> > --- gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > +++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > @@ -28,5 +28,5 @@ foo (int x)
> >    }
> >  }
> >  
> > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > diff --git gcc/testsuite/g++.dg/gomp/teams-1.C gcc/testsuite/g++.dg/gomp/teams-1.C
> > index ce40b55..05f1a7e 100644
> > --- gcc/testsuite/g++.dg/gomp/teams-1.C
> > +++ gcc/testsuite/g++.dg/gomp/teams-1.C
> > @@ -60,7 +60,7 @@ bar (int x)
> >    }
> >  }
> >  
> > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
> > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 37 }
> >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }
> > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > index 95e6b2d..6adabf4 100644
> > --- gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > @@ -11,7 +11,7 @@ void foo()
> >      {
> >        a[i] = b[i];
> >        if (c == 5)
> > -	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> >      }
> >  }
> >  
> > @@ -31,7 +31,7 @@ void baz()
> >  {
> >    bad1:
> >    #pragma omp parallel
> > -    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > +    goto bad1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
> >  
> >    goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> >    #pragma omp parallel
> > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump.c gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > index 9ec3293..1ca886a 100644
> > --- gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > +++ gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > @@ -10,7 +10,7 @@ void foo()
> >      {
> >        a[i] = b[i];
> >        if (c == 5)
> > -	return;	 /* { dg-error "invalid branch to.from a Cilk" } */
> > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> >      }
> >  }
> >  
> > @@ -23,5 +23,5 @@ void bar()
> >        a[i] = b[i];
> >      }
> >    if (c == 6)
> > -    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
> > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-1.c gcc/testsuite/gcc.dg/gomp/block-1.c
> > index dd7fe77..e67e6c3 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-1.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-1.c
> > @@ -4,9 +4,9 @@ void foo()
> >  {
> >    bad1:
> >    #pragma omp parallel
> > -    goto bad1;			// { dg-error "invalid branch" }
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			// { dg-error "invalid entry" }
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp parallel
> >      {
> >        bad2: ;
> > diff --git gcc/testsuite/gcc.dg/gomp/block-10.c gcc/testsuite/gcc.dg/gomp/block-10.c
> > index 76ee397..69ae3c0 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-10.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-10.c
> > @@ -3,28 +3,28 @@
> >  void foo(int i)
> >  {
> >    int j;
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp parallel
> >      { case 0:; }
> >    }
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp for
> >      for (j = 0; j < 10; ++ j)
> >        { case 1:; }
> >    }
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp critical
> >      { case 2:; }
> >    }
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp master
> >      { case 3:; }
> >    }
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp sections
> >      { case 4:;
> > @@ -32,7 +32,7 @@ void foo(int i)
> >         { case 5:; }
> >      }
> >    }
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp ordered
> >      { default:; }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-2.c gcc/testsuite/gcc.dg/gomp/block-2.c
> > index 4c56add..5c01463 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-2.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-2.c
> > @@ -11,9 +11,9 @@ void foo()
> >    bad1:
> >    #pragma omp for
> >    for (i = 0; i < 10; ++i)
> > -    goto bad1;			// { dg-error "invalid branch" }
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			// { dg-error "invalid entry" }
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp for
> >    for (i = 0; i < 10; ++i)
> >      {
> > diff --git gcc/testsuite/gcc.dg/gomp/block-3.c gcc/testsuite/gcc.dg/gomp/block-3.c
> > index b4530e9..3be15fb 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-3.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-3.c
> > @@ -18,16 +18,16 @@ void foo()
> >      #pragma omp section
> >        { bad1: ; }
> >      #pragma omp section
> > -      goto bad1;		// { dg-error "invalid branch" }
> > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >  
> >    #pragma omp sections
> >      {
> > -      goto bad2;		// { dg-error "invalid branch" }
> > +      goto bad2; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >    bad2:;
> >  
> > -  goto bad3;			// { dg-error "invalid entry" }
> > +  goto bad3; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp sections
> >      {
> >        bad3: ;
> > diff --git gcc/testsuite/gcc.dg/gomp/block-4.c gcc/testsuite/gcc.dg/gomp/block-4.c
> > index 61f490c..b2ef9b1 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-4.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-4.c
> > @@ -4,6 +4,6 @@ void foo()
> >  {
> >    #pragma omp critical
> >      {
> > -      return;		// { dg-error "invalid branch" }
> > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-5.c gcc/testsuite/gcc.dg/gomp/block-5.c
> > index 741049f..7f3b37c 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-5.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-5.c
> > @@ -4,12 +4,12 @@ void foo()
> >  {
> >    #pragma omp master
> >      {
> > -      goto bad1;	// { dg-error "invalid branch" }
> > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >  
> >    #pragma omp master
> >      {
> >      bad1:
> > -      return;		// { dg-error "invalid branch" }
> > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-6.c gcc/testsuite/gcc.dg/gomp/block-6.c
> > index 87e6392..fc9fdc8 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-6.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-6.c
> > @@ -4,6 +4,6 @@ void foo()
> >  {
> >    #pragma omp ordered
> >      {
> > -      return;		// { dg-error "invalid branch" }
> > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> >      }
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-7.c gcc/testsuite/gcc.dg/gomp/block-7.c
> > index 2bc1cdb..6219e7e 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-7.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-7.c
> > @@ -6,15 +6,15 @@ void foo()
> >    for (i = 0; i < 10; ++i)
> >      {
> >        #pragma omp for
> > -      for (j = ({ continue; 0; });	// { dg-error "invalid branch" }
> > -	   j < ({ continue; 10; });	// { dg-error "invalid branch" }
> > -	   j += ({ continue; 1; }))	// { dg-error "invalid branch" }
> > +      for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > +	   j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > +	   j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> >  	continue;
> >  
> >        #pragma omp for
> > -      for (j = ({ break; 0; });		// { dg-error "invalid branch" }
> > -	   j < ({ break; 10; });	// { dg-error "invalid branch" }
> > -	   j += ({ break; 1; }))	// { dg-error "invalid branch" }
> > +      for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > +	   j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > +	   j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> >  	break;				// { dg-error "break" }
> >      }
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-8.c gcc/testsuite/gcc.dg/gomp/block-8.c
> > index 3c717d9..f410070 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-8.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-8.c
> > @@ -7,5 +7,5 @@ int foo()
> >  
> >    #pragma omp parallel for
> >    for (i = 0; i < 10; ++i)
> > -    return 0;			// { dg-error "invalid branch" }
> > +    return 0; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  }
> > diff --git gcc/testsuite/gcc.dg/gomp/block-9.c gcc/testsuite/gcc.dg/gomp/block-9.c
> > index 9217cb7..2fae3de 100644
> > --- gcc/testsuite/gcc.dg/gomp/block-9.c
> > +++ gcc/testsuite/gcc.dg/gomp/block-9.c
> > @@ -3,7 +3,7 @@
> >  void foo(int i)
> >  {
> >    int j;
> > -  switch (i)			// { dg-error "invalid entry" }
> > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp parallel
> >      { case 0:; }
> > diff --git gcc/testsuite/gcc.dg/gomp/target-1.c gcc/testsuite/gcc.dg/gomp/target-1.c
> > index 09e65bd..aaa6a14 100644
> > --- gcc/testsuite/gcc.dg/gomp/target-1.c
> > +++ gcc/testsuite/gcc.dg/gomp/target-1.c
> > @@ -5,9 +5,9 @@ foo (int x)
> >  {
> >    bad1:
> >    #pragma omp target
> > -    goto bad1;			/* { dg-error "invalid branch" } */
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			/* { dg-error "invalid entry" } */
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp target
> >      {
> >        bad2: ;
> > @@ -21,7 +21,7 @@ foo (int x)
> >  	{ ok1: break; }
> >      }
> >  
> > -  switch (x)			/* { dg-error "invalid entry" } */
> > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp target
> >      { case 0:; }
> > diff --git gcc/testsuite/gcc.dg/gomp/target-2.c gcc/testsuite/gcc.dg/gomp/target-2.c
> > index 546a1d0..3a7afc4 100644
> > --- gcc/testsuite/gcc.dg/gomp/target-2.c
> > +++ gcc/testsuite/gcc.dg/gomp/target-2.c
> > @@ -5,9 +5,9 @@ foo (int x, int y)
> >  {
> >    bad1:
> >    #pragma omp target data map(tofrom: y)
> > -    goto bad1;			/* { dg-error "invalid branch" } */
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			/* { dg-error "invalid entry" } */
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp target data map(tofrom: y)
> >      {
> >        bad2: ;
> > @@ -21,7 +21,7 @@ foo (int x, int y)
> >  	{ ok1: break; }
> >      }
> >  
> > -  switch (x)			/* { dg-error "invalid entry" } */
> > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp target data map(tofrom: y)
> >      { case 0:; }
> > diff --git gcc/testsuite/gcc.dg/gomp/taskgroup-1.c gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > index e301efc..1997e0c 100644
> > --- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > +++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > @@ -5,9 +5,9 @@ foo (int x)
> >  {
> >    bad1:
> >    #pragma omp taskgroup
> > -    goto bad1;			/* { dg-error "invalid branch" } */
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			/* { dg-error "invalid entry" } */
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp taskgroup
> >      {
> >        bad2: ;
> > @@ -21,7 +21,7 @@ foo (int x)
> >  	{ ok1: break; }
> >      }
> >  
> > -  switch (x)			/* { dg-error "invalid entry" } */
> > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp taskgroup
> >      { case 0:; }
> > diff --git gcc/testsuite/gcc.dg/gomp/teams-1.c gcc/testsuite/gcc.dg/gomp/teams-1.c
> > index 73c00de..ad5b100 100644
> > --- gcc/testsuite/gcc.dg/gomp/teams-1.c
> > +++ gcc/testsuite/gcc.dg/gomp/teams-1.c
> > @@ -5,9 +5,9 @@ foo (int x)
> >  {
> >    bad1:
> >    #pragma omp target teams
> > -    goto bad1;			/* { dg-error "invalid branch" } */
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			/* { dg-error "invalid entry" } */
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp target teams
> >      {
> >        bad2: ;
> > @@ -21,7 +21,7 @@ foo (int x)
> >  	{ ok1: break; }
> >      }
> >  
> > -  switch (x)			/* { dg-error "invalid entry" } */
> > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp target teams
> >      { case 0:; }
> > @@ -34,9 +34,9 @@ bar (int x)
> >    bad1:
> >    #pragma omp target
> >    #pragma omp teams
> > -    goto bad1;			/* { dg-error "invalid branch" } */
> > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> >  
> > -  goto bad2;			/* { dg-error "invalid entry" } */
> > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> >    #pragma omp target
> >    #pragma omp teams
> >      {
> > @@ -52,7 +52,7 @@ bar (int x)
> >  	{ ok1: break; }
> >      }
> >  
> > -  switch (x)			/* { dg-error "invalid entry" } */
> > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> >    {
> >    #pragma omp target
> >    #pragma omp teams


> OpenACC structured blocks; OK for gomp-4_0-branch?
> 
> commit 58c24ac3e22a5b050227c44e97faf478f8b9f591
> Author: Thomas Schwinge <thomas@codesourcery.com>
> Date:   Tue Dec 10 13:10:24 2013 +0100
> 
>     OpenACC parallel structured blocks.
>     
>     	gcc/
>     	* gcc/omp-low.c (diagnose_sb_0, diagnose_sb_1, diagnose_sb_2):
>     	Handle GIMPLE_OACC_PARALLEL.
>     	* gimplify.c (gimplify_case_label_expr): Update comment.
>     	gcc/testsuite/
>     	* gcc.dg/goacc/parallel-sb-1.c: New file.
>     	* gcc.dg/goacc/parallel-sb-2.c: Likewise.
> 
> diff --git gcc/c/c-parser.c gcc/c/c-parser.c
> index ce46f31..e73379e 100644
> --- gcc/c/c-parser.c
> +++ gcc/c/c-parser.c
> @@ -11007,6 +11007,7 @@ c_parser_omp_structured_block (c_parser *parser)
>  
>  /* OpenACC 2.0:
>     # pragma acc parallel oacc-parallel-clause[optseq] new-line
> +     structured-block
>  
>     LOC is the location of the #pragma token.
>  */
> diff --git gcc/gimplify.c gcc/gimplify.c
> index e45bed2..db0dafe 100644
> --- gcc/gimplify.c
> +++ gcc/gimplify.c
> @@ -1479,9 +1479,10 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
>    struct gimplify_ctx *ctxp;
>    gimple gimple_label;
>  
> -  /* Invalid OpenMP programs can play Duff's Device type games with
> +  /* Invalid programs can play Duff's Device type games with, for example,
>       #pragma omp parallel.  At least in the C front end, we don't
> -     detect such invalid branches until after gimplification.  */
> +     detect such invalid branches until after gimplification, in the
> +     diagnose_omp_blocks pass.  */
>    for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
>      if (ctxp->case_labels.exists ())
>        break;
> diff --git gcc/omp-low.c gcc/omp-low.c
> index f55a1ea..e636545 100644
> --- gcc/omp-low.c
> +++ gcc/omp-low.c
> @@ -10806,7 +10806,7 @@ make_pass_lower_omp (gcc::context *ctxt)
>    return new pass_lower_omp (ctxt);
>  }
>  
> -/* The following is a utility to diagnose OpenMP structured block violations.
> +/* The following is a utility to diagnose structured block violations.
>     It is not part of the "omplower" pass, as that's invoked too late.  It
>     should be invoked by the respective front ends after gimplification.  */
>  
> @@ -10834,6 +10834,15 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
>  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
>  	kind = "Cilk Plus";
>      }
> +  if (flag_openacc)
> +    {
> +      if ((branch_ctx && gimple_code (branch_ctx) == GIMPLE_OACC_PARALLEL)
> +	  || (label_ctx && gimple_code (label_ctx) == GIMPLE_OACC_PARALLEL))
> +	{
> +	  gcc_assert (kind == NULL);
> +	  kind = "OpenACC";
> +	}
> +    }
>    if (kind == NULL)
>      {
>        gcc_assert (flag_openmp);
> @@ -10889,7 +10898,7 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
>    return true;
>  }
>  
> -/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
> +/* Pass 1: Create a minimal tree of structured blocks, and record
>     where each label is found.  */
>  
>  static tree
> @@ -10902,10 +10911,11 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
>  
>    *handled_ops_p = true;
>  
> - switch (gimple_code (stmt))
> +  switch (gimple_code (stmt))
>      {
>      WALK_SUBSTMTS;
>  
> +    case GIMPLE_OACC_PARALLEL:
>      case GIMPLE_OMP_PARALLEL:
>      case GIMPLE_OMP_TASK:
>      case GIMPLE_OMP_SECTIONS:
> @@ -10917,7 +10927,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
>      case GIMPLE_OMP_TARGET:
>      case GIMPLE_OMP_TEAMS:
>      case GIMPLE_OMP_TASKGROUP:
> -      /* The minimal context here is just the current OMP construct.  */
> +      /* The minimal context here is just the current construct.  */
>        inner_context = stmt;
>        wi->info = inner_context;
>        walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
> @@ -10964,6 +10974,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
>      {
>      WALK_SUBSTMTS;
>  
> +    case GIMPLE_OACC_PARALLEL:
>      case GIMPLE_OMP_PARALLEL:
>      case GIMPLE_OMP_TASK:
>      case GIMPLE_OMP_SECTIONS:
> @@ -11046,8 +11057,8 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
>    return NULL_TREE;
>  }
>  
> -/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
> -   codes.  */
> +/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
> +   GIMPLE codes.  */
>  bool
>  make_gimple_omp_edges (basic_block bb, struct omp_region **region)
>  {
> diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> new file mode 100644
> index 0000000..3909916
> --- /dev/null
> +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> @@ -0,0 +1,22 @@
> +// { dg-do compile }
> +
> +void foo()
> +{
> +  bad1:
> +  #pragma acc parallel
> +    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
> +
> +  goto bad2; // { dg-error "invalid entry to OpenACC structured block" }
> +  #pragma acc parallel
> +    {
> +      bad2: ;
> +    }
> +
> +  #pragma acc parallel
> +    {
> +      int i;
> +      goto ok1;
> +      for (i = 0; i < 10; ++i)
> +	{ ok1: break; }
> +    }
> +}
> diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> new file mode 100644
> index 0000000..aede042
> --- /dev/null
> +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> @@ -0,0 +1,10 @@
> +// { dg-do compile }
> +
> +void foo(int i)
> +{
> +  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
> +  {
> +  #pragma acc parallel
> +    { case 0:; }
> +  }
> +}


Grüße,
 Thomas
Thomas Schwinge Jan. 10, 2014, 11:48 a.m. UTC | #2
Hi!

Ping.

On Thu, 19 Dec 2013 17:49:09 +0100, I wrote:
> Ping.
> 
> On Tue, 10 Dec 2013 13:53:39 +0100, I wrote:
> > At the end of this email you can find the patch that I'd like to apply to
> > gomp-4_0-branch for OpenACC structured blocks, after the following two
> > have been approved:
> 
> > On Fri, 06 Dec 2013 19:33:35 +0100, I wrote:
> > > On Fri, 15 Nov 2013 14:44:45 -0700, Aldy Hernandez <aldyh@redhat.com> wrote:
> > > > --- a/gcc/omp-low.c
> > > > +++ b/gcc/omp-low.c
> > > > @@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >      error ("invalid entry to OpenMP structured block");
> > > >  #endif
> > > >  
> > > > +  bool cilkplus_block = false;
> > > > +  if (flag_enable_cilkplus)
> > > > +    {
> > > > +      if ((branch_ctx
> > > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > +	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > +	cilkplus_block = true;
> > > > +    }
> > > 
> > > There is one issue here: consider the following code:
> > > 
> > >     void baz()
> > >     {
> > >       bad1:
> > >       #pragma omp parallel
> > >         goto bad1;
> > >     }
> > > 
> > > Then, if both -fcilkplus and -fopenmp are specified, that will run into a
> > > SIGSEGV/ICE because of label_ctx == NULL.  The fix is simple enough; OK
> > > for trunk and gomp-4_0-branch (after full testing)?
> > 
> > Testing looks good.
> > 
> > > The testcase is
> > > basically a concatenation of gcc.dg/cilk-plus/jump.c and
> > > gcc.dg/gomp/block-1.c -- should this be done differently/better?
> > > 
> > > commit eee16f8aad4527b705d327476b00bf9f5ba6dcce
> > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > Date:   Fri Dec 6 18:55:41 2013 +0100
> > > 
> > >     Fix possible ICE (null pointer dereference) introduced in r204863.
> > >     
> > >     	gcc/
> > >     	* omp-low.c (diagnose_sb_0): Make sure label_ctx is valid to
> > >     	dereference.
> > >     	gcc/testsuite/
> > >     	* gcc.dg/cilk-plus/jump-openmp.c: New file.
> > > 
> > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > index e0f7d1d..91221c0 100644
> > > --- gcc/omp-low.c
> > > +++ gcc/omp-low.c
> > > @@ -10865,7 +10865,8 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >        if ((branch_ctx
> > >  	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > >  	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > -	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > +	  || (label_ctx
> > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > >  	cilkplus_block = true;
> > >      }
> > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > new file mode 100644
> > > index 0000000..95e6b2d
> > > --- /dev/null
> > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > @@ -0,0 +1,49 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-fcilkplus -fopenmp" } */
> > > +/* { dg-require-effective-target fopenmp } */
> > > +
> > > +int *a, *b, c;
> > > +
> > > +void foo()
> > > +{
> > > +#pragma simd
> > > +  for (int i=0; i < 1000; ++i)
> > > +    {
> > > +      a[i] = b[i];
> > > +      if (c == 5)
> > > +	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > +    }
> > > +}
> > > +
> > > +void bar()
> > > +{
> > > +#pragma simd
> > > +  for (int i=0; i < 1000; ++i)
> > > +    {
> > > +    lab:
> > > +      a[i] = b[i];
> > > +    }
> > > +  if (c == 6)
> > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > > +}
> > > +
> > > +void baz()
> > > +{
> > > +  bad1:
> > > +  #pragma omp parallel
> > > +    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > +
> > > +  goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > > +  #pragma omp parallel
> > > +    {
> > > +      bad2: ;
> > > +    }
> > > +
> > > +  #pragma omp parallel
> > > +    {
> > > +      int i;
> > > +      goto ok1;
> > > +      for (i = 0; i < 10; ++i)
> > > +	{ ok1: break; }
> > > +    }
> > > +}
> > > 
> > > 
> > > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > > >    if (branch_ctx == NULL)
> > > > -    error ("invalid entry to OpenMP structured block");
> > > > +    {
> > > > +      if (cilkplus_block)
> > > > +	error ("invalid entry to Cilk Plus structured block");
> > > > +      else
> > > > +	error ("invalid entry to OpenMP structured block");
> > > > +    }
> > > >    else
> > > > -    /* Otherwise, be vague and lazy, but efficient.  */
> > > > -    error ("invalid branch to/from an OpenMP structured block");
> > > > +    {
> > > > +      /* Otherwise, be vague and lazy, but efficient.  */
> > > > +      if (cilkplus_block)
> > > > +	error ("invalid branch to/from a Cilk Plus structured block");
> > > > +      else
> > > > +	error ("invalid branch to/from an OpenMP structured block");
> > > > +    }
> 
> > > In fact, and keeping in mind that we're currently adding OpenACC support,
> > > I'd suggest to do this differently; OK for trunk and gomp-4_0-branch?
> > 
> > Testing looks good.
> > 
> > > commit 367dabfcc94a3e96d63b48c38d0dd94ca9f517f8
> > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > Date:   Fri Dec 6 19:23:47 2013 +0100
> > > 
> > >     Generalize diagnose_omp_blocks' structured block logic.
> > >     
> > >     	gcc/
> > >     	* omp-low.c (diagnose_sb_0): Generalize detection which kind of
> > >     	structured block we're in.
> > >     	gcc/testsuite/
> > >     	* g++.dg/gomp/block-1.C: Adjust to changed error message and/or
> > >     	be tighten matching rules.
> > >     	* g++.dg/gomp/block-2.C: Likewise.
> > >     	* g++.dg/gomp/block-3.C: Likewise.
> > >     	* g++.dg/gomp/block-5.C: Likewise.
> > >     	* g++.dg/gomp/target-1.C: Likewise.
> > >     	* g++.dg/gomp/target-2.C: Likewise.
> > >     	* g++.dg/gomp/taskgroup-1.C: Likewise.
> > >     	* g++.dg/gomp/teams-1.C: Likewise.
> > >     	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
> > >     	* gcc.dg/cilk-plus/jump.c: Likewise.
> > >     	* gcc.dg/gomp/block-1.c: Likewise.
> > >     	* gcc.dg/gomp/block-10.c: Likewise.
> > >     	* gcc.dg/gomp/block-2.c: Likewise.
> > >     	* gcc.dg/gomp/block-3.c: Likewise.
> > >     	* gcc.dg/gomp/block-4.c: Likewise.
> > >     	* gcc.dg/gomp/block-5.c: Likewise.
> > >     	* gcc.dg/gomp/block-6.c: Likewise.
> > >     	* gcc.dg/gomp/block-7.c: Likewise.
> > >     	* gcc.dg/gomp/block-8.c: Likewise.
> > >     	* gcc.dg/gomp/block-9.c: Likewise.
> > >     	* gcc.dg/gomp/target-1.c: Likewise.
> > >     	* gcc.dg/gomp/target-2.c: Likewise.
> > >     	* gcc.dg/gomp/taskgroup-1.c: Likewise.
> > >     	* gcc.dg/gomp/teams-1.c: Likewise.
> > > 
> > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > index 91221c0..f55a1ea 100644
> > > --- gcc/omp-low.c
> > > +++ gcc/omp-low.c
> > > @@ -10822,6 +10822,23 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >    if (label_ctx == branch_ctx)
> > >      return false;
> > >  
> > > +  const char* kind = NULL;
> > > +
> > > +  if (flag_enable_cilkplus)
> > > +    {
> > > +      if ((branch_ctx
> > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > +	  || (label_ctx
> > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > +	kind = "Cilk Plus";
> > > +    }
> > > +  if (kind == NULL)
> > > +    {
> > > +      gcc_assert (flag_openmp);
> > > +      kind = "OpenMP";
> > > +    }
> > >  
> > >    /*
> > >       Previously we kept track of the label's entire context in diagnose_sb_[12]
> > > @@ -10854,38 +10871,18 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >      }
> > >  
> > >    if (exit_p)
> > > -    error ("invalid exit from OpenMP structured block");
> > > +    error ("invalid exit from %s structured block", kind);
> > >    else
> > > -    error ("invalid entry to OpenMP structured block");
> > > +    error ("invalid entry to %s structured block", kind);
> > >  #endif
> > >  
> > > -  bool cilkplus_block = false;
> > > -  if (flag_enable_cilkplus)
> > > -    {
> > > -      if ((branch_ctx
> > > -	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > -	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > -	  || (label_ctx
> > > -	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > -	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > -	cilkplus_block = true;
> > > -    }
> > > -
> > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > >    if (branch_ctx == NULL)
> > > -    {
> > > -      if (cilkplus_block)
> > > -	error ("invalid entry to Cilk Plus structured block");
> > > -      else
> > > -	error ("invalid entry to OpenMP structured block");
> > > -    }
> > > +    error ("invalid entry to %s structured block", kind);
> > >    else
> > >      {
> > >        /* Otherwise, be vague and lazy, but efficient.  */
> > > -      if (cilkplus_block)
> > > -	error ("invalid branch to/from a Cilk Plus structured block");
> > > -      else
> > > -	error ("invalid branch to/from an OpenMP structured block");
> > > +      error ("invalid branch to/from %s structured block", kind);
> > >      }
> > >  
> > >    gsi_replace (gsi_p, gimple_build_nop (), false);
> > > diff --git gcc/testsuite/g++.dg/gomp/block-1.C gcc/testsuite/g++.dg/gomp/block-1.C
> > > index d2b8664..f4badaf 100644
> > > --- gcc/testsuite/g++.dg/gomp/block-1.C
> > > +++ gcc/testsuite/g++.dg/gomp/block-1.C
> > > @@ -21,5 +21,5 @@ void foo()
> > >      }
> > >  }
> > >  
> > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
> > > diff --git gcc/testsuite/g++.dg/gomp/block-2.C gcc/testsuite/g++.dg/gomp/block-2.C
> > > index 17d98d8..02f5f83d 100644
> > > --- gcc/testsuite/g++.dg/gomp/block-2.C
> > > +++ gcc/testsuite/g++.dg/gomp/block-2.C
> > > @@ -31,5 +31,5 @@ void foo()
> > >      continue;
> > >  }
> > >  
> > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
> > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 14 }
> > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
> > > diff --git gcc/testsuite/g++.dg/gomp/block-3.C gcc/testsuite/g++.dg/gomp/block-3.C
> > > index ff28175..bb54166 100644
> > > --- gcc/testsuite/g++.dg/gomp/block-3.C
> > > +++ gcc/testsuite/g++.dg/gomp/block-3.C
> > > @@ -58,6 +58,6 @@ void foo()
> > >      }
> > >  }
> > >  
> > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
> > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
> > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 21 }
> > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 26 }
> > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
> > > diff --git gcc/testsuite/g++.dg/gomp/block-5.C gcc/testsuite/g++.dg/gomp/block-5.C
> > > index 391f8b6..0aa23a4 100644
> > > --- gcc/testsuite/g++.dg/gomp/block-5.C
> > > +++ gcc/testsuite/g++.dg/gomp/block-5.C
> > > @@ -14,4 +14,4 @@ void foo()
> > >      }
> > >  }
> > >  
> > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > > diff --git gcc/testsuite/g++.dg/gomp/target-1.C gcc/testsuite/g++.dg/gomp/target-1.C
> > > index b6ed4f8..767661f 100644
> > > --- gcc/testsuite/g++.dg/gomp/target-1.C
> > > +++ gcc/testsuite/g++.dg/gomp/target-1.C
> > > @@ -28,5 +28,5 @@ foo (int x)
> > >    }
> > >  }
> > >  
> > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > diff --git gcc/testsuite/g++.dg/gomp/target-2.C gcc/testsuite/g++.dg/gomp/target-2.C
> > > index 6a14f53..5a40dd4 100644
> > > --- gcc/testsuite/g++.dg/gomp/target-2.C
> > > +++ gcc/testsuite/g++.dg/gomp/target-2.C
> > > @@ -28,5 +28,5 @@ foo (int x, int y)
> > >    }
> > >  }
> > >  
> > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > diff --git gcc/testsuite/g++.dg/gomp/taskgroup-1.C gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > index dcab0bb..a06edf1 100644
> > > --- gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > +++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > @@ -28,5 +28,5 @@ foo (int x)
> > >    }
> > >  }
> > >  
> > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > diff --git gcc/testsuite/g++.dg/gomp/teams-1.C gcc/testsuite/g++.dg/gomp/teams-1.C
> > > index ce40b55..05f1a7e 100644
> > > --- gcc/testsuite/g++.dg/gomp/teams-1.C
> > > +++ gcc/testsuite/g++.dg/gomp/teams-1.C
> > > @@ -60,7 +60,7 @@ bar (int x)
> > >    }
> > >  }
> > >  
> > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
> > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 37 }
> > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }
> > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > index 95e6b2d..6adabf4 100644
> > > --- gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > @@ -11,7 +11,7 @@ void foo()
> > >      {
> > >        a[i] = b[i];
> > >        if (c == 5)
> > > -	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > >      }
> > >  }
> > >  
> > > @@ -31,7 +31,7 @@ void baz()
> > >  {
> > >    bad1:
> > >    #pragma omp parallel
> > > -    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > +    goto bad1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
> > >  
> > >    goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > >    #pragma omp parallel
> > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump.c gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > index 9ec3293..1ca886a 100644
> > > --- gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > @@ -10,7 +10,7 @@ void foo()
> > >      {
> > >        a[i] = b[i];
> > >        if (c == 5)
> > > -	return;	 /* { dg-error "invalid branch to.from a Cilk" } */
> > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > >      }
> > >  }
> > >  
> > > @@ -23,5 +23,5 @@ void bar()
> > >        a[i] = b[i];
> > >      }
> > >    if (c == 6)
> > > -    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
> > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-1.c gcc/testsuite/gcc.dg/gomp/block-1.c
> > > index dd7fe77..e67e6c3 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-1.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-1.c
> > > @@ -4,9 +4,9 @@ void foo()
> > >  {
> > >    bad1:
> > >    #pragma omp parallel
> > > -    goto bad1;			// { dg-error "invalid branch" }
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			// { dg-error "invalid entry" }
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp parallel
> > >      {
> > >        bad2: ;
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-10.c gcc/testsuite/gcc.dg/gomp/block-10.c
> > > index 76ee397..69ae3c0 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-10.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-10.c
> > > @@ -3,28 +3,28 @@
> > >  void foo(int i)
> > >  {
> > >    int j;
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp parallel
> > >      { case 0:; }
> > >    }
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp for
> > >      for (j = 0; j < 10; ++ j)
> > >        { case 1:; }
> > >    }
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp critical
> > >      { case 2:; }
> > >    }
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp master
> > >      { case 3:; }
> > >    }
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp sections
> > >      { case 4:;
> > > @@ -32,7 +32,7 @@ void foo(int i)
> > >         { case 5:; }
> > >      }
> > >    }
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp ordered
> > >      { default:; }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-2.c gcc/testsuite/gcc.dg/gomp/block-2.c
> > > index 4c56add..5c01463 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-2.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-2.c
> > > @@ -11,9 +11,9 @@ void foo()
> > >    bad1:
> > >    #pragma omp for
> > >    for (i = 0; i < 10; ++i)
> > > -    goto bad1;			// { dg-error "invalid branch" }
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			// { dg-error "invalid entry" }
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp for
> > >    for (i = 0; i < 10; ++i)
> > >      {
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-3.c gcc/testsuite/gcc.dg/gomp/block-3.c
> > > index b4530e9..3be15fb 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-3.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-3.c
> > > @@ -18,16 +18,16 @@ void foo()
> > >      #pragma omp section
> > >        { bad1: ; }
> > >      #pragma omp section
> > > -      goto bad1;		// { dg-error "invalid branch" }
> > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >  
> > >    #pragma omp sections
> > >      {
> > > -      goto bad2;		// { dg-error "invalid branch" }
> > > +      goto bad2; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >    bad2:;
> > >  
> > > -  goto bad3;			// { dg-error "invalid entry" }
> > > +  goto bad3; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp sections
> > >      {
> > >        bad3: ;
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-4.c gcc/testsuite/gcc.dg/gomp/block-4.c
> > > index 61f490c..b2ef9b1 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-4.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-4.c
> > > @@ -4,6 +4,6 @@ void foo()
> > >  {
> > >    #pragma omp critical
> > >      {
> > > -      return;		// { dg-error "invalid branch" }
> > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-5.c gcc/testsuite/gcc.dg/gomp/block-5.c
> > > index 741049f..7f3b37c 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-5.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-5.c
> > > @@ -4,12 +4,12 @@ void foo()
> > >  {
> > >    #pragma omp master
> > >      {
> > > -      goto bad1;	// { dg-error "invalid branch" }
> > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >  
> > >    #pragma omp master
> > >      {
> > >      bad1:
> > > -      return;		// { dg-error "invalid branch" }
> > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-6.c gcc/testsuite/gcc.dg/gomp/block-6.c
> > > index 87e6392..fc9fdc8 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-6.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-6.c
> > > @@ -4,6 +4,6 @@ void foo()
> > >  {
> > >    #pragma omp ordered
> > >      {
> > > -      return;		// { dg-error "invalid branch" }
> > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >      }
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-7.c gcc/testsuite/gcc.dg/gomp/block-7.c
> > > index 2bc1cdb..6219e7e 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-7.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-7.c
> > > @@ -6,15 +6,15 @@ void foo()
> > >    for (i = 0; i < 10; ++i)
> > >      {
> > >        #pragma omp for
> > > -      for (j = ({ continue; 0; });	// { dg-error "invalid branch" }
> > > -	   j < ({ continue; 10; });	// { dg-error "invalid branch" }
> > > -	   j += ({ continue; 1; }))	// { dg-error "invalid branch" }
> > > +      for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > +	   j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > +	   j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  	continue;
> > >  
> > >        #pragma omp for
> > > -      for (j = ({ break; 0; });		// { dg-error "invalid branch" }
> > > -	   j < ({ break; 10; });	// { dg-error "invalid branch" }
> > > -	   j += ({ break; 1; }))	// { dg-error "invalid branch" }
> > > +      for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > +	   j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > +	   j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  	break;				// { dg-error "break" }
> > >      }
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-8.c gcc/testsuite/gcc.dg/gomp/block-8.c
> > > index 3c717d9..f410070 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-8.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-8.c
> > > @@ -7,5 +7,5 @@ int foo()
> > >  
> > >    #pragma omp parallel for
> > >    for (i = 0; i < 10; ++i)
> > > -    return 0;			// { dg-error "invalid branch" }
> > > +    return 0; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  }
> > > diff --git gcc/testsuite/gcc.dg/gomp/block-9.c gcc/testsuite/gcc.dg/gomp/block-9.c
> > > index 9217cb7..2fae3de 100644
> > > --- gcc/testsuite/gcc.dg/gomp/block-9.c
> > > +++ gcc/testsuite/gcc.dg/gomp/block-9.c
> > > @@ -3,7 +3,7 @@
> > >  void foo(int i)
> > >  {
> > >    int j;
> > > -  switch (i)			// { dg-error "invalid entry" }
> > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp parallel
> > >      { case 0:; }
> > > diff --git gcc/testsuite/gcc.dg/gomp/target-1.c gcc/testsuite/gcc.dg/gomp/target-1.c
> > > index 09e65bd..aaa6a14 100644
> > > --- gcc/testsuite/gcc.dg/gomp/target-1.c
> > > +++ gcc/testsuite/gcc.dg/gomp/target-1.c
> > > @@ -5,9 +5,9 @@ foo (int x)
> > >  {
> > >    bad1:
> > >    #pragma omp target
> > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp target
> > >      {
> > >        bad2: ;
> > > @@ -21,7 +21,7 @@ foo (int x)
> > >  	{ ok1: break; }
> > >      }
> > >  
> > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp target
> > >      { case 0:; }
> > > diff --git gcc/testsuite/gcc.dg/gomp/target-2.c gcc/testsuite/gcc.dg/gomp/target-2.c
> > > index 546a1d0..3a7afc4 100644
> > > --- gcc/testsuite/gcc.dg/gomp/target-2.c
> > > +++ gcc/testsuite/gcc.dg/gomp/target-2.c
> > > @@ -5,9 +5,9 @@ foo (int x, int y)
> > >  {
> > >    bad1:
> > >    #pragma omp target data map(tofrom: y)
> > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp target data map(tofrom: y)
> > >      {
> > >        bad2: ;
> > > @@ -21,7 +21,7 @@ foo (int x, int y)
> > >  	{ ok1: break; }
> > >      }
> > >  
> > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp target data map(tofrom: y)
> > >      { case 0:; }
> > > diff --git gcc/testsuite/gcc.dg/gomp/taskgroup-1.c gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > index e301efc..1997e0c 100644
> > > --- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > +++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > @@ -5,9 +5,9 @@ foo (int x)
> > >  {
> > >    bad1:
> > >    #pragma omp taskgroup
> > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp taskgroup
> > >      {
> > >        bad2: ;
> > > @@ -21,7 +21,7 @@ foo (int x)
> > >  	{ ok1: break; }
> > >      }
> > >  
> > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp taskgroup
> > >      { case 0:; }
> > > diff --git gcc/testsuite/gcc.dg/gomp/teams-1.c gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > index 73c00de..ad5b100 100644
> > > --- gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > +++ gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > @@ -5,9 +5,9 @@ foo (int x)
> > >  {
> > >    bad1:
> > >    #pragma omp target teams
> > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp target teams
> > >      {
> > >        bad2: ;
> > > @@ -21,7 +21,7 @@ foo (int x)
> > >  	{ ok1: break; }
> > >      }
> > >  
> > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp target teams
> > >      { case 0:; }
> > > @@ -34,9 +34,9 @@ bar (int x)
> > >    bad1:
> > >    #pragma omp target
> > >    #pragma omp teams
> > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > >  
> > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > >    #pragma omp target
> > >    #pragma omp teams
> > >      {
> > > @@ -52,7 +52,7 @@ bar (int x)
> > >  	{ ok1: break; }
> > >      }
> > >  
> > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > >    {
> > >    #pragma omp target
> > >    #pragma omp teams
> 
> 
> > OpenACC structured blocks; OK for gomp-4_0-branch?
> > 
> > commit 58c24ac3e22a5b050227c44e97faf478f8b9f591
> > Author: Thomas Schwinge <thomas@codesourcery.com>
> > Date:   Tue Dec 10 13:10:24 2013 +0100
> > 
> >     OpenACC parallel structured blocks.
> >     
> >     	gcc/
> >     	* gcc/omp-low.c (diagnose_sb_0, diagnose_sb_1, diagnose_sb_2):
> >     	Handle GIMPLE_OACC_PARALLEL.
> >     	* gimplify.c (gimplify_case_label_expr): Update comment.
> >     	gcc/testsuite/
> >     	* gcc.dg/goacc/parallel-sb-1.c: New file.
> >     	* gcc.dg/goacc/parallel-sb-2.c: Likewise.
> > 
> > diff --git gcc/c/c-parser.c gcc/c/c-parser.c
> > index ce46f31..e73379e 100644
> > --- gcc/c/c-parser.c
> > +++ gcc/c/c-parser.c
> > @@ -11007,6 +11007,7 @@ c_parser_omp_structured_block (c_parser *parser)
> >  
> >  /* OpenACC 2.0:
> >     # pragma acc parallel oacc-parallel-clause[optseq] new-line
> > +     structured-block
> >  
> >     LOC is the location of the #pragma token.
> >  */
> > diff --git gcc/gimplify.c gcc/gimplify.c
> > index e45bed2..db0dafe 100644
> > --- gcc/gimplify.c
> > +++ gcc/gimplify.c
> > @@ -1479,9 +1479,10 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
> >    struct gimplify_ctx *ctxp;
> >    gimple gimple_label;
> >  
> > -  /* Invalid OpenMP programs can play Duff's Device type games with
> > +  /* Invalid programs can play Duff's Device type games with, for example,
> >       #pragma omp parallel.  At least in the C front end, we don't
> > -     detect such invalid branches until after gimplification.  */
> > +     detect such invalid branches until after gimplification, in the
> > +     diagnose_omp_blocks pass.  */
> >    for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
> >      if (ctxp->case_labels.exists ())
> >        break;
> > diff --git gcc/omp-low.c gcc/omp-low.c
> > index f55a1ea..e636545 100644
> > --- gcc/omp-low.c
> > +++ gcc/omp-low.c
> > @@ -10806,7 +10806,7 @@ make_pass_lower_omp (gcc::context *ctxt)
> >    return new pass_lower_omp (ctxt);
> >  }
> >  
> > -/* The following is a utility to diagnose OpenMP structured block violations.
> > +/* The following is a utility to diagnose structured block violations.
> >     It is not part of the "omplower" pass, as that's invoked too late.  It
> >     should be invoked by the respective front ends after gimplification.  */
> >  
> > @@ -10834,6 +10834,15 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> >  	kind = "Cilk Plus";
> >      }
> > +  if (flag_openacc)
> > +    {
> > +      if ((branch_ctx && gimple_code (branch_ctx) == GIMPLE_OACC_PARALLEL)
> > +	  || (label_ctx && gimple_code (label_ctx) == GIMPLE_OACC_PARALLEL))
> > +	{
> > +	  gcc_assert (kind == NULL);
> > +	  kind = "OpenACC";
> > +	}
> > +    }
> >    if (kind == NULL)
> >      {
> >        gcc_assert (flag_openmp);
> > @@ -10889,7 +10898,7 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> >    return true;
> >  }
> >  
> > -/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
> > +/* Pass 1: Create a minimal tree of structured blocks, and record
> >     where each label is found.  */
> >  
> >  static tree
> > @@ -10902,10 +10911,11 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> >  
> >    *handled_ops_p = true;
> >  
> > - switch (gimple_code (stmt))
> > +  switch (gimple_code (stmt))
> >      {
> >      WALK_SUBSTMTS;
> >  
> > +    case GIMPLE_OACC_PARALLEL:
> >      case GIMPLE_OMP_PARALLEL:
> >      case GIMPLE_OMP_TASK:
> >      case GIMPLE_OMP_SECTIONS:
> > @@ -10917,7 +10927,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> >      case GIMPLE_OMP_TARGET:
> >      case GIMPLE_OMP_TEAMS:
> >      case GIMPLE_OMP_TASKGROUP:
> > -      /* The minimal context here is just the current OMP construct.  */
> > +      /* The minimal context here is just the current construct.  */
> >        inner_context = stmt;
> >        wi->info = inner_context;
> >        walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
> > @@ -10964,6 +10974,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> >      {
> >      WALK_SUBSTMTS;
> >  
> > +    case GIMPLE_OACC_PARALLEL:
> >      case GIMPLE_OMP_PARALLEL:
> >      case GIMPLE_OMP_TASK:
> >      case GIMPLE_OMP_SECTIONS:
> > @@ -11046,8 +11057,8 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> >    return NULL_TREE;
> >  }
> >  
> > -/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
> > -   codes.  */
> > +/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
> > +   GIMPLE codes.  */
> >  bool
> >  make_gimple_omp_edges (basic_block bb, struct omp_region **region)
> >  {
> > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > new file mode 100644
> > index 0000000..3909916
> > --- /dev/null
> > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > @@ -0,0 +1,22 @@
> > +// { dg-do compile }
> > +
> > +void foo()
> > +{
> > +  bad1:
> > +  #pragma acc parallel
> > +    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
> > +
> > +  goto bad2; // { dg-error "invalid entry to OpenACC structured block" }
> > +  #pragma acc parallel
> > +    {
> > +      bad2: ;
> > +    }
> > +
> > +  #pragma acc parallel
> > +    {
> > +      int i;
> > +      goto ok1;
> > +      for (i = 0; i < 10; ++i)
> > +	{ ok1: break; }
> > +    }
> > +}
> > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > new file mode 100644
> > index 0000000..aede042
> > --- /dev/null
> > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > @@ -0,0 +1,10 @@
> > +// { dg-do compile }
> > +
> > +void foo(int i)
> > +{
> > +  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
> > +  {
> > +  #pragma acc parallel
> > +    { case 0:; }
> > +  }
> > +}


Grüße,
 Thomas
Thomas Schwinge Jan. 24, 2014, 3:57 p.m. UTC | #3
Hi!

Ping.  With a different subject line, this time.  Let's first concentrate
on the ICE in the Cilk Plus structured block checker, then generalize
diagnose_omp_blocks' structured block logic, before finally getting to
the OpenACC extension.


Here starts the ICE patch:

On Fri, 10 Jan 2014 12:48:21 +0100, I wrote:
> Ping.
> 
> On Thu, 19 Dec 2013 17:49:09 +0100, I wrote:
> > Ping.
> > 
> > On Tue, 10 Dec 2013 13:53:39 +0100, I wrote:
> > > At the end of this email you can find the patch that I'd like to apply to
> > > gomp-4_0-branch for OpenACC structured blocks, after the following two
> > > have been approved:
> > 
> > > On Fri, 06 Dec 2013 19:33:35 +0100, I wrote:
> > > > On Fri, 15 Nov 2013 14:44:45 -0700, Aldy Hernandez <aldyh@redhat.com> wrote:
> > > > > --- a/gcc/omp-low.c
> > > > > +++ b/gcc/omp-low.c
> > > > > @@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > > >      error ("invalid entry to OpenMP structured block");
> > > > >  #endif
> > > > >  
> > > > > +  bool cilkplus_block = false;
> > > > > +  if (flag_enable_cilkplus)
> > > > > +    {
> > > > > +      if ((branch_ctx
> > > > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > > +	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > > +	cilkplus_block = true;
> > > > > +    }
> > > > 
> > > > There is one issue here: consider the following code:
> > > > 
> > > >     void baz()
> > > >     {
> > > >       bad1:
> > > >       #pragma omp parallel
> > > >         goto bad1;
> > > >     }
> > > > 
> > > > Then, if both -fcilkplus and -fopenmp are specified, that will run into a
> > > > SIGSEGV/ICE because of label_ctx == NULL.  The fix is simple enough; OK
> > > > for trunk and gomp-4_0-branch (after full testing)?
> > > 
> > > Testing looks good.
> > > 
> > > > The testcase is
> > > > basically a concatenation of gcc.dg/cilk-plus/jump.c and
> > > > gcc.dg/gomp/block-1.c -- should this be done differently/better?
> > > > 
> > > > commit eee16f8aad4527b705d327476b00bf9f5ba6dcce
> > > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > > Date:   Fri Dec 6 18:55:41 2013 +0100
> > > > 
> > > >     Fix possible ICE (null pointer dereference) introduced in r204863.
> > > >     
> > > >     	gcc/
> > > >     	* omp-low.c (diagnose_sb_0): Make sure label_ctx is valid to
> > > >     	dereference.
> > > >     	gcc/testsuite/
> > > >     	* gcc.dg/cilk-plus/jump-openmp.c: New file.
> > > > 
> > > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > > index e0f7d1d..91221c0 100644
> > > > --- gcc/omp-low.c
> > > > +++ gcc/omp-low.c
> > > > @@ -10865,7 +10865,8 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >        if ((branch_ctx
> > > >  	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > >  	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > -	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > +	  || (label_ctx
> > > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > >  	cilkplus_block = true;
> > > >      }
> > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > new file mode 100644
> > > > index 0000000..95e6b2d
> > > > --- /dev/null
> > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > @@ -0,0 +1,49 @@
> > > > +/* { dg-do compile } */
> > > > +/* { dg-options "-fcilkplus -fopenmp" } */
> > > > +/* { dg-require-effective-target fopenmp } */
> > > > +
> > > > +int *a, *b, c;
> > > > +
> > > > +void foo()
> > > > +{
> > > > +#pragma simd
> > > > +  for (int i=0; i < 1000; ++i)
> > > > +    {
> > > > +      a[i] = b[i];
> > > > +      if (c == 5)
> > > > +	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > > +    }
> > > > +}
> > > > +
> > > > +void bar()
> > > > +{
> > > > +#pragma simd
> > > > +  for (int i=0; i < 1000; ++i)
> > > > +    {
> > > > +    lab:
> > > > +      a[i] = b[i];
> > > > +    }
> > > > +  if (c == 6)
> > > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > > > +}
> > > > +
> > > > +void baz()
> > > > +{
> > > > +  bad1:
> > > > +  #pragma omp parallel
> > > > +    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > > +
> > > > +  goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > > > +  #pragma omp parallel
> > > > +    {
> > > > +      bad2: ;
> > > > +    }
> > > > +
> > > > +  #pragma omp parallel
> > > > +    {
> > > > +      int i;
> > > > +      goto ok1;
> > > > +      for (i = 0; i < 10; ++i)
> > > > +	{ ok1: break; }
> > > > +    }
> > > > +}


Here starts the patch to generalize diagnose_omp_blocks' structured block
logic (still not specific to OpenACC):

> > > > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > > > >    if (branch_ctx == NULL)
> > > > > -    error ("invalid entry to OpenMP structured block");
> > > > > +    {
> > > > > +      if (cilkplus_block)
> > > > > +	error ("invalid entry to Cilk Plus structured block");
> > > > > +      else
> > > > > +	error ("invalid entry to OpenMP structured block");
> > > > > +    }
> > > > >    else
> > > > > -    /* Otherwise, be vague and lazy, but efficient.  */
> > > > > -    error ("invalid branch to/from an OpenMP structured block");
> > > > > +    {
> > > > > +      /* Otherwise, be vague and lazy, but efficient.  */
> > > > > +      if (cilkplus_block)
> > > > > +	error ("invalid branch to/from a Cilk Plus structured block");
> > > > > +      else
> > > > > +	error ("invalid branch to/from an OpenMP structured block");
> > > > > +    }
> > 
> > > > In fact, and keeping in mind that we're currently adding OpenACC support,
> > > > I'd suggest to do this differently; OK for trunk and gomp-4_0-branch?
> > > 
> > > Testing looks good.
> > > 
> > > > commit 367dabfcc94a3e96d63b48c38d0dd94ca9f517f8
> > > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > > Date:   Fri Dec 6 19:23:47 2013 +0100
> > > > 
> > > >     Generalize diagnose_omp_blocks' structured block logic.
> > > >     
> > > >     	gcc/
> > > >     	* omp-low.c (diagnose_sb_0): Generalize detection which kind of
> > > >     	structured block we're in.
> > > >     	gcc/testsuite/
> > > >     	* g++.dg/gomp/block-1.C: Adjust to changed error message and/or
> > > >     	be tighten matching rules.
> > > >     	* g++.dg/gomp/block-2.C: Likewise.
> > > >     	* g++.dg/gomp/block-3.C: Likewise.
> > > >     	* g++.dg/gomp/block-5.C: Likewise.
> > > >     	* g++.dg/gomp/target-1.C: Likewise.
> > > >     	* g++.dg/gomp/target-2.C: Likewise.
> > > >     	* g++.dg/gomp/taskgroup-1.C: Likewise.
> > > >     	* g++.dg/gomp/teams-1.C: Likewise.
> > > >     	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
> > > >     	* gcc.dg/cilk-plus/jump.c: Likewise.
> > > >     	* gcc.dg/gomp/block-1.c: Likewise.
> > > >     	* gcc.dg/gomp/block-10.c: Likewise.
> > > >     	* gcc.dg/gomp/block-2.c: Likewise.
> > > >     	* gcc.dg/gomp/block-3.c: Likewise.
> > > >     	* gcc.dg/gomp/block-4.c: Likewise.
> > > >     	* gcc.dg/gomp/block-5.c: Likewise.
> > > >     	* gcc.dg/gomp/block-6.c: Likewise.
> > > >     	* gcc.dg/gomp/block-7.c: Likewise.
> > > >     	* gcc.dg/gomp/block-8.c: Likewise.
> > > >     	* gcc.dg/gomp/block-9.c: Likewise.
> > > >     	* gcc.dg/gomp/target-1.c: Likewise.
> > > >     	* gcc.dg/gomp/target-2.c: Likewise.
> > > >     	* gcc.dg/gomp/taskgroup-1.c: Likewise.
> > > >     	* gcc.dg/gomp/teams-1.c: Likewise.
> > > > 
> > > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > > index 91221c0..f55a1ea 100644
> > > > --- gcc/omp-low.c
> > > > +++ gcc/omp-low.c
> > > > @@ -10822,6 +10822,23 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >    if (label_ctx == branch_ctx)
> > > >      return false;
> > > >  
> > > > +  const char* kind = NULL;
> > > > +
> > > > +  if (flag_enable_cilkplus)
> > > > +    {
> > > > +      if ((branch_ctx
> > > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > +	  || (label_ctx
> > > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > +	kind = "Cilk Plus";
> > > > +    }
> > > > +  if (kind == NULL)
> > > > +    {
> > > > +      gcc_assert (flag_openmp);
> > > > +      kind = "OpenMP";
> > > > +    }
> > > >  
> > > >    /*
> > > >       Previously we kept track of the label's entire context in diagnose_sb_[12]
> > > > @@ -10854,38 +10871,18 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >      }
> > > >  
> > > >    if (exit_p)
> > > > -    error ("invalid exit from OpenMP structured block");
> > > > +    error ("invalid exit from %s structured block", kind);
> > > >    else
> > > > -    error ("invalid entry to OpenMP structured block");
> > > > +    error ("invalid entry to %s structured block", kind);
> > > >  #endif
> > > >  
> > > > -  bool cilkplus_block = false;
> > > > -  if (flag_enable_cilkplus)
> > > > -    {
> > > > -      if ((branch_ctx
> > > > -	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > -	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > -	  || (label_ctx
> > > > -	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > -	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > -	cilkplus_block = true;
> > > > -    }
> > > > -
> > > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > > >    if (branch_ctx == NULL)
> > > > -    {
> > > > -      if (cilkplus_block)
> > > > -	error ("invalid entry to Cilk Plus structured block");
> > > > -      else
> > > > -	error ("invalid entry to OpenMP structured block");
> > > > -    }
> > > > +    error ("invalid entry to %s structured block", kind);
> > > >    else
> > > >      {
> > > >        /* Otherwise, be vague and lazy, but efficient.  */
> > > > -      if (cilkplus_block)
> > > > -	error ("invalid branch to/from a Cilk Plus structured block");
> > > > -      else
> > > > -	error ("invalid branch to/from an OpenMP structured block");
> > > > +      error ("invalid branch to/from %s structured block", kind);
> > > >      }
> > > >  
> > > >    gsi_replace (gsi_p, gimple_build_nop (), false);
> > > > diff --git gcc/testsuite/g++.dg/gomp/block-1.C gcc/testsuite/g++.dg/gomp/block-1.C
> > > > index d2b8664..f4badaf 100644
> > > > --- gcc/testsuite/g++.dg/gomp/block-1.C
> > > > +++ gcc/testsuite/g++.dg/gomp/block-1.C
> > > > @@ -21,5 +21,5 @@ void foo()
> > > >      }
> > > >  }
> > > >  
> > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/block-2.C gcc/testsuite/g++.dg/gomp/block-2.C
> > > > index 17d98d8..02f5f83d 100644
> > > > --- gcc/testsuite/g++.dg/gomp/block-2.C
> > > > +++ gcc/testsuite/g++.dg/gomp/block-2.C
> > > > @@ -31,5 +31,5 @@ void foo()
> > > >      continue;
> > > >  }
> > > >  
> > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
> > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 14 }
> > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/block-3.C gcc/testsuite/g++.dg/gomp/block-3.C
> > > > index ff28175..bb54166 100644
> > > > --- gcc/testsuite/g++.dg/gomp/block-3.C
> > > > +++ gcc/testsuite/g++.dg/gomp/block-3.C
> > > > @@ -58,6 +58,6 @@ void foo()
> > > >      }
> > > >  }
> > > >  
> > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
> > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
> > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 21 }
> > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 26 }
> > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/block-5.C gcc/testsuite/g++.dg/gomp/block-5.C
> > > > index 391f8b6..0aa23a4 100644
> > > > --- gcc/testsuite/g++.dg/gomp/block-5.C
> > > > +++ gcc/testsuite/g++.dg/gomp/block-5.C
> > > > @@ -14,4 +14,4 @@ void foo()
> > > >      }
> > > >  }
> > > >  
> > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/target-1.C gcc/testsuite/g++.dg/gomp/target-1.C
> > > > index b6ed4f8..767661f 100644
> > > > --- gcc/testsuite/g++.dg/gomp/target-1.C
> > > > +++ gcc/testsuite/g++.dg/gomp/target-1.C
> > > > @@ -28,5 +28,5 @@ foo (int x)
> > > >    }
> > > >  }
> > > >  
> > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/target-2.C gcc/testsuite/g++.dg/gomp/target-2.C
> > > > index 6a14f53..5a40dd4 100644
> > > > --- gcc/testsuite/g++.dg/gomp/target-2.C
> > > > +++ gcc/testsuite/g++.dg/gomp/target-2.C
> > > > @@ -28,5 +28,5 @@ foo (int x, int y)
> > > >    }
> > > >  }
> > > >  
> > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/taskgroup-1.C gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > index dcab0bb..a06edf1 100644
> > > > --- gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > +++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > @@ -28,5 +28,5 @@ foo (int x)
> > > >    }
> > > >  }
> > > >  
> > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > diff --git gcc/testsuite/g++.dg/gomp/teams-1.C gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > index ce40b55..05f1a7e 100644
> > > > --- gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > +++ gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > @@ -60,7 +60,7 @@ bar (int x)
> > > >    }
> > > >  }
> > > >  
> > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
> > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 37 }
> > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }
> > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > index 95e6b2d..6adabf4 100644
> > > > --- gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > @@ -11,7 +11,7 @@ void foo()
> > > >      {
> > > >        a[i] = b[i];
> > > >        if (c == 5)
> > > > -	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > > >      }
> > > >  }
> > > >  
> > > > @@ -31,7 +31,7 @@ void baz()
> > > >  {
> > > >    bad1:
> > > >    #pragma omp parallel
> > > > -    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > > +    goto bad1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
> > > >  
> > > >    goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > > >    #pragma omp parallel
> > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump.c gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > index 9ec3293..1ca886a 100644
> > > > --- gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > @@ -10,7 +10,7 @@ void foo()
> > > >      {
> > > >        a[i] = b[i];
> > > >        if (c == 5)
> > > > -	return;	 /* { dg-error "invalid branch to.from a Cilk" } */
> > > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > > >      }
> > > >  }
> > > >  
> > > > @@ -23,5 +23,5 @@ void bar()
> > > >        a[i] = b[i];
> > > >      }
> > > >    if (c == 6)
> > > > -    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
> > > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-1.c gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > index dd7fe77..e67e6c3 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > @@ -4,9 +4,9 @@ void foo()
> > > >  {
> > > >    bad1:
> > > >    #pragma omp parallel
> > > > -    goto bad1;			// { dg-error "invalid branch" }
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			// { dg-error "invalid entry" }
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp parallel
> > > >      {
> > > >        bad2: ;
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-10.c gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > index 76ee397..69ae3c0 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > @@ -3,28 +3,28 @@
> > > >  void foo(int i)
> > > >  {
> > > >    int j;
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp parallel
> > > >      { case 0:; }
> > > >    }
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp for
> > > >      for (j = 0; j < 10; ++ j)
> > > >        { case 1:; }
> > > >    }
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp critical
> > > >      { case 2:; }
> > > >    }
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp master
> > > >      { case 3:; }
> > > >    }
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp sections
> > > >      { case 4:;
> > > > @@ -32,7 +32,7 @@ void foo(int i)
> > > >         { case 5:; }
> > > >      }
> > > >    }
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp ordered
> > > >      { default:; }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-2.c gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > index 4c56add..5c01463 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > @@ -11,9 +11,9 @@ void foo()
> > > >    bad1:
> > > >    #pragma omp for
> > > >    for (i = 0; i < 10; ++i)
> > > > -    goto bad1;			// { dg-error "invalid branch" }
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			// { dg-error "invalid entry" }
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp for
> > > >    for (i = 0; i < 10; ++i)
> > > >      {
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-3.c gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > index b4530e9..3be15fb 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > @@ -18,16 +18,16 @@ void foo()
> > > >      #pragma omp section
> > > >        { bad1: ; }
> > > >      #pragma omp section
> > > > -      goto bad1;		// { dg-error "invalid branch" }
> > > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >  
> > > >    #pragma omp sections
> > > >      {
> > > > -      goto bad2;		// { dg-error "invalid branch" }
> > > > +      goto bad2; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >    bad2:;
> > > >  
> > > > -  goto bad3;			// { dg-error "invalid entry" }
> > > > +  goto bad3; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp sections
> > > >      {
> > > >        bad3: ;
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-4.c gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > index 61f490c..b2ef9b1 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > @@ -4,6 +4,6 @@ void foo()
> > > >  {
> > > >    #pragma omp critical
> > > >      {
> > > > -      return;		// { dg-error "invalid branch" }
> > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-5.c gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > index 741049f..7f3b37c 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > @@ -4,12 +4,12 @@ void foo()
> > > >  {
> > > >    #pragma omp master
> > > >      {
> > > > -      goto bad1;	// { dg-error "invalid branch" }
> > > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >  
> > > >    #pragma omp master
> > > >      {
> > > >      bad1:
> > > > -      return;		// { dg-error "invalid branch" }
> > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-6.c gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > index 87e6392..fc9fdc8 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > @@ -4,6 +4,6 @@ void foo()
> > > >  {
> > > >    #pragma omp ordered
> > > >      {
> > > > -      return;		// { dg-error "invalid branch" }
> > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >      }
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-7.c gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > index 2bc1cdb..6219e7e 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > @@ -6,15 +6,15 @@ void foo()
> > > >    for (i = 0; i < 10; ++i)
> > > >      {
> > > >        #pragma omp for
> > > > -      for (j = ({ continue; 0; });	// { dg-error "invalid branch" }
> > > > -	   j < ({ continue; 10; });	// { dg-error "invalid branch" }
> > > > -	   j += ({ continue; 1; }))	// { dg-error "invalid branch" }
> > > > +      for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > +	   j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > +	   j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  	continue;
> > > >  
> > > >        #pragma omp for
> > > > -      for (j = ({ break; 0; });		// { dg-error "invalid branch" }
> > > > -	   j < ({ break; 10; });	// { dg-error "invalid branch" }
> > > > -	   j += ({ break; 1; }))	// { dg-error "invalid branch" }
> > > > +      for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > +	   j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > +	   j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  	break;				// { dg-error "break" }
> > > >      }
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-8.c gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > index 3c717d9..f410070 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > @@ -7,5 +7,5 @@ int foo()
> > > >  
> > > >    #pragma omp parallel for
> > > >    for (i = 0; i < 10; ++i)
> > > > -    return 0;			// { dg-error "invalid branch" }
> > > > +    return 0; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/block-9.c gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > index 9217cb7..2fae3de 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > @@ -3,7 +3,7 @@
> > > >  void foo(int i)
> > > >  {
> > > >    int j;
> > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp parallel
> > > >      { case 0:; }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/target-1.c gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > index 09e65bd..aaa6a14 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > @@ -5,9 +5,9 @@ foo (int x)
> > > >  {
> > > >    bad1:
> > > >    #pragma omp target
> > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp target
> > > >      {
> > > >        bad2: ;
> > > > @@ -21,7 +21,7 @@ foo (int x)
> > > >  	{ ok1: break; }
> > > >      }
> > > >  
> > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp target
> > > >      { case 0:; }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/target-2.c gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > index 546a1d0..3a7afc4 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > @@ -5,9 +5,9 @@ foo (int x, int y)
> > > >  {
> > > >    bad1:
> > > >    #pragma omp target data map(tofrom: y)
> > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp target data map(tofrom: y)
> > > >      {
> > > >        bad2: ;
> > > > @@ -21,7 +21,7 @@ foo (int x, int y)
> > > >  	{ ok1: break; }
> > > >      }
> > > >  
> > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp target data map(tofrom: y)
> > > >      { case 0:; }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/taskgroup-1.c gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > index e301efc..1997e0c 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > @@ -5,9 +5,9 @@ foo (int x)
> > > >  {
> > > >    bad1:
> > > >    #pragma omp taskgroup
> > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp taskgroup
> > > >      {
> > > >        bad2: ;
> > > > @@ -21,7 +21,7 @@ foo (int x)
> > > >  	{ ok1: break; }
> > > >      }
> > > >  
> > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp taskgroup
> > > >      { case 0:; }
> > > > diff --git gcc/testsuite/gcc.dg/gomp/teams-1.c gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > index 73c00de..ad5b100 100644
> > > > --- gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > +++ gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > @@ -5,9 +5,9 @@ foo (int x)
> > > >  {
> > > >    bad1:
> > > >    #pragma omp target teams
> > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp target teams
> > > >      {
> > > >        bad2: ;
> > > > @@ -21,7 +21,7 @@ foo (int x)
> > > >  	{ ok1: break; }
> > > >      }
> > > >  
> > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp target teams
> > > >      { case 0:; }
> > > > @@ -34,9 +34,9 @@ bar (int x)
> > > >    bad1:
> > > >    #pragma omp target
> > > >    #pragma omp teams
> > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > >  
> > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > >    #pragma omp target
> > > >    #pragma omp teams
> > > >      {
> > > > @@ -52,7 +52,7 @@ bar (int x)
> > > >  	{ ok1: break; }
> > > >      }
> > > >  
> > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > >    {
> > > >    #pragma omp target
> > > >    #pragma omp teams


..., and finally:

> > > OpenACC structured blocks; OK for gomp-4_0-branch?
> > > 
> > > commit 58c24ac3e22a5b050227c44e97faf478f8b9f591
> > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > Date:   Tue Dec 10 13:10:24 2013 +0100
> > > 
> > >     OpenACC parallel structured blocks.
> > >     
> > >     	gcc/
> > >     	* gcc/omp-low.c (diagnose_sb_0, diagnose_sb_1, diagnose_sb_2):
> > >     	Handle GIMPLE_OACC_PARALLEL.
> > >     	* gimplify.c (gimplify_case_label_expr): Update comment.
> > >     	gcc/testsuite/
> > >     	* gcc.dg/goacc/parallel-sb-1.c: New file.
> > >     	* gcc.dg/goacc/parallel-sb-2.c: Likewise.
> > > 
> > > diff --git gcc/c/c-parser.c gcc/c/c-parser.c
> > > index ce46f31..e73379e 100644
> > > --- gcc/c/c-parser.c
> > > +++ gcc/c/c-parser.c
> > > @@ -11007,6 +11007,7 @@ c_parser_omp_structured_block (c_parser *parser)
> > >  
> > >  /* OpenACC 2.0:
> > >     # pragma acc parallel oacc-parallel-clause[optseq] new-line
> > > +     structured-block
> > >  
> > >     LOC is the location of the #pragma token.
> > >  */
> > > diff --git gcc/gimplify.c gcc/gimplify.c
> > > index e45bed2..db0dafe 100644
> > > --- gcc/gimplify.c
> > > +++ gcc/gimplify.c
> > > @@ -1479,9 +1479,10 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
> > >    struct gimplify_ctx *ctxp;
> > >    gimple gimple_label;
> > >  
> > > -  /* Invalid OpenMP programs can play Duff's Device type games with
> > > +  /* Invalid programs can play Duff's Device type games with, for example,
> > >       #pragma omp parallel.  At least in the C front end, we don't
> > > -     detect such invalid branches until after gimplification.  */
> > > +     detect such invalid branches until after gimplification, in the
> > > +     diagnose_omp_blocks pass.  */
> > >    for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
> > >      if (ctxp->case_labels.exists ())
> > >        break;
> > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > index f55a1ea..e636545 100644
> > > --- gcc/omp-low.c
> > > +++ gcc/omp-low.c
> > > @@ -10806,7 +10806,7 @@ make_pass_lower_omp (gcc::context *ctxt)
> > >    return new pass_lower_omp (ctxt);
> > >  }
> > >  
> > > -/* The following is a utility to diagnose OpenMP structured block violations.
> > > +/* The following is a utility to diagnose structured block violations.
> > >     It is not part of the "omplower" pass, as that's invoked too late.  It
> > >     should be invoked by the respective front ends after gimplification.  */
> > >  
> > > @@ -10834,6 +10834,15 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > >  	kind = "Cilk Plus";
> > >      }
> > > +  if (flag_openacc)
> > > +    {
> > > +      if ((branch_ctx && gimple_code (branch_ctx) == GIMPLE_OACC_PARALLEL)
> > > +	  || (label_ctx && gimple_code (label_ctx) == GIMPLE_OACC_PARALLEL))
> > > +	{
> > > +	  gcc_assert (kind == NULL);
> > > +	  kind = "OpenACC";
> > > +	}
> > > +    }
> > >    if (kind == NULL)
> > >      {
> > >        gcc_assert (flag_openmp);
> > > @@ -10889,7 +10898,7 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > >    return true;
> > >  }
> > >  
> > > -/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
> > > +/* Pass 1: Create a minimal tree of structured blocks, and record
> > >     where each label is found.  */
> > >  
> > >  static tree
> > > @@ -10902,10 +10911,11 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > >  
> > >    *handled_ops_p = true;
> > >  
> > > - switch (gimple_code (stmt))
> > > +  switch (gimple_code (stmt))
> > >      {
> > >      WALK_SUBSTMTS;
> > >  
> > > +    case GIMPLE_OACC_PARALLEL:
> > >      case GIMPLE_OMP_PARALLEL:
> > >      case GIMPLE_OMP_TASK:
> > >      case GIMPLE_OMP_SECTIONS:
> > > @@ -10917,7 +10927,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > >      case GIMPLE_OMP_TARGET:
> > >      case GIMPLE_OMP_TEAMS:
> > >      case GIMPLE_OMP_TASKGROUP:
> > > -      /* The minimal context here is just the current OMP construct.  */
> > > +      /* The minimal context here is just the current construct.  */
> > >        inner_context = stmt;
> > >        wi->info = inner_context;
> > >        walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
> > > @@ -10964,6 +10974,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > >      {
> > >      WALK_SUBSTMTS;
> > >  
> > > +    case GIMPLE_OACC_PARALLEL:
> > >      case GIMPLE_OMP_PARALLEL:
> > >      case GIMPLE_OMP_TASK:
> > >      case GIMPLE_OMP_SECTIONS:
> > > @@ -11046,8 +11057,8 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > >    return NULL_TREE;
> > >  }
> > >  
> > > -/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
> > > -   codes.  */
> > > +/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
> > > +   GIMPLE codes.  */
> > >  bool
> > >  make_gimple_omp_edges (basic_block bb, struct omp_region **region)
> > >  {
> > > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > > new file mode 100644
> > > index 0000000..3909916
> > > --- /dev/null
> > > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > > @@ -0,0 +1,22 @@
> > > +// { dg-do compile }
> > > +
> > > +void foo()
> > > +{
> > > +  bad1:
> > > +  #pragma acc parallel
> > > +    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
> > > +
> > > +  goto bad2; // { dg-error "invalid entry to OpenACC structured block" }
> > > +  #pragma acc parallel
> > > +    {
> > > +      bad2: ;
> > > +    }
> > > +
> > > +  #pragma acc parallel
> > > +    {
> > > +      int i;
> > > +      goto ok1;
> > > +      for (i = 0; i < 10; ++i)
> > > +	{ ok1: break; }
> > > +    }
> > > +}
> > > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > > new file mode 100644
> > > index 0000000..aede042
> > > --- /dev/null
> > > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > > @@ -0,0 +1,10 @@
> > > +// { dg-do compile }
> > > +
> > > +void foo(int i)
> > > +{
> > > +  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
> > > +  {
> > > +  #pragma acc parallel
> > > +    { case 0:; }
> > > +  }
> > > +}


Grüße,
 Thomas
Thomas Schwinge Feb. 11, 2014, 12:43 p.m. UTC | #4
Hi!

Ping again for test case and rather trivial patch to cure a GCC trunk ICE
in the Cilk Plus structured block checker if both -fcilkplus and -fopenmp
are specified.

Also, I'd still like to know whether the »Generalize diagnose_omp_blocks'
structured block logic« patch is fine, too?  (If that one is
acknowledged, I'll then commit the »OpenACC parallel structured blocks«
patch to gomp-4_0-branch.)

On Fri, 24 Jan 2014 16:57:28 +0100, I wrote:
> Ping.  With a different subject line, this time.  Let's first concentrate
> on the ICE in the Cilk Plus structured block checker, then generalize
> diagnose_omp_blocks' structured block logic, before finally getting to
> the OpenACC extension.
> 
> 
> Here starts the ICE patch:
> 
> On Fri, 10 Jan 2014 12:48:21 +0100, I wrote:
> > Ping.
> > 
> > On Thu, 19 Dec 2013 17:49:09 +0100, I wrote:
> > > Ping.
> > > 
> > > On Tue, 10 Dec 2013 13:53:39 +0100, I wrote:
> > > > At the end of this email you can find the patch that I'd like to apply to
> > > > gomp-4_0-branch for OpenACC structured blocks, after the following two
> > > > have been approved:
> > > 
> > > > On Fri, 06 Dec 2013 19:33:35 +0100, I wrote:
> > > > > On Fri, 15 Nov 2013 14:44:45 -0700, Aldy Hernandez <aldyh@redhat.com> wrote:
> > > > > > --- a/gcc/omp-low.c
> > > > > > +++ b/gcc/omp-low.c
> > > > > > @@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > > > >      error ("invalid entry to OpenMP structured block");
> > > > > >  #endif
> > > > > >  
> > > > > > +  bool cilkplus_block = false;
> > > > > > +  if (flag_enable_cilkplus)
> > > > > > +    {
> > > > > > +      if ((branch_ctx
> > > > > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > > > +	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > > > +	cilkplus_block = true;
> > > > > > +    }
> > > > > 
> > > > > There is one issue here: consider the following code:
> > > > > 
> > > > >     void baz()
> > > > >     {
> > > > >       bad1:
> > > > >       #pragma omp parallel
> > > > >         goto bad1;
> > > > >     }
> > > > > 
> > > > > Then, if both -fcilkplus and -fopenmp are specified, that will run into a
> > > > > SIGSEGV/ICE because of label_ctx == NULL.  The fix is simple enough; OK
> > > > > for trunk and gomp-4_0-branch (after full testing)?
> > > > 
> > > > Testing looks good.
> > > > 
> > > > > The testcase is
> > > > > basically a concatenation of gcc.dg/cilk-plus/jump.c and
> > > > > gcc.dg/gomp/block-1.c -- should this be done differently/better?
> > > > > 
> > > > > commit eee16f8aad4527b705d327476b00bf9f5ba6dcce
> > > > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > > > Date:   Fri Dec 6 18:55:41 2013 +0100
> > > > > 
> > > > >     Fix possible ICE (null pointer dereference) introduced in r204863.
> > > > >     
> > > > >     	gcc/
> > > > >     	* omp-low.c (diagnose_sb_0): Make sure label_ctx is valid to
> > > > >     	dereference.
> > > > >     	gcc/testsuite/
> > > > >     	* gcc.dg/cilk-plus/jump-openmp.c: New file.
> > > > > 
> > > > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > > > index e0f7d1d..91221c0 100644
> > > > > --- gcc/omp-low.c
> > > > > +++ gcc/omp-low.c
> > > > > @@ -10865,7 +10865,8 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > > >        if ((branch_ctx
> > > > >  	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > >  	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > > -	  || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > > +	  || (label_ctx
> > > > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > >  	cilkplus_block = true;
> > > > >      }
> > > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > > new file mode 100644
> > > > > index 0000000..95e6b2d
> > > > > --- /dev/null
> > > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > > @@ -0,0 +1,49 @@
> > > > > +/* { dg-do compile } */
> > > > > +/* { dg-options "-fcilkplus -fopenmp" } */
> > > > > +/* { dg-require-effective-target fopenmp } */
> > > > > +
> > > > > +int *a, *b, c;
> > > > > +
> > > > > +void foo()
> > > > > +{
> > > > > +#pragma simd
> > > > > +  for (int i=0; i < 1000; ++i)
> > > > > +    {
> > > > > +      a[i] = b[i];
> > > > > +      if (c == 5)
> > > > > +	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > > > +    }
> > > > > +}
> > > > > +
> > > > > +void bar()
> > > > > +{
> > > > > +#pragma simd
> > > > > +  for (int i=0; i < 1000; ++i)
> > > > > +    {
> > > > > +    lab:
> > > > > +      a[i] = b[i];
> > > > > +    }
> > > > > +  if (c == 6)
> > > > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > > > > +}
> > > > > +
> > > > > +void baz()
> > > > > +{
> > > > > +  bad1:
> > > > > +  #pragma omp parallel
> > > > > +    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > > > +
> > > > > +  goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > > > > +  #pragma omp parallel
> > > > > +    {
> > > > > +      bad2: ;
> > > > > +    }
> > > > > +
> > > > > +  #pragma omp parallel
> > > > > +    {
> > > > > +      int i;
> > > > > +      goto ok1;
> > > > > +      for (i = 0; i < 10; ++i)
> > > > > +	{ ok1: break; }
> > > > > +    }
> > > > > +}
> 
> 
> Here starts the patch to generalize diagnose_omp_blocks' structured block
> logic (still not specific to OpenACC):
> 
> > > > > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > > > > >    if (branch_ctx == NULL)
> > > > > > -    error ("invalid entry to OpenMP structured block");
> > > > > > +    {
> > > > > > +      if (cilkplus_block)
> > > > > > +	error ("invalid entry to Cilk Plus structured block");
> > > > > > +      else
> > > > > > +	error ("invalid entry to OpenMP structured block");
> > > > > > +    }
> > > > > >    else
> > > > > > -    /* Otherwise, be vague and lazy, but efficient.  */
> > > > > > -    error ("invalid branch to/from an OpenMP structured block");
> > > > > > +    {
> > > > > > +      /* Otherwise, be vague and lazy, but efficient.  */
> > > > > > +      if (cilkplus_block)
> > > > > > +	error ("invalid branch to/from a Cilk Plus structured block");
> > > > > > +      else
> > > > > > +	error ("invalid branch to/from an OpenMP structured block");
> > > > > > +    }
> > > 
> > > > > In fact, and keeping in mind that we're currently adding OpenACC support,
> > > > > I'd suggest to do this differently; OK for trunk and gomp-4_0-branch?
> > > > 
> > > > Testing looks good.
> > > > 
> > > > > commit 367dabfcc94a3e96d63b48c38d0dd94ca9f517f8
> > > > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > > > Date:   Fri Dec 6 19:23:47 2013 +0100
> > > > > 
> > > > >     Generalize diagnose_omp_blocks' structured block logic.
> > > > >     
> > > > >     	gcc/
> > > > >     	* omp-low.c (diagnose_sb_0): Generalize detection which kind of
> > > > >     	structured block we're in.
> > > > >     	gcc/testsuite/
> > > > >     	* g++.dg/gomp/block-1.C: Adjust to changed error message and/or
> > > > >     	be tighten matching rules.
> > > > >     	* g++.dg/gomp/block-2.C: Likewise.
> > > > >     	* g++.dg/gomp/block-3.C: Likewise.
> > > > >     	* g++.dg/gomp/block-5.C: Likewise.
> > > > >     	* g++.dg/gomp/target-1.C: Likewise.
> > > > >     	* g++.dg/gomp/target-2.C: Likewise.
> > > > >     	* g++.dg/gomp/taskgroup-1.C: Likewise.
> > > > >     	* g++.dg/gomp/teams-1.C: Likewise.
> > > > >     	* gcc.dg/cilk-plus/jump-openmp.c: Likewise.
> > > > >     	* gcc.dg/cilk-plus/jump.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-1.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-10.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-2.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-3.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-4.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-5.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-6.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-7.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-8.c: Likewise.
> > > > >     	* gcc.dg/gomp/block-9.c: Likewise.
> > > > >     	* gcc.dg/gomp/target-1.c: Likewise.
> > > > >     	* gcc.dg/gomp/target-2.c: Likewise.
> > > > >     	* gcc.dg/gomp/taskgroup-1.c: Likewise.
> > > > >     	* gcc.dg/gomp/teams-1.c: Likewise.
> > > > > 
> > > > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > > > index 91221c0..f55a1ea 100644
> > > > > --- gcc/omp-low.c
> > > > > +++ gcc/omp-low.c
> > > > > @@ -10822,6 +10822,23 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > > >    if (label_ctx == branch_ctx)
> > > > >      return false;
> > > > >  
> > > > > +  const char* kind = NULL;
> > > > > +
> > > > > +  if (flag_enable_cilkplus)
> > > > > +    {
> > > > > +      if ((branch_ctx
> > > > > +	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > > +	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > > +	  || (label_ctx
> > > > > +	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > > +	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > > +	kind = "Cilk Plus";
> > > > > +    }
> > > > > +  if (kind == NULL)
> > > > > +    {
> > > > > +      gcc_assert (flag_openmp);
> > > > > +      kind = "OpenMP";
> > > > > +    }
> > > > >  
> > > > >    /*
> > > > >       Previously we kept track of the label's entire context in diagnose_sb_[12]
> > > > > @@ -10854,38 +10871,18 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > > >      }
> > > > >  
> > > > >    if (exit_p)
> > > > > -    error ("invalid exit from OpenMP structured block");
> > > > > +    error ("invalid exit from %s structured block", kind);
> > > > >    else
> > > > > -    error ("invalid entry to OpenMP structured block");
> > > > > +    error ("invalid entry to %s structured block", kind);
> > > > >  #endif
> > > > >  
> > > > > -  bool cilkplus_block = false;
> > > > > -  if (flag_enable_cilkplus)
> > > > > -    {
> > > > > -      if ((branch_ctx
> > > > > -	   && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
> > > > > -	   && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
> > > > > -	  || (label_ctx
> > > > > -	      && gimple_code (label_ctx) == GIMPLE_OMP_FOR
> > > > > -	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > > > -	cilkplus_block = true;
> > > > > -    }
> > > > > -
> > > > >    /* If it's obvious we have an invalid entry, be specific about the error.  */
> > > > >    if (branch_ctx == NULL)
> > > > > -    {
> > > > > -      if (cilkplus_block)
> > > > > -	error ("invalid entry to Cilk Plus structured block");
> > > > > -      else
> > > > > -	error ("invalid entry to OpenMP structured block");
> > > > > -    }
> > > > > +    error ("invalid entry to %s structured block", kind);
> > > > >    else
> > > > >      {
> > > > >        /* Otherwise, be vague and lazy, but efficient.  */
> > > > > -      if (cilkplus_block)
> > > > > -	error ("invalid branch to/from a Cilk Plus structured block");
> > > > > -      else
> > > > > -	error ("invalid branch to/from an OpenMP structured block");
> > > > > +      error ("invalid branch to/from %s structured block", kind);
> > > > >      }
> > > > >  
> > > > >    gsi_replace (gsi_p, gimple_build_nop (), false);
> > > > > diff --git gcc/testsuite/g++.dg/gomp/block-1.C gcc/testsuite/g++.dg/gomp/block-1.C
> > > > > index d2b8664..f4badaf 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/block-1.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/block-1.C
> > > > > @@ -21,5 +21,5 @@ void foo()
> > > > >      }
> > > > >  }
> > > > >  
> > > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/block-2.C gcc/testsuite/g++.dg/gomp/block-2.C
> > > > > index 17d98d8..02f5f83d 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/block-2.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/block-2.C
> > > > > @@ -31,5 +31,5 @@ void foo()
> > > > >      continue;
> > > > >  }
> > > > >  
> > > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
> > > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 14 }
> > > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/block-3.C gcc/testsuite/g++.dg/gomp/block-3.C
> > > > > index ff28175..bb54166 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/block-3.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/block-3.C
> > > > > @@ -58,6 +58,6 @@ void foo()
> > > > >      }
> > > > >  }
> > > > >  
> > > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
> > > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
> > > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 21 }
> > > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 26 }
> > > > >  // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/block-5.C gcc/testsuite/g++.dg/gomp/block-5.C
> > > > > index 391f8b6..0aa23a4 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/block-5.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/block-5.C
> > > > > @@ -14,4 +14,4 @@ void foo()
> > > > >      }
> > > > >  }
> > > > >  
> > > > > -// { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
> > > > > +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/target-1.C gcc/testsuite/g++.dg/gomp/target-1.C
> > > > > index b6ed4f8..767661f 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/target-1.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/target-1.C
> > > > > @@ -28,5 +28,5 @@ foo (int x)
> > > > >    }
> > > > >  }
> > > > >  
> > > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/target-2.C gcc/testsuite/g++.dg/gomp/target-2.C
> > > > > index 6a14f53..5a40dd4 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/target-2.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/target-2.C
> > > > > @@ -28,5 +28,5 @@ foo (int x, int y)
> > > > >    }
> > > > >  }
> > > > >  
> > > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/taskgroup-1.C gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > > index dcab0bb..a06edf1 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C
> > > > > @@ -28,5 +28,5 @@ foo (int x)
> > > > >    }
> > > > >  }
> > > > >  
> > > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > > diff --git gcc/testsuite/g++.dg/gomp/teams-1.C gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > > index ce40b55..05f1a7e 100644
> > > > > --- gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > > +++ gcc/testsuite/g++.dg/gomp/teams-1.C
> > > > > @@ -60,7 +60,7 @@ bar (int x)
> > > > >    }
> > > > >  }
> > > > >  
> > > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 8 }
> > > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 8 }
> > > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 10 }
> > > > > -// { dg-error "invalid branch to/from an OpenMP structured block" "" { target *-*-* } 37 }
> > > > > +// { dg-error "invalid branch to/from OpenMP structured block" "" { target *-*-* } 37 }
> > > > >  // { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* } 39 }
> > > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > > index 95e6b2d..6adabf4 100644
> > > > > --- gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump-openmp.c
> > > > > @@ -11,7 +11,7 @@ void foo()
> > > > >      {
> > > > >        a[i] = b[i];
> > > > >        if (c == 5)
> > > > > -	return; /* { dg-error "invalid branch to/from a Cilk Plus structured block" } */
> > > > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > > > >      }
> > > > >  }
> > > > >  
> > > > > @@ -31,7 +31,7 @@ void baz()
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp parallel
> > > > > -    goto bad1; /* { dg-error "invalid branch to/from an OpenMP structured block" } */
> > > > > +    goto bad1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
> > > > >  
> > > > >    goto bad2; /* { dg-error "invalid entry to OpenMP structured block" } */
> > > > >    #pragma omp parallel
> > > > > diff --git gcc/testsuite/gcc.dg/cilk-plus/jump.c gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > > index 9ec3293..1ca886a 100644
> > > > > --- gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > > +++ gcc/testsuite/gcc.dg/cilk-plus/jump.c
> > > > > @@ -10,7 +10,7 @@ void foo()
> > > > >      {
> > > > >        a[i] = b[i];
> > > > >        if (c == 5)
> > > > > -	return;	 /* { dg-error "invalid branch to.from a Cilk" } */
> > > > > +	return; /* { dg-error "invalid branch to/from Cilk Plus structured block" } */
> > > > >      }
> > > > >  }
> > > > >  
> > > > > @@ -23,5 +23,5 @@ void bar()
> > > > >        a[i] = b[i];
> > > > >      }
> > > > >    if (c == 6)
> > > > > -    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
> > > > > +    goto lab; /* { dg-error "invalid entry to Cilk Plus structured block" } */
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-1.c gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > > index dd7fe77..e67e6c3 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-1.c
> > > > > @@ -4,9 +4,9 @@ void foo()
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp parallel
> > > > > -    goto bad1;			// { dg-error "invalid branch" }
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			// { dg-error "invalid entry" }
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp parallel
> > > > >      {
> > > > >        bad2: ;
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-10.c gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > > index 76ee397..69ae3c0 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-10.c
> > > > > @@ -3,28 +3,28 @@
> > > > >  void foo(int i)
> > > > >  {
> > > > >    int j;
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp parallel
> > > > >      { case 0:; }
> > > > >    }
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp for
> > > > >      for (j = 0; j < 10; ++ j)
> > > > >        { case 1:; }
> > > > >    }
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp critical
> > > > >      { case 2:; }
> > > > >    }
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp master
> > > > >      { case 3:; }
> > > > >    }
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp sections
> > > > >      { case 4:;
> > > > > @@ -32,7 +32,7 @@ void foo(int i)
> > > > >         { case 5:; }
> > > > >      }
> > > > >    }
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp ordered
> > > > >      { default:; }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-2.c gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > > index 4c56add..5c01463 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-2.c
> > > > > @@ -11,9 +11,9 @@ void foo()
> > > > >    bad1:
> > > > >    #pragma omp for
> > > > >    for (i = 0; i < 10; ++i)
> > > > > -    goto bad1;			// { dg-error "invalid branch" }
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			// { dg-error "invalid entry" }
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp for
> > > > >    for (i = 0; i < 10; ++i)
> > > > >      {
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-3.c gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > > index b4530e9..3be15fb 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-3.c
> > > > > @@ -18,16 +18,16 @@ void foo()
> > > > >      #pragma omp section
> > > > >        { bad1: ; }
> > > > >      #pragma omp section
> > > > > -      goto bad1;		// { dg-error "invalid branch" }
> > > > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >  
> > > > >    #pragma omp sections
> > > > >      {
> > > > > -      goto bad2;		// { dg-error "invalid branch" }
> > > > > +      goto bad2; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >    bad2:;
> > > > >  
> > > > > -  goto bad3;			// { dg-error "invalid entry" }
> > > > > +  goto bad3; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp sections
> > > > >      {
> > > > >        bad3: ;
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-4.c gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > > index 61f490c..b2ef9b1 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-4.c
> > > > > @@ -4,6 +4,6 @@ void foo()
> > > > >  {
> > > > >    #pragma omp critical
> > > > >      {
> > > > > -      return;		// { dg-error "invalid branch" }
> > > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-5.c gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > > index 741049f..7f3b37c 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-5.c
> > > > > @@ -4,12 +4,12 @@ void foo()
> > > > >  {
> > > > >    #pragma omp master
> > > > >      {
> > > > > -      goto bad1;	// { dg-error "invalid branch" }
> > > > > +      goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >  
> > > > >    #pragma omp master
> > > > >      {
> > > > >      bad1:
> > > > > -      return;		// { dg-error "invalid branch" }
> > > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-6.c gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > > index 87e6392..fc9fdc8 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-6.c
> > > > > @@ -4,6 +4,6 @@ void foo()
> > > > >  {
> > > > >    #pragma omp ordered
> > > > >      {
> > > > > -      return;		// { dg-error "invalid branch" }
> > > > > +      return; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >      }
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-7.c gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > > index 2bc1cdb..6219e7e 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-7.c
> > > > > @@ -6,15 +6,15 @@ void foo()
> > > > >    for (i = 0; i < 10; ++i)
> > > > >      {
> > > > >        #pragma omp for
> > > > > -      for (j = ({ continue; 0; });	// { dg-error "invalid branch" }
> > > > > -	   j < ({ continue; 10; });	// { dg-error "invalid branch" }
> > > > > -	   j += ({ continue; 1; }))	// { dg-error "invalid branch" }
> > > > > +      for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > > +	   j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > > +	   j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  	continue;
> > > > >  
> > > > >        #pragma omp for
> > > > > -      for (j = ({ break; 0; });		// { dg-error "invalid branch" }
> > > > > -	   j < ({ break; 10; });	// { dg-error "invalid branch" }
> > > > > -	   j += ({ break; 1; }))	// { dg-error "invalid branch" }
> > > > > +      for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > > +	   j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > > +	   j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  	break;				// { dg-error "break" }
> > > > >      }
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-8.c gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > > index 3c717d9..f410070 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-8.c
> > > > > @@ -7,5 +7,5 @@ int foo()
> > > > >  
> > > > >    #pragma omp parallel for
> > > > >    for (i = 0; i < 10; ++i)
> > > > > -    return 0;			// { dg-error "invalid branch" }
> > > > > +    return 0; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/block-9.c gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > > index 9217cb7..2fae3de 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/block-9.c
> > > > > @@ -3,7 +3,7 @@
> > > > >  void foo(int i)
> > > > >  {
> > > > >    int j;
> > > > > -  switch (i)			// { dg-error "invalid entry" }
> > > > > +  switch (i) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp parallel
> > > > >      { case 0:; }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/target-1.c gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > > index 09e65bd..aaa6a14 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/target-1.c
> > > > > @@ -5,9 +5,9 @@ foo (int x)
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp target
> > > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp target
> > > > >      {
> > > > >        bad2: ;
> > > > > @@ -21,7 +21,7 @@ foo (int x)
> > > > >  	{ ok1: break; }
> > > > >      }
> > > > >  
> > > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp target
> > > > >      { case 0:; }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/target-2.c gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > > index 546a1d0..3a7afc4 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/target-2.c
> > > > > @@ -5,9 +5,9 @@ foo (int x, int y)
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp target data map(tofrom: y)
> > > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp target data map(tofrom: y)
> > > > >      {
> > > > >        bad2: ;
> > > > > @@ -21,7 +21,7 @@ foo (int x, int y)
> > > > >  	{ ok1: break; }
> > > > >      }
> > > > >  
> > > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp target data map(tofrom: y)
> > > > >      { case 0:; }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/taskgroup-1.c gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > > index e301efc..1997e0c 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c
> > > > > @@ -5,9 +5,9 @@ foo (int x)
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp taskgroup
> > > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp taskgroup
> > > > >      {
> > > > >        bad2: ;
> > > > > @@ -21,7 +21,7 @@ foo (int x)
> > > > >  	{ ok1: break; }
> > > > >      }
> > > > >  
> > > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp taskgroup
> > > > >      { case 0:; }
> > > > > diff --git gcc/testsuite/gcc.dg/gomp/teams-1.c gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > > index 73c00de..ad5b100 100644
> > > > > --- gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > > +++ gcc/testsuite/gcc.dg/gomp/teams-1.c
> > > > > @@ -5,9 +5,9 @@ foo (int x)
> > > > >  {
> > > > >    bad1:
> > > > >    #pragma omp target teams
> > > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp target teams
> > > > >      {
> > > > >        bad2: ;
> > > > > @@ -21,7 +21,7 @@ foo (int x)
> > > > >  	{ ok1: break; }
> > > > >      }
> > > > >  
> > > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp target teams
> > > > >      { case 0:; }
> > > > > @@ -34,9 +34,9 @@ bar (int x)
> > > > >    bad1:
> > > > >    #pragma omp target
> > > > >    #pragma omp teams
> > > > > -    goto bad1;			/* { dg-error "invalid branch" } */
> > > > > +    goto bad1; // { dg-error "invalid branch to/from OpenMP structured block" }
> > > > >  
> > > > > -  goto bad2;			/* { dg-error "invalid entry" } */
> > > > > +  goto bad2; // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    #pragma omp target
> > > > >    #pragma omp teams
> > > > >      {
> > > > > @@ -52,7 +52,7 @@ bar (int x)
> > > > >  	{ ok1: break; }
> > > > >      }
> > > > >  
> > > > > -  switch (x)			/* { dg-error "invalid entry" } */
> > > > > +  switch (x) // { dg-error "invalid entry to OpenMP structured block" }
> > > > >    {
> > > > >    #pragma omp target
> > > > >    #pragma omp teams
> 
> 
> ..., and finally:
> 
> > > > OpenACC structured blocks; OK for gomp-4_0-branch?
> > > > 
> > > > commit 58c24ac3e22a5b050227c44e97faf478f8b9f591
> > > > Author: Thomas Schwinge <thomas@codesourcery.com>
> > > > Date:   Tue Dec 10 13:10:24 2013 +0100
> > > > 
> > > >     OpenACC parallel structured blocks.
> > > >     
> > > >     	gcc/
> > > >     	* gcc/omp-low.c (diagnose_sb_0, diagnose_sb_1, diagnose_sb_2):
> > > >     	Handle GIMPLE_OACC_PARALLEL.
> > > >     	* gimplify.c (gimplify_case_label_expr): Update comment.
> > > >     	gcc/testsuite/
> > > >     	* gcc.dg/goacc/parallel-sb-1.c: New file.
> > > >     	* gcc.dg/goacc/parallel-sb-2.c: Likewise.
> > > > 
> > > > diff --git gcc/c/c-parser.c gcc/c/c-parser.c
> > > > index ce46f31..e73379e 100644
> > > > --- gcc/c/c-parser.c
> > > > +++ gcc/c/c-parser.c
> > > > @@ -11007,6 +11007,7 @@ c_parser_omp_structured_block (c_parser *parser)
> > > >  
> > > >  /* OpenACC 2.0:
> > > >     # pragma acc parallel oacc-parallel-clause[optseq] new-line
> > > > +     structured-block
> > > >  
> > > >     LOC is the location of the #pragma token.
> > > >  */
> > > > diff --git gcc/gimplify.c gcc/gimplify.c
> > > > index e45bed2..db0dafe 100644
> > > > --- gcc/gimplify.c
> > > > +++ gcc/gimplify.c
> > > > @@ -1479,9 +1479,10 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
> > > >    struct gimplify_ctx *ctxp;
> > > >    gimple gimple_label;
> > > >  
> > > > -  /* Invalid OpenMP programs can play Duff's Device type games with
> > > > +  /* Invalid programs can play Duff's Device type games with, for example,
> > > >       #pragma omp parallel.  At least in the C front end, we don't
> > > > -     detect such invalid branches until after gimplification.  */
> > > > +     detect such invalid branches until after gimplification, in the
> > > > +     diagnose_omp_blocks pass.  */
> > > >    for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
> > > >      if (ctxp->case_labels.exists ())
> > > >        break;
> > > > diff --git gcc/omp-low.c gcc/omp-low.c
> > > > index f55a1ea..e636545 100644
> > > > --- gcc/omp-low.c
> > > > +++ gcc/omp-low.c
> > > > @@ -10806,7 +10806,7 @@ make_pass_lower_omp (gcc::context *ctxt)
> > > >    return new pass_lower_omp (ctxt);
> > > >  }
> > > >  
> > > > -/* The following is a utility to diagnose OpenMP structured block violations.
> > > > +/* The following is a utility to diagnose structured block violations.
> > > >     It is not part of the "omplower" pass, as that's invoked too late.  It
> > > >     should be invoked by the respective front ends after gimplification.  */
> > > >  
> > > > @@ -10834,6 +10834,15 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >  	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
> > > >  	kind = "Cilk Plus";
> > > >      }
> > > > +  if (flag_openacc)
> > > > +    {
> > > > +      if ((branch_ctx && gimple_code (branch_ctx) == GIMPLE_OACC_PARALLEL)
> > > > +	  || (label_ctx && gimple_code (label_ctx) == GIMPLE_OACC_PARALLEL))
> > > > +	{
> > > > +	  gcc_assert (kind == NULL);
> > > > +	  kind = "OpenACC";
> > > > +	}
> > > > +    }
> > > >    if (kind == NULL)
> > > >      {
> > > >        gcc_assert (flag_openmp);
> > > > @@ -10889,7 +10898,7 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
> > > >    return true;
> > > >  }
> > > >  
> > > > -/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
> > > > +/* Pass 1: Create a minimal tree of structured blocks, and record
> > > >     where each label is found.  */
> > > >  
> > > >  static tree
> > > > @@ -10902,10 +10911,11 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > > >  
> > > >    *handled_ops_p = true;
> > > >  
> > > > - switch (gimple_code (stmt))
> > > > +  switch (gimple_code (stmt))
> > > >      {
> > > >      WALK_SUBSTMTS;
> > > >  
> > > > +    case GIMPLE_OACC_PARALLEL:
> > > >      case GIMPLE_OMP_PARALLEL:
> > > >      case GIMPLE_OMP_TASK:
> > > >      case GIMPLE_OMP_SECTIONS:
> > > > @@ -10917,7 +10927,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > > >      case GIMPLE_OMP_TARGET:
> > > >      case GIMPLE_OMP_TEAMS:
> > > >      case GIMPLE_OMP_TASKGROUP:
> > > > -      /* The minimal context here is just the current OMP construct.  */
> > > > +      /* The minimal context here is just the current construct.  */
> > > >        inner_context = stmt;
> > > >        wi->info = inner_context;
> > > >        walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
> > > > @@ -10964,6 +10974,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > > >      {
> > > >      WALK_SUBSTMTS;
> > > >  
> > > > +    case GIMPLE_OACC_PARALLEL:
> > > >      case GIMPLE_OMP_PARALLEL:
> > > >      case GIMPLE_OMP_TASK:
> > > >      case GIMPLE_OMP_SECTIONS:
> > > > @@ -11046,8 +11057,8 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
> > > >    return NULL_TREE;
> > > >  }
> > > >  
> > > > -/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
> > > > -   codes.  */
> > > > +/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
> > > > +   GIMPLE codes.  */
> > > >  bool
> > > >  make_gimple_omp_edges (basic_block bb, struct omp_region **region)
> > > >  {
> > > > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > > > new file mode 100644
> > > > index 0000000..3909916
> > > > --- /dev/null
> > > > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
> > > > @@ -0,0 +1,22 @@
> > > > +// { dg-do compile }
> > > > +
> > > > +void foo()
> > > > +{
> > > > +  bad1:
> > > > +  #pragma acc parallel
> > > > +    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
> > > > +
> > > > +  goto bad2; // { dg-error "invalid entry to OpenACC structured block" }
> > > > +  #pragma acc parallel
> > > > +    {
> > > > +      bad2: ;
> > > > +    }
> > > > +
> > > > +  #pragma acc parallel
> > > > +    {
> > > > +      int i;
> > > > +      goto ok1;
> > > > +      for (i = 0; i < 10; ++i)
> > > > +	{ ok1: break; }
> > > > +    }
> > > > +}
> > > > diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > > > new file mode 100644
> > > > index 0000000..aede042
> > > > --- /dev/null
> > > > +++ gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
> > > > @@ -0,0 +1,10 @@
> > > > +// { dg-do compile }
> > > > +
> > > > +void foo(int i)
> > > > +{
> > > > +  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
> > > > +  {
> > > > +  #pragma acc parallel
> > > > +    { case 0:; }
> > > > +  }
> > > > +}
> 
> 
> Grüße,
>  Thomas
diff mbox

Patch

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index ce46f31..e73379e 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -11007,6 +11007,7 @@  c_parser_omp_structured_block (c_parser *parser)
 
 /* OpenACC 2.0:
    # pragma acc parallel oacc-parallel-clause[optseq] new-line
+     structured-block
 
    LOC is the location of the #pragma token.
 */
diff --git gcc/gimplify.c gcc/gimplify.c
index e45bed2..db0dafe 100644
--- gcc/gimplify.c
+++ gcc/gimplify.c
@@ -1479,9 +1479,10 @@  gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
   struct gimplify_ctx *ctxp;
   gimple gimple_label;
 
-  /* Invalid OpenMP programs can play Duff's Device type games with
+  /* Invalid programs can play Duff's Device type games with, for example,
      #pragma omp parallel.  At least in the C front end, we don't
-     detect such invalid branches until after gimplification.  */
+     detect such invalid branches until after gimplification, in the
+     diagnose_omp_blocks pass.  */
   for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
     if (ctxp->case_labels.exists ())
       break;
diff --git gcc/omp-low.c gcc/omp-low.c
index f55a1ea..e636545 100644
--- gcc/omp-low.c
+++ gcc/omp-low.c
@@ -10806,7 +10806,7 @@  make_pass_lower_omp (gcc::context *ctxt)
   return new pass_lower_omp (ctxt);
 }
 
-/* The following is a utility to diagnose OpenMP structured block violations.
+/* The following is a utility to diagnose structured block violations.
    It is not part of the "omplower" pass, as that's invoked too late.  It
    should be invoked by the respective front ends after gimplification.  */
 
@@ -10834,6 +10834,15 @@  diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
 	      && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
 	kind = "Cilk Plus";
     }
+  if (flag_openacc)
+    {
+      if ((branch_ctx && gimple_code (branch_ctx) == GIMPLE_OACC_PARALLEL)
+	  || (label_ctx && gimple_code (label_ctx) == GIMPLE_OACC_PARALLEL))
+	{
+	  gcc_assert (kind == NULL);
+	  kind = "OpenACC";
+	}
+    }
   if (kind == NULL)
     {
       gcc_assert (flag_openmp);
@@ -10889,7 +10898,7 @@  diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
   return true;
 }
 
-/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
+/* Pass 1: Create a minimal tree of structured blocks, and record
    where each label is found.  */
 
 static tree
@@ -10902,10 +10911,11 @@  diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
 
   *handled_ops_p = true;
 
- switch (gimple_code (stmt))
+  switch (gimple_code (stmt))
     {
     WALK_SUBSTMTS;
 
+    case GIMPLE_OACC_PARALLEL:
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_SECTIONS:
@@ -10917,7 +10927,7 @@  diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_TARGET:
     case GIMPLE_OMP_TEAMS:
     case GIMPLE_OMP_TASKGROUP:
-      /* The minimal context here is just the current OMP construct.  */
+      /* The minimal context here is just the current construct.  */
       inner_context = stmt;
       wi->info = inner_context;
       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
@@ -10964,6 +10974,7 @@  diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     {
     WALK_SUBSTMTS;
 
+    case GIMPLE_OACC_PARALLEL:
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
     case GIMPLE_OMP_SECTIONS:
@@ -11046,8 +11057,8 @@  diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   return NULL_TREE;
 }
 
-/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
-   codes.  */
+/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
+   GIMPLE codes.  */
 bool
 make_gimple_omp_edges (basic_block bb, struct omp_region **region)
 {
diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
new file mode 100644
index 0000000..3909916
--- /dev/null
+++ gcc/testsuite/gcc.dg/goacc/parallel-sb-1.c
@@ -0,0 +1,22 @@ 
+// { dg-do compile }
+
+void foo()
+{
+  bad1:
+  #pragma acc parallel
+    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
+
+  goto bad2; // { dg-error "invalid entry to OpenACC structured block" }
+  #pragma acc parallel
+    {
+      bad2: ;
+    }
+
+  #pragma acc parallel
+    {
+      int i;
+      goto ok1;
+      for (i = 0; i < 10; ++i)
+	{ ok1: break; }
+    }
+}
diff --git gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
new file mode 100644
index 0000000..aede042
--- /dev/null
+++ gcc/testsuite/gcc.dg/goacc/parallel-sb-2.c
@@ -0,0 +1,10 @@ 
+// { dg-do compile }
+
+void foo(int i)
+{
+  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
+  {
+  #pragma acc parallel
+    { case 0:; }
+  }
+}