+2013-06-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57509
+ * c-common.h (c_build_vec_perm_expr): New complain argument.
+ * c-common.c (c_build_vec_perm_expr): Likewise.
+ Use save_expr also in C++.
+
2013-06-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
* c-common.c (c_common_nodes_and_builtins): Use cxx11 in lieu of cxx0x.
an implementation accident and this semantics is not guaranteed to
the user. */
tree
-c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
+c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask,
+ bool complain)
{
tree ret;
bool wrap = true;
if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE)
{
- error_at (loc, "__builtin_shuffle last argument must "
- "be an integer vector");
+ if (complain)
+ error_at (loc, "__builtin_shuffle last argument must "
+ "be an integer vector");
return error_mark_node;
}
if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE)
{
- error_at (loc, "__builtin_shuffle arguments must be vectors");
+ if (complain)
+ error_at (loc, "__builtin_shuffle arguments must be vectors");
return error_mark_node;
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1)))
{
- error_at (loc, "__builtin_shuffle argument vectors must be of "
- "the same type");
+ if (complain)
+ error_at (loc, "__builtin_shuffle argument vectors must be of "
+ "the same type");
return error_mark_node;
}
&& TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1))
!= TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
{
- error_at (loc, "__builtin_shuffle number of elements of the "
- "argument vector(s) and the mask vector should "
- "be the same");
+ if (complain)
+ error_at (loc, "__builtin_shuffle number of elements of the "
+ "argument vector(s) and the mask vector should "
+ "be the same");
return error_mark_node;
}
if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))))
!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))))
{
- error_at (loc, "__builtin_shuffle argument vector(s) inner type "
- "must have the same size as inner type of the mask");
+ if (complain)
+ error_at (loc, "__builtin_shuffle argument vector(s) inner type "
+ "must have the same size as inner type of the mask");
return error_mark_node;
}
mask = c_fully_fold (mask, false, &maybe_const);
wrap &= maybe_const;
}
+ else if (two_arguments)
+ v1 = v0 = save_expr (v0);
ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
extern bool vector_targets_convertible_p (const_tree t1, const_tree t2);
extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note);
-extern tree c_build_vec_perm_expr (location_t, tree, tree, tree);
+extern tree c_build_vec_perm_expr (location_t, tree, tree, tree, bool = true);
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
+2013-06-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57509
+ * typeck.c (cp_build_vec_perm_expr): New function.
+ * cp-tree.h: Declare it.
+ * parser.c (cp_parser_postfix_expression): Call it.
+ * pt.c (tsubst_copy): Handle VEC_PERM_EXPR.
+ (tsubst_copy_and_build): Likewise.
+
2013-06-27 Marc Glisse <marc.glisse@inria.fr>
PR c++/57172
extern tree cp_build_binary_op (location_t,
enum tree_code, tree, tree,
tsubst_flags_t);
+extern tree build_x_vec_perm_expr (location_t,
+ tree, tree, tree,
+ tsubst_flags_t);
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
extern tree build_simple_component_ref (tree, tree);
extern tree build_ptrmemfunc_access_expr (tree, tree);
mark_exp_read (p);
if (vec->length () == 2)
- return c_build_vec_perm_expr (loc, (*vec)[0], NULL_TREE, (*vec)[1]);
+ return build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE, (*vec)[1],
+ tf_warning_or_error);
else if (vec->length () == 3)
- return c_build_vec_perm_expr (loc, (*vec)[0], (*vec)[1], (*vec)[2]);
+ return build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1], (*vec)[2],
+ tf_warning_or_error);
else
{
error_at (loc, "wrong number of arguments to "
case COND_EXPR:
case MODOP_EXPR:
case PSEUDO_DTOR_EXPR:
+ case VEC_PERM_EXPR:
{
r = build_nt
(code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
case PAREN_EXPR:
RETURN (finish_parenthesized_expr (RECUR (TREE_OPERAND (t, 0))));
+ case VEC_PERM_EXPR:
+ RETURN (build_x_vec_perm_expr (input_location,
+ RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
+ complain));
+
default:
/* Handle Objective-C++ constructs, if appropriate. */
{
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)
+ || 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);
+}
\f
/* Return a tree for the sum or difference (RESULTCODE says which)
of pointer PTROP and integer INTOP. */
+2013-06-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/57509
+ * g++.dg/ext/pr57509.C: New file.
+
2013-06-27 Jakub Jelinek <jakub@redhat.com>
PR target/57623
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-std=c++11" } */
+
+template <bool> struct enable_if {};
+template <> struct enable_if<true> {typedef void type;};
+template <class T> void f (T& v) { v = __builtin_shuffle (v, v); }
+template <class T> void g (T) {}
+template <class T> auto g (T x) -> typename enable_if<sizeof(__builtin_shuffle(x,x))!=2>::type {}
+typedef int v4i __attribute__((vector_size(4*sizeof(int))));
+typedef float v4f __attribute__((vector_size(4*sizeof(float))));
+int main(){
+ v4i a = {1,2,3,0};
+ f(a);
+ v4f b = {1,2,3,0};
+ g(b);
+}