Like the fortran FE, the C++ FE doesn't set the expr_location of the
split acc loop in combined acc parallel/kernels loop directives. This
only happens for with combined directives, otherwise
cp_parser_omp_construct would be responsible for setting the
location. After fixing this bug, I was able to resolve a couple of
long standing diagnostics discrepancies between the c/c++ FEs in the
test suite.

Is this patch OK for trunk? I bootstrapped and regtested using x86_64
with nvptx offloading.

Thanks,
Cesar

2018-XX-YY  Cesar Philippidis  <ce...@codesourcery.com>

        gcc/cp/
        * parser.c (cp_parser_oacc_kernels_parallel): Adjust EXPR_LOCATION
        on the combined acc loop.

        gcc/testsuite/
        * c-c++-common/goacc/combined-directives-3.c: New test.
        * c-c++-common/goacc/loop-2-kernels.c (void K): Adjust test.
        * c-c++-common/goacc/loop-2-parallel.c (void P): Adjust test.
        * c-c++-common/goacc/loop-3.c (void p2): Adjust test.

(cherry picked from gomp-4_0-branch r245673)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 90d5d00..52e61fc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -37183,8 +37183,9 @@ cp_parser_oacc_kernels_parallel (cp_parser *parser, 
cp_token *pragma_tok,
          cp_lexer_consume_token (parser->lexer);
          tree block = begin_omp_parallel ();
          tree clauses;
-         cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, &clauses,
-                              if_p);
+         tree stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask,
+                                          &clauses, if_p);
+         protected_set_expr_location (stmt, pragma_tok->location);
          return finish_omp_construct (code, block, clauses);
        }
     }
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c 
b/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c
new file mode 100644
index 0000000..77d4182
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c
@@ -0,0 +1,24 @@
+/* Verify the accuracy of the line number associated with combined
+   constructs.  */
+
+int
+main ()
+{
+  int x, y, z;
+
+#pragma acc parallel loop seq auto /* { dg-error "'seq' overrides other 
OpenACC loop specifiers" } */
+  for (x = 0; x < 10; x++)
+#pragma acc loop
+    for (y = 0; y < 10; y++)
+      ;
+
+#pragma acc parallel loop gang auto /* { dg-error "'auto' conflicts with other 
OpenACC loop specifiers" } */
+  for (x = 0; x < 10; x++)
+#pragma acc loop worker auto /* { dg-error "'auto' conflicts with other 
OpenACC loop specifiers" } */
+    for (y = 0; y < 10; y++)
+#pragma acc loop vector
+      for (z = 0; z < 10; z++)
+       ;
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-2-kernels.c 
b/gcc/testsuite/c-c++-common/goacc/loop-2-kernels.c
index 01ad32d..3a11ef5f 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-2-kernels.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-2-kernels.c
@@ -145,8 +145,8 @@ void K(void)
 #pragma acc kernels loop worker(num:5)
   for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop seq worker // { dg-error "'seq' overrides" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc kernels loop seq worker // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
 #pragma acc kernels loop gang worker
   for (i = 0; i < 10; i++)
@@ -161,8 +161,8 @@ void K(void)
 #pragma acc kernels loop vector(length:5)
   for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop seq vector // { dg-error "'seq' overrides" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc kernels loop seq vector // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
 #pragma acc kernels loop gang vector
   for (i = 0; i < 10; i++)
@@ -174,16 +174,16 @@ void K(void)
 #pragma acc kernels loop auto
   for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop seq auto // { dg-error "'seq' overrides" "" { target 
c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc kernels loop seq auto // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop gang auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc kernels loop gang auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop worker auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc kernels loop worker auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc kernels loop vector auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc kernels loop vector auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-2-parallel.c 
b/gcc/testsuite/c-c++-common/goacc/loop-2-parallel.c
index 0ef5741..27f7bbd 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-2-parallel.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-2-parallel.c
@@ -115,16 +115,16 @@ void P(void)
   for (i = 0; i < 10; i++)
     { }
 
-#pragma acc parallel loop seq gang // { dg-error "'seq' overrides" "" { target 
c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc parallel loop seq gang // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
 
 #pragma acc parallel loop worker
   for (i = 0; i < 10; i++)
     { }
 
-#pragma acc parallel loop seq worker // { dg-error "'seq' overrides" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc parallel loop seq worker // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
 #pragma acc parallel loop gang worker
   for (i = 0; i < 10; i++)
@@ -134,8 +134,8 @@ void P(void)
   for (i = 0; i < 10; i++)
     { }
 
-#pragma acc parallel loop seq vector // { dg-error "'seq' overrides" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc parallel loop seq vector // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
 #pragma acc parallel loop gang vector
   for (i = 0; i < 10; i++)
@@ -147,16 +147,16 @@ void P(void)
 #pragma acc parallel loop auto
   for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop seq auto // { dg-error "'seq' overrides" "" { target 
c } }
-  for (i = 0; i < 10; i++) // { dg-error "'seq' overrides" "" { target c++ } }
+#pragma acc parallel loop seq auto // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop gang auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc parallel loop gang auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop worker auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc parallel loop worker auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop vector auto // { dg-error "'auto' conflicts" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "'auto' conflicts" "" { target c++ } }
+#pragma acc parallel loop vector auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
     { }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-3.c 
b/gcc/testsuite/c-c++-common/goacc/loop-3.c
index 44b65a8..ad31d05 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-3.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-3.c
@@ -35,24 +35,24 @@ void p2 (void)
 {
   int i, j;
 
-#pragma acc parallel loop gang(5) // { dg-error "argument not permitted" "" { 
target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop gang(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop gang(num:5) // { dg-error "argument not permitted" 
"" { target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop gang(num:5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
     { }
 
-#pragma acc parallel loop worker(5) // { dg-error "argument not permitted" "" 
{ target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop worker(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop worker(num:5) // { dg-error "argument not permitted" 
"" { target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop worker(num:5) // { dg-error "argument not permitted" 
}
+  for (i = 0; i < 10; i++)
     { }
 
-#pragma acc parallel loop vector(5) // { dg-error "argument not permitted" "" 
{ target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop vector(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
     { }
-#pragma acc parallel loop vector(length:5) // { dg-error "argument not 
permitted" "" { target c } }
-  for (i = 0; i < 10; i++) // { dg-error "argument not permitted" "" { target 
c++ } }
+#pragma acc parallel loop vector(length:5) // { dg-error "argument not 
permitted" }
+  for (i = 0; i < 10; i++)
     { }
 }
-- 
2.7.4

Reply via email to