summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-27 21:29:22 +0000
committerglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-27 21:29:22 +0000
commit68ea4406dc48c6ca3fa27969b498b763bcaf4e19 (patch)
tree37a7ba1615b56c5f026c57c7156e10579e63abcb
parent86990cac7cb5acd5d6edd28a56a59e18ae9c39a5 (diff)
downloadgcc-68ea4406dc48c6ca3fa27969b498b763bcaf4e19.tar.gz
2013-06-27 Marc Glisse <marc.glisse@inria.fr>
PR c++/57509 gcc/c-family/ * 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++. gcc/cp/ * 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. gcc/testsuite/ * g++.dg/ext/pr57509.C: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200495 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-common.c30
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/parser.c6
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/typeck.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/pr57509.C16
10 files changed, 87 insertions, 14 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index bc73a809a55..c9a4f70e8bc 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+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.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8b780c20845..8f7f5e52b0a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2260,7 +2260,8 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note)
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;
@@ -2280,22 +2281,25 @@ c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
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;
}
@@ -2304,17 +2308,19 @@ c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
&& 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;
}
@@ -2335,6 +2341,8 @@ c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
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);
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 625c3011460..6dfcffd7921 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -911,7 +911,7 @@ extern bool lvalue_p (const_tree);
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 *);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93e639e8687..4f74133c2e7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
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
* pt.c (more_specialized_fn): If both arguments are references,
give priority to an lvalue.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 00ee45013b3..4b2cd512f1c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6042,6 +6042,9 @@ extern tree check_return_expr (tree, bool *);
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);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ec8ad46dd44..ad2fe257731 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5691,9 +5691,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
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 "
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e2ffe7314c4..4ab64c9d826 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12464,6 +12464,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
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),
@@ -14628,6 +14629,13 @@ tsubst_copy_and_build (tree t,
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. */
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5b321ce5a7f..4a7f1f68c71 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4871,6 +4871,21 @@ 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)
+ || 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);
+}
/* Return a tree for the sum or difference (RESULTCODE says which)
of pointer PTROP and integer INTOP. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7bf618df1af..22b10523acb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/g++.dg/ext/pr57509.C b/gcc/testsuite/g++.dg/ext/pr57509.C
new file mode 100644
index 00000000000..d44ee81e091
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pr57509.C
@@ -0,0 +1,16 @@
+/* { 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);
+}