diff mbox

Fix for PR c++/60269

Message ID BF230D13CA30DD48930C31D4099330003B024F4D@fmsmsx101.amr.corp.intel.com
State New
Headers show

Commit Message

Iyer, Balaji V Feb. 19, 2015, 3:39 a.m. UTC
Hello Everyone,
                Attached, please find a patch that is a fix for PR c++/60269. Tested on x86_64 and have no regression issues. Is this OK for trunk?

Thanks,

Balaji V. Iyer.


+2015-02-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       PR c++/60269
+       * parser.c (cp_parser_cilk_simd_vectorlength): Added a check for
+       template handling.  If so, then defer the validity checks to pt.c.
+       * pt.c (tsubst_omp_clauses): Added a check for invalid vectorlength
+       for Cilk Plus SIMD loops.
+

+2015-02-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       PR c++/60269
+       * g++.dg/cilk-plus/pr60269.C: New test.
+

Comments

Jakub Jelinek Feb. 19, 2015, 10:20 a.m. UTC | #1
On Thu, Feb 19, 2015 at 03:39:19AM +0000, Iyer, Balaji V wrote:
> Attached, please find a patch that is a fix for PR c++/60269. Tested on x86_64 and have no regression issues. Is this OK for trunk?

> +2015-02-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
> +
> +       PR c++/60269
> +       * parser.c (cp_parser_cilk_simd_vectorlength): Added a check for
> +       template handling.  If so, then defer the validity checks to pt.c.
> +       * pt.c (tsubst_omp_clauses): Added a check for invalid vectorlength
> +       for Cilk Plus SIMD loops.

That looks wrong to me.

> +	  if (flag_cilkplus && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_SAFELEN)
> +	    {
> +	      tree new_expr = OMP_CLAUSE_OPERAND (nc, 0);
> +	      if (!new_expr || new_expr == error_mark_node)
> +		;
> +	      else if (!TREE_TYPE (new_expr) || !TREE_CONSTANT (new_expr)
> +		  || !INTEGRAL_TYPE_P (TREE_TYPE (new_expr)))
> +		error ("vectorlength must be an integer constant");
> +	      else if (TREE_CONSTANT (new_expr) 
> +		       && exact_log2 (TREE_INT_CST_LOW (new_expr)) == -1)
> +		error ("vectorlength must be a power of 2");
> +	    }   

This won't affect just #pragma simd vectorlength (x) though, but also
#pragma omp simd safelen(x).  And for the latter it is certainly
undesirable, the checking is done in finish_omp_clauses.  flag_cilkplus
can be true even if it is an OpenMP construct.

So, there are 2 ways out of this IMHO.  Either you add some special flag
on the OMP_CLAUSE_SAFELEN clause, which will tell you it is a vectorlength,
and put this diagnostics, reworked to check for type_dependent_*, into
finish_omp_clauses (then you can also move the
cp_parser_cilk_simd_vectorlength diagnostics there).
Or, if you really want to do this in tsubst_omp_clauses, you'd need some
extra argument from the caller to tell you e.g. tree_code of the tree
containing the clauses (you could use the declare_simd argument for that
turned into enum tree_code, and pass FUNCTION_DECL for declare_simd?).
But of course you need to arrange for the case where you report invalid
vectorlength for the clause to be removed from the list of clauses,
otherwise finish_omp_clauses will complain on it again and might break error
recovery.

Testcase coverage should also include testcases for where the vectorlength
clause is invalid (both the conditions you report), both outside and inside
of templates.

	Jakub
diff mbox

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e0b455c..97ddee4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -33207,13 +33207,19 @@  cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
      error mark node then they would have emitted an error message.  */
   if (expr == error_mark_node)
     ;
-  else if (!TREE_TYPE (expr)
-	   || !TREE_CONSTANT (expr)
-	   || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
-    error_at (loc, "vectorlength must be an integer constant");
-  else if (TREE_CONSTANT (expr)
+  else if (!processing_template_decl 
+	   && (!TREE_TYPE (expr) || !TREE_CONSTANT (expr)
+	       || !INTEGRAL_TYPE_P (TREE_TYPE (expr))))
+    {
+      error_at (loc, "vectorlength must be an integer constant");
+      expr = error_mark_node;
+    }
+  else if (!processing_template_decl && TREE_CONSTANT (expr)
 	   && exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
-    error_at (loc, "vectorlength must be a power of 2");
+    {
+      error_at (loc, "vectorlength must be a power of 2");
+      expr = error_mark_node;
+    }
   else 
     {
       tree c;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9a00d0d..dc1bae8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13491,6 +13491,18 @@  tsubst_omp_clauses (tree clauses, bool declare_simd,
 	  OMP_CLAUSE_OPERAND (nc, 0)
 	    = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, 
 			   in_decl, /*integral_constant_expression_p=*/false);
+	  if (flag_cilkplus && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_SAFELEN)
+	    {
+	      tree new_expr = OMP_CLAUSE_OPERAND (nc, 0);
+	      if (!new_expr || new_expr == error_mark_node)
+		;
+	      else if (!TREE_TYPE (new_expr) || !TREE_CONSTANT (new_expr)
+		  || !INTEGRAL_TYPE_P (TREE_TYPE (new_expr)))
+		error ("vectorlength must be an integer constant");
+	      else if (TREE_CONSTANT (new_expr) 
+		       && exact_log2 (TREE_INT_CST_LOW (new_expr)) == -1)
+		error ("vectorlength must be a power of 2");
+	    }   
 	  break;
 	case OMP_CLAUSE_REDUCTION:
 	  if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (oc))
diff --git a/gcc/testsuite/g++.dg/cilk-plus/pr60269.C b/gcc/testsuite/g++.dg/cilk-plus/pr60269.C
new file mode 100644
index 0000000..fa0c25b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/pr60269.C
@@ -0,0 +1,17 @@ 
+// { dg-do compile }
+// { dg-options "-O3 -fcilkplus" } 
+
+template <int N>
+void foo (int *a, int *b, int *c)
+{
+#pragma simd vectorlength (N)
+    for (int i = 0; i < N; i++)
+          a[i] = b[i] * c[i];
+}
+
+void
+bar (int *a, int *b, int *c)
+{
+    foo <64> (a, b, c);
+}
+