diff mbox

[C++] PR59378: __builtin_shuffle in templates

Message ID alpine.DEB.2.02.1401011908240.25026@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse Jan. 1, 2014, 6:14 p.m. UTC
Hello,

this patch makes build_x_vec_perm_expr more similar to the other build_x_* 
functions (I don't know why I had imagined it wouldn't be necessary).

Bootstrap+testsuite on x86_64-unknown-linux-gnu.

2014-01-01  Marc Glisse  <marc.glisse@inria.fr>

 	PR c++/59378
gcc/cp/
 	* typeck.c (build_x_vec_perm_expr): Handle non-dependent arguments
 	in templates.
gcc/testsuite/
 	* g++.dg/ext/pr59378.C: New file.

Comments

Jason Merrill Jan. 2, 2014, 9:32 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 206274)
+++ gcc/cp/typeck.c	(working copy)
@@ -4937,26 +4937,39 @@  cp_build_binary_op (location_t location,
   return result;
 }
 
 /* Build a VEC_PERM_EXPR.
    This is a simple wrapper for c_build_vec_perm_expr.  */
 tree
 build_x_vec_perm_expr (location_t loc,
 			tree arg0, tree arg1, tree arg2,
 			tsubst_flags_t complain)
 {
-  if (processing_template_decl
-      && (type_dependent_expression_p (arg0)
+  tree orig_arg0 = arg0;
+  tree orig_arg1 = arg1;
+  tree orig_arg2 = arg2;
+  if (processing_template_decl)
+    {
+      if (type_dependent_expression_p (arg0)
 	  || type_dependent_expression_p (arg1)
-	  || type_dependent_expression_p (arg2)))
-    return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
-  return c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
+	  || type_dependent_expression_p (arg2))
+	return build_min_nt_loc (loc, VEC_PERM_EXPR, arg0, arg1, arg2);
+      arg0 = build_non_dependent_expr (arg0);
+      if (arg1)
+	arg1 = build_non_dependent_expr (arg1);
+      arg2 = build_non_dependent_expr (arg2);
+    }
+  tree exp = c_build_vec_perm_expr (loc, arg0, arg1, arg2, complain & tf_error);
+  if (processing_template_decl && exp != error_mark_node)
+    return build_min_non_dep (VEC_PERM_EXPR, exp, orig_arg0,
+			      orig_arg1, orig_arg2);
+  return exp;
 }
 
 /* Return a tree for the sum or difference (RESULTCODE says which)
    of pointer PTROP and integer INTOP.  */
 
 static tree
 cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
 		    tsubst_flags_t complain)
 {
   tree res_type = TREE_TYPE (ptrop);
Index: gcc/testsuite/g++.dg/ext/pr59378.C
===================================================================
--- gcc/testsuite/g++.dg/ext/pr59378.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/pr59378.C	(working copy)
@@ -0,0 +1,8 @@ 
+// { dg-do compile }
+typedef int v4si __attribute__ ((vector_size (4*sizeof(int))));
+template<int C>
+void traverse(v4si& bounds){
+  v4si m = {0,1,2,3};
+  bounds = __builtin_shuffle(bounds, m);
+}
+template void traverse<0>(v4si&);