The following patch fixes the remaining problems in the C++ front-end to bring the pragma simd implementation on equal footing with the C FE.

Herein lie some small changes to the code parsing the initialization statement in the for loop, as well as the condition. I also separated out the "for2.c" test, since both frontends were sufficiently different to warrant different tests.

The remaining Cilk Plus failure (for both C and C++) is c-c++-common/cilk-plus/PS/for5.c, which I'm still investigating how to fix.

Pushed to branch.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c93ea9e..d68bdf7 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -30236,6 +30236,17 @@ cp_parser_simd_for_init_statement (cp_parser *parser, 
tree *init,
       error_at (loc, "expected iteration declaration");
       return error_mark_node;
     }
+
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC)
+      || cp_lexer_next_token_is_keyword (parser->lexer, RID_REGISTER)
+      || cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTERN)
+      || cp_lexer_next_token_is_keyword (parser->lexer, RID_MUTABLE)
+      || cp_lexer_next_token_is_keyword (parser->lexer, RID_THREAD))
+    {
+      error_at (loc, "storage class is not allowed");
+      cp_lexer_consume_token (parser->lexer);
+    }
+
   cp_parser_parse_tentatively (parser);
   cp_parser_type_specifier_seq (parser, true, false, &type_specifiers);
   if (cp_parser_parse_definitely (parser))
@@ -30332,7 +30343,8 @@ cp_parser_simd_for_init_statement (cp_parser *parser, 
tree *init,
        }
       else
        {
-         decl = NULL_TREE;
+         if (decl != error_mark_node)
+           decl = NULL;
          cp_parser_abort_tentative_parse (parser);
          *init = cp_parser_expression (parser, false, NULL);
        }
@@ -30379,6 +30391,7 @@ cp_parser_cilk_for (cp_parser *parser, enum rid 
for_keyword, tree clauses)
       return error_mark_node;
     }
 
+  /* Parse initialization.  */
   if (for_keyword == RID_FOR)
     decl = cp_parser_simd_for_init_statement (parser, &init, &pre_body);
 
@@ -30410,6 +30423,13 @@ cp_parser_cilk_for (cp_parser *parser, enum rid 
for_keyword, tree clauses)
       valid = false;
     }
 
+  if (!valid)
+    {
+      /* Skip to the semicolon ending the init.  */
+      cp_parser_skip_to_end_of_statement (parser);
+    }
+
+  /* Parse condition.  */
   if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
     return error_mark_node;
   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -30426,7 +30446,8 @@ cp_parser_cilk_for (cp_parser *parser, enum rid 
for_keyword, tree clauses)
   if (cond == error_mark_node)
     valid = false;
   cp_parser_consume_semicolon_at_end_of_statement (parser);
-  
+
+  /* Parse increment.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
     {
       error_at (loc, "missing increment");
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 16e2472..f8c5d82 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6058,7 +6058,7 @@ finish_omp_cancellation_point (tree clauses)
 tree
 finish_cilk_for_cond (tree cond)
 {
-  return maybe_convert_cond (cond);
+  return cp_truthvalue_conversion (cond);
 }
 
 /* Begin a __transaction_atomic or __transaction_relaxed statement.
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c 
b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
index 5ecefd5..fe8b630 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
@@ -12,7 +12,7 @@ void foo()
   for (int i=0; i < 1000; ++i)
     {
       if (c == 5)
-       return;  /* { dg-error "return statments are not allowed" } */
+       return;  /* { dg-error "\(return statments are not allowed\|invalid 
exit\)" } */
       if (c == 6)
        __builtin_setjmp (jmpbuf); /* { dg-error "calls to setjmp are not 
allowed" } */
       a[i] = b[i];
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c 
b/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c
deleted file mode 100644
index dc0a41e..0000000
--- a/gcc/testsuite/c-c++-common/cilk-plus/PS/for2.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O3 -fcilkplus" } */
-
-// Test storage classes in the initialization of a <#pragma simd> for
-// loop.
-
-int *a, *b;
-
-void foo()
-{
-#pragma simd
-  for (static int foo=5; foo < 10; ++foo)
-    a[foo] = b[foo];
-  /* { dg-error "declaration of static variable" "storage class1" { target 
*-*-* } 12 } */
-  /* { dg-error "induction variable cannot be static" "storage class2" { 
target *-*-* } 12 } */
-
-  static int bar;
-#pragma simd
-  for (bar=0; bar < 1000; ++bar) /* { dg-error "induction variable cannot be 
static" } */
-    a[bar] = bar;
-
-#pragma simd
-  for (extern int var=0; var < 1000; ++var)
-    a[var] = var;
-  /* { dg-error "has both 'extern' and initializer" "extern" { target *-*-* } 
23 } */
-  /* { dg-error "declaration of static variable" "" { target *-*-* } 23 } */
-  /* { dg-error "induction variable cannot be static" "" { target *-*-* } 23 } 
*/
-
-  extern int extvar;
-#pragma simd
-  for (extvar = 0; extvar < 1000; ++extvar) /* { dg-error "induction variable 
cannot be extern" } */
-    b[extvar] = a[extvar];
-
-  // This seems like it should be ok.
-  // Must check with standards people.
-#pragma simd
-  for (auto int autoi = 0; autoi < 1000; ++autoi)
-    b[autoi] = a[autoi] * 2;
-  // Similarly here.
-  auto int autoj;
-#pragma simd
-  for (auto int autoj = 0; autoj < 1000; ++autoj)
-    b[autoj] = a[autoj] * 2;
-
-  register int regi;
-#pragma simd
-  for (regi = 0; regi < 1000; ++regi) /* { dg-error "induction variable cannot 
be declared register" } */
-    b[regi] = a[regi] * 2;
-
-#pragma simd
-  for (register int regj = 0; regj < 1000; ++regj) /* { dg-error "induction 
variable cannot be declared register" } */
-    b[regj] = a[regj] * 2;
-
-  volatile int vi;
-#pragma simd
-  for (vi=0; vi<1000; ++vi) /* { dg-error "induction variable cannot be 
volatile" } */
-    a[vi] = b[vi];
-
-#pragma simd
-  for (volatile int vj=0; vj<1000; ++vj) /* { dg-error "induction variable 
cannot be volatile" } */
-    a[vj] = b[vj];
-
-#pragma simd
-  for (const int ci=0; ci<1000; ++ci) /* { dg-error "increment of read-only 
var" } */
-    a[ci] = b[ci];
-}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/for2.C 
b/gcc/testsuite/g++.dg/cilk-plus/for2.C
new file mode 100644
index 0000000..d30e057
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/for2.C
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+// Test storage classes in the initialization of a <#pragma simd> for
+// loop.
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd
+  for (static int tt=5; tt < 10; ++tt) /* { dg-error "storage class is not 
allowed" } */
+    a[tt] = b[tt];
+
+#pragma simd
+  for (extern int var=0; var < 1000; ++var) /* { dg-error "storage class is 
not allowed" } */
+    a[var] = var;
+
+#pragma simd
+  for (register int regj = 0; regj < 1000; ++regj) /* { dg-error "storage 
class is not allowed" } */
+    b[regj] = a[regj] * 2;
+
+#pragma simd
+  for (volatile int vj=0; vj<1000; ++vj) /* { dg-error "induction variable 
cannot be volatile" } */
+    a[vj] = b[vj];
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/for2.c 
b/gcc/testsuite/gcc.dg/cilk-plus/for2.c
new file mode 100644
index 0000000..dc0a41e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/for2.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcilkplus" } */
+
+// Test storage classes in the initialization of a <#pragma simd> for
+// loop.
+
+int *a, *b;
+
+void foo()
+{
+#pragma simd
+  for (static int foo=5; foo < 10; ++foo)
+    a[foo] = b[foo];
+  /* { dg-error "declaration of static variable" "storage class1" { target 
*-*-* } 12 } */
+  /* { dg-error "induction variable cannot be static" "storage class2" { 
target *-*-* } 12 } */
+
+  static int bar;
+#pragma simd
+  for (bar=0; bar < 1000; ++bar) /* { dg-error "induction variable cannot be 
static" } */
+    a[bar] = bar;
+
+#pragma simd
+  for (extern int var=0; var < 1000; ++var)
+    a[var] = var;
+  /* { dg-error "has both 'extern' and initializer" "extern" { target *-*-* } 
23 } */
+  /* { dg-error "declaration of static variable" "" { target *-*-* } 23 } */
+  /* { dg-error "induction variable cannot be static" "" { target *-*-* } 23 } 
*/
+
+  extern int extvar;
+#pragma simd
+  for (extvar = 0; extvar < 1000; ++extvar) /* { dg-error "induction variable 
cannot be extern" } */
+    b[extvar] = a[extvar];
+
+  // This seems like it should be ok.
+  // Must check with standards people.
+#pragma simd
+  for (auto int autoi = 0; autoi < 1000; ++autoi)
+    b[autoi] = a[autoi] * 2;
+  // Similarly here.
+  auto int autoj;
+#pragma simd
+  for (auto int autoj = 0; autoj < 1000; ++autoj)
+    b[autoj] = a[autoj] * 2;
+
+  register int regi;
+#pragma simd
+  for (regi = 0; regi < 1000; ++regi) /* { dg-error "induction variable cannot 
be declared register" } */
+    b[regi] = a[regi] * 2;
+
+#pragma simd
+  for (register int regj = 0; regj < 1000; ++regj) /* { dg-error "induction 
variable cannot be declared register" } */
+    b[regj] = a[regj] * 2;
+
+  volatile int vi;
+#pragma simd
+  for (vi=0; vi<1000; ++vi) /* { dg-error "induction variable cannot be 
volatile" } */
+    a[vi] = b[vi];
+
+#pragma simd
+  for (volatile int vj=0; vj<1000; ++vj) /* { dg-error "induction variable 
cannot be volatile" } */
+    a[vj] = b[vj];
+
+#pragma simd
+  for (const int ci=0; ci<1000; ++ci) /* { dg-error "increment of read-only 
var" } */
+    a[ci] = b[ci];
+}

Reply via email to