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

            Bug ID: 127816
           Summary: [15/16/17 Regression] [OpenMP] metadirective parallel
                    makes GCC reject otherwise ordinary acceptable
                    statements
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gabravier at gmail dot com
  Target Milestone: ---

struct S { int x, y; };
void f1 ();
void f2 ();
struct S s;

void t4a (bool c)
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  if (c) { f1 (); } else { f2 (); }
}

void t4b ()
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  do { f1 (); } while (0);
}

void t4c ()
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  s = (struct S){1, 2};
}

My reading of the OpenMP is that these should parse - the statement after the
#pragma is a perfectly ordinary and acceptable full statement (AIUI, anything
that would be permissible if wrapped into a single-statement compound-statement
is itself acceptable). Trunk GCC (with -std=c23 -O2 -fopenmp) disagrees:

<source>: In function 't4a':
<source>:9:21: error: 'else' without a previous 'if'
    9 |   if (c) { f1 (); } else { f2 (); }
      |                     ^~~~
<source>: In function 't4b':
<source>:14:64: error: expected 'while' at end of input
   14 |   #pragma omp metadirective when(implementation={vendor(gnu)}:
parallel)
      |                                                                ^~~~~~~~
cc1: error: expected 'while' at end of input
<source>: In function 't4c':
<source>:21:23: error: expected ';' at end of input
   21 |   s = (struct S){1, 2};
      |                       ^
      |                       ;
<source>:21:23: error: expected ';' at end of input
   21 |   s = (struct S){1, 2};
      |                       ^
      |                       ;

...and so do GCC 15 and 16. My guess as to the cause is that the
analyze_metadirective_body function does not properly accept all of the
statements it should. From testing this in C++ with:

struct S { int x, y; };
void f1 ();
void f2 ();
S s;

void t4a (bool c)
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  if (c) { f1 (); } else { f2 (); }
}

void t4b ()
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  do { f1 (); } while (0);
}

void t4c ()
{
  #pragma omp metadirective when(implementation={vendor(gnu)}: parallel)
  s = S{1, 2};
}

...the same bug also appears to be same, with the same function name in the C++
parser, too.

Reply via email to