Patchwork [cilkplus] pragma simd C++: fix more testcases

login
register
mail settings
Submitter Aldy Hernandez
Date June 10, 2013, 6:44 p.m.
Message ID <51B61E82.3030507@redhat.com>
Download mbox | patch
Permalink /patch/250336/
State New
Headers show

Comments

Aldy Hernandez - June 10, 2013, 6:44 p.m.
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.

Patch

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];
+}