re PR c/63326 (whether a #pragma is a statement depends on the type of pragma)
authorJakub Jelinek <jakub@redhat.com>
Fri, 27 Nov 2015 08:59:55 +0000 (09:59 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 27 Nov 2015 08:59:55 +0000 (09:59 +0100)
PR c/63326
* c-parser.c (c_parser_compound_statement_nostart): If
last_label is true, use pragma_stmt instead of pragma_compound
as second c_parser_pragma argument.
(c_parser_omp_ordered, c_parser_omp_target_update,
c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Pass
false as second argument to c_parser_skip_to_pragma_eol after
diagnosing standalone directives used in pragma_stmt context.

* parser.c (cp_parser_statement): Clear in_compound after labels.

* gcc.dg/gomp/barrier-2.c (f2): Expect another error after label.
* c-c++-common/gomp/pr63326.c: New test.

* testsuite/libgomp.c/cancel-parallel-2.c (foo): Add semicolon
in between case label and OpenMP standalone directives.
* testsuite/libgomp.c++/cancel-parallel-2.C (foo): Likewise.

From-SVN: r230999

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/pr63326.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/barrier-2.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/cancel-parallel-2.C
libgomp/testsuite/libgomp.c/cancel-parallel-2.c

index 805cc4f16a51967c4fc8e545a833709f72fedbb7..2f58369bf4a6c1f8010bef5144e8dfd87b62cd82 100644 (file)
@@ -1,3 +1,14 @@
+2015-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/63326
+       * c-parser.c (c_parser_compound_statement_nostart): If
+       last_label is true, use pragma_stmt instead of pragma_compound
+       as second c_parser_pragma argument.
+       (c_parser_omp_ordered, c_parser_omp_target_update,
+       c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Pass
+       false as second argument to c_parser_skip_to_pragma_eol after
+       diagnosing standalone directives used in pragma_stmt context.
+
 2015-11-24  Ilya Verbin  <ilya.verbin@intel.com>
 
        * c-parser.c (c_parser_oacc_declare): Replace "ifdef ENABLE_OFFLOADING"
index 44a925ba32c6f5e467656a1a5dd001573d7d34c8..0259f66aeb4d2b319bbe8e7c3496cefc37aef693 100644 (file)
@@ -4729,7 +4729,8 @@ c_parser_compound_statement_nostart (c_parser *parser)
             syntactically.  This ensures that the user doesn't put them
             places that would turn into syntax errors if the directive
             were ignored.  */
-         if (c_parser_pragma (parser, pragma_compound))
+         if (c_parser_pragma (parser,
+                              last_label ? pragma_stmt : pragma_compound))
            last_label = false, last_stmt = true;
        }
       else if (c_parser_next_token_is (parser, CPP_EOF))
@@ -14988,7 +14989,7 @@ c_parser_omp_ordered (c_parser *parser, enum pragma_context context)
              error_at (loc,
                        "%<#pragma omp ordered%> with %<depend> clause may "
                        "only be used in compound statements");
-             c_parser_skip_to_pragma_eol (parser);
+             c_parser_skip_to_pragma_eol (parser, false);
              return false;
            }
 
@@ -15636,7 +15637,7 @@ c_parser_omp_target_update (location_t loc, c_parser *parser,
       error_at (loc,
                "%<#pragma omp target update%> may only be "
                "used in compound statements");
-      c_parser_skip_to_pragma_eol (parser);
+      c_parser_skip_to_pragma_eol (parser, false);
       return false;
     }
 
@@ -15696,7 +15697,7 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
       error_at (loc,
                "%<#pragma omp target enter data%> may only be "
                "used in compound statements");
-      c_parser_skip_to_pragma_eol (parser);
+      c_parser_skip_to_pragma_eol (parser, false);
       return NULL_TREE;
     }
 
@@ -15781,7 +15782,7 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
       error_at (loc,
                "%<#pragma omp target exit data%> may only be "
                "used in compound statements");
-      c_parser_skip_to_pragma_eol (parser);
+      c_parser_skip_to_pragma_eol (parser, false);
       return NULL_TREE;
     }
 
index eb4bb6810a1e39e647d38148e9585e6b9f6ab50f..bb54dce0fe945c358c4f4e98cd5229f3fe379617 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/63326
+       * parser.c (cp_parser_statement): Clear in_compound after labels.
+
 2015-11-27  Martin Liska  <mliska@suse.cz>
 
        * parser.c (cp_parser_late_parsing_cilk_simd_fn_info):
index 6583d4ca7db41fc96e40af718bd0ce6212f06609..90a0673a38cf0f62ccc7048247c5091661cae866 100644 (file)
@@ -10003,6 +10003,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
             Parse the label, and then use tail recursion to parse
             the statement.  */
          cp_parser_label_for_labeled_statement (parser, std_attrs);
+         in_compound = false;
          goto restart;
 
        case RID_IF:
@@ -10100,6 +10101,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
             the statement.  */
 
          cp_parser_label_for_labeled_statement (parser, std_attrs);
+         in_compound = false;
          goto restart;
        }
     }
index 57222900c71b4637a52d6e60b4cdb472bc03d8b9..e946a6f24dcb448095539e6d1920dc95cefd118c 100644 (file)
@@ -1,3 +1,9 @@
+2015-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/63326
+       * gcc.dg/gomp/barrier-2.c (f2): Expect another error after label.
+       * c-c++-common/gomp/pr63326.c: New test.
+
 2015-11-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/68553
diff --git a/gcc/testsuite/c-c++-common/gomp/pr63326.c b/gcc/testsuite/c-c++-common/gomp/pr63326.c
new file mode 100644 (file)
index 0000000..e319f49
--- /dev/null
@@ -0,0 +1,479 @@
+/* PR c/63326 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void
+f1 (int x)
+{
+  int i;
+  if (x)
+    #pragma omp barrier                                /* { dg-error "may only be used in compound statements" } */
+  ;
+  if (x)
+    #pragma omp flush                          /* { dg-error "may only be used in compound statements" } */
+  ;
+  if (x)
+    #pragma omp taskwait                       /* { dg-error "may only be used in compound statements" } */
+  ;
+  if (x)
+    #pragma omp taskyield                      /* { dg-error "may only be used in compound statements" } */
+  ;
+  #pragma omp parallel
+  {
+    if (x)
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp parallel
+  {
+    if (x)
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      if (x)
+       #pragma omp ordered depend(source)      /* { dg-error "may only be used in compound statements" } */
+      ;
+      if (x)
+       #pragma omp ordered depend(sink: i-1)   /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  if (x)
+    #pragma omp target enter data map(to:i)    /* { dg-error "may only be used in compound statements" } */
+  ;
+  if (x)
+    #pragma omp target update to(i)            /* { dg-error "may only be used in compound statements" } */
+  ;
+  if (x)
+    #pragma omp target exit data map(from:i)   /* { dg-error "may only be used in compound statements" } */
+  ;
+}
+
+void
+f2 (int x)
+{
+  int i;
+  while (x)
+    #pragma omp barrier                                /* { dg-error "may only be used in compound statements" } */
+  ;
+  while (x)
+    #pragma omp flush                          /* { dg-error "may only be used in compound statements" } */
+  ;
+  while (x)
+    #pragma omp taskwait                       /* { dg-error "may only be used in compound statements" } */
+  ;
+  while (x)
+    #pragma omp taskyield                      /* { dg-error "may only be used in compound statements" } */
+  ;
+  #pragma omp parallel
+  {
+    while (x)
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp parallel
+  {
+    while (x)
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      while (x)
+       #pragma omp ordered depend(source)      /* { dg-error "may only be used in compound statements" } */
+      ;
+      while (x)
+       #pragma omp ordered depend(sink: i-1)   /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  while (x)
+    #pragma omp target enter data map(to:i)    /* { dg-error "may only be used in compound statements" } */
+  ;
+  while (x)
+    #pragma omp target update to(i)            /* { dg-error "may only be used in compound statements" } */
+  ;
+  while (x)
+    #pragma omp target exit data map(from:i)   /* { dg-error "may only be used in compound statements" } */
+  ;
+}
+
+void
+f3 (int x)
+{
+  int i;
+  for (x = 0; x < 10; x++)
+    #pragma omp barrier                                /* { dg-error "may only be used in compound statements" } */
+  ;
+  for (x = 0; x < 10; x++)
+    #pragma omp flush                          /* { dg-error "may only be used in compound statements" } */
+  ;
+  for (x = 0; x < 10; x++)
+    #pragma omp taskwait                       /* { dg-error "may only be used in compound statements" } */
+  ;
+  for (x = 0; x < 10; x++)
+    #pragma omp taskyield                      /* { dg-error "may only be used in compound statements" } */
+  ;
+  #pragma omp parallel
+  {
+    for (x = 0; x < 10; x++)
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp parallel
+  {
+    for (x = 0; x < 10; x++)
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      for (x = 0; x < 10; x++)
+       #pragma omp ordered depend(source)      /* { dg-error "may only be used in compound statements" } */
+      ;
+      for (x = 0; x < 10; x++)
+       #pragma omp ordered depend(sink: i-1)   /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  for (x = 0; x < 10; x++)
+    #pragma omp target enter data map(to:i)    /* { dg-error "may only be used in compound statements" } */
+  ;
+  for (x = 0; x < 10; x++)
+    #pragma omp target update to(i)            /* { dg-error "may only be used in compound statements" } */
+  ;
+  for (x = 0; x < 10; x++)
+    #pragma omp target exit data map(from:i)   /* { dg-error "may only be used in compound statements" } */
+  ;
+}
+
+void
+f4 (int x)
+{
+  int i;
+  {
+    do
+      #pragma omp barrier                      /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  {
+    do
+      #pragma omp flush                                /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  {
+    do
+      #pragma omp taskwait                     /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  {
+    do
+      #pragma omp taskyield                    /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  #pragma omp parallel
+  {
+    do
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  #pragma omp parallel
+  {
+    do
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      {
+       do
+         #pragma omp ordered depend(source)    /* { dg-error "may only be used in compound statements" } */
+       while (0);
+      } /* { dg-error "before" "" { target c++ } } */
+      {
+       do
+         #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */
+       while (0);
+      } /* { dg-error "before" "" { target c++ } } */
+    }
+  {
+    do
+      #pragma omp target enter data map(to:i)  /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  {
+    do
+      #pragma omp target update to(i)          /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+  {
+    do
+      #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */
+    while (0);
+  } /* { dg-error "before" "" { target c++ } } */
+}
+
+void
+f5 (int x)
+{
+  int i;
+  switch (x)
+    #pragma omp barrier                                /* { dg-error "may only be used in compound statements" } */
+  ;
+  switch (x)
+    #pragma omp flush                          /* { dg-error "may only be used in compound statements" } */
+  ;
+  switch (x)
+    #pragma omp taskwait                       /* { dg-error "may only be used in compound statements" } */
+  ;
+  switch (x)
+    #pragma omp taskyield                      /* { dg-error "may only be used in compound statements" } */
+  ;
+  #pragma omp parallel
+  {
+    switch (x)
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp parallel
+  {
+    switch (x)
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      switch (x)
+       #pragma omp ordered depend(source)      /* { dg-error "may only be used in compound statements" } */
+      ;
+      switch (x)
+       #pragma omp ordered depend(sink: i-1)   /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    #pragma omp target enter data map(to:i)    /* { dg-error "may only be used in compound statements" } */
+  ;
+  switch (x)
+    #pragma omp target update to(i)            /* { dg-error "may only be used in compound statements" } */
+  ;
+  switch (x)
+    #pragma omp target exit data map(from:i)   /* { dg-error "may only be used in compound statements" } */
+  ;
+}
+
+void
+f6 (int x)
+{
+  int i;
+  switch (x)
+    {
+    case 1:
+      #pragma omp barrier                      /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp flush                                /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp taskwait                     /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp taskyield                    /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  #pragma omp parallel
+  {
+    switch (x)
+      {
+      case 1:
+       #pragma omp cancel parallel             /* { dg-error "may only be used in compound statements" } */
+       ;
+      }
+  }
+  #pragma omp parallel
+  {
+    switch (x)
+      {
+      case 1:
+       #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */
+       ;
+      }
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      switch (x)
+       {
+       case 1:
+         #pragma omp ordered depend(source)    /* { dg-error "may only be used in compound statements" } */
+         ;
+       }
+      switch (x)
+       {
+       case 1:
+         #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */
+         ;
+       }
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp target enter data map(to:i)  /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp target update to(i)          /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    case 1:
+      #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+}
+
+void
+f7 (int x)
+{
+  int i;
+  switch (x)
+    {
+    default:
+      #pragma omp barrier                      /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp flush                                /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp taskwait                     /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp taskyield                    /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  #pragma omp parallel
+  {
+    switch (x)
+      {
+      default:
+       #pragma omp cancel parallel             /* { dg-error "may only be used in compound statements" } */
+       ;
+      }
+  }
+  #pragma omp parallel
+  {
+    switch (x)
+      {
+      default:
+       #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */
+       ;
+      }
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      switch (x)
+       {
+       default:
+         #pragma omp ordered depend(source)    /* { dg-error "may only be used in compound statements" } */
+         ;
+       }
+      switch (x)
+       {
+       default:
+         #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */
+         ;
+       }
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp target enter data map(to:i)  /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp target update to(i)          /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  switch (x)
+    {
+    default:
+      #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+}
+
+void
+f8 (int x)
+{
+  int i;
+  lab1:
+    #pragma omp barrier                                /* { dg-error "may only be used in compound statements" } */
+  ;
+  lab2:
+    #pragma omp flush                          /* { dg-error "may only be used in compound statements" } */
+  ;
+  lab3:
+    #pragma omp taskwait                       /* { dg-error "may only be used in compound statements" } */
+  ;
+  lab4:
+    #pragma omp taskyield                      /* { dg-error "may only be used in compound statements" } */
+  ;
+  #pragma omp parallel
+  {
+    lab5:
+      #pragma omp cancel parallel              /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp parallel
+  {
+    lab6:
+      #pragma omp cancellation point parallel  /* { dg-error "may only be used in compound statements" } */
+    ;
+  }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 16; i++)
+    {
+      lab7:
+       #pragma omp ordered depend(source)      /* { dg-error "may only be used in compound statements" } */
+      ;
+      lab8:
+       #pragma omp ordered depend(sink: i-1)   /* { dg-error "may only be used in compound statements" } */
+      ;
+    }
+  lab9:
+    #pragma omp target enter data map(to:i)    /* { dg-error "may only be used in compound statements" } */
+  ;
+  lab10:
+    #pragma omp target update to(i)            /* { dg-error "may only be used in compound statements" } */
+  ;
+  lab11:
+    #pragma omp target exit data map(from:i)   /* { dg-error "may only be used in compound statements" } */
+  ;
+}
index 3787c35a13e9b3fb2468e5823194210e6906f3bb..5a7091946c4c93edbca6de23e2cb5236cc4c9af3 100644 (file)
@@ -16,7 +16,7 @@ void f1(void)
 void f2(void)
 {
   label:       /* { dg-error "label at end of compound statement" } */
-    #pragma omp barrier
+    #pragma omp barrier                /* { dg-error "may only be used in compound statements" } */
 }
 
 void f3(_Bool p)
index 75a9b4a1799525a81f2b86eadedccaf3014cf7ea..9b320b3cd55ca58c06d6a6f0873597addfc19683 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/63326
+       * testsuite/libgomp.c/cancel-parallel-2.c (foo): Add semicolon
+       in between case label and OpenMP standalone directives.
+       * testsuite/libgomp.c++/cancel-parallel-2.C (foo): Likewise.
+
 2015-11-26  David Edelsohn  <dje.gcc@gmail.com>
 
        * configure: Regenerate.
index 340423b5586a4bebb38b5d95a19f398a94b3bb8b..23b8caa410efeb90b6941acd966a66da383889ad 100644 (file)
@@ -17,7 +17,7 @@ foo (int *x)
     int thr = omp_get_thread_num ();
     switch (x[thr])
       {
-      case 4:
+      case 4:;
        #pragma omp cancel parallel
        break;
       case 3:
@@ -31,7 +31,7 @@ foo (int *x)
       case 2:
        usleep (1000);
        /* FALLTHRU */
-      case 1:
+      case 1:;
        #pragma omp cancellation point parallel
        break;
       }
index cae0aa45c0f8152565c8d90fec46914f178e4b61..20adb55507f7ca23e143cc09f1e35e095a101420 100644 (file)
@@ -13,7 +13,7 @@ foo (int *x)
     int thr = omp_get_thread_num ();
     switch (x[thr])
       {
-      case 4:
+      case 4:;
        #pragma omp cancel parallel
        break;
       case 3:
@@ -27,7 +27,7 @@ foo (int *x)
       case 2:
        usleep (1000);
        /* FALLTHRU */
-      case 1:
+      case 1:;
        #pragma omp cancellation point parallel
        break;
       }