aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2014-10-03 21:57:01 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2014-10-03 19:57:01 +0000
commit3c9aabbde58e5c540b0718c0a585e3ca97910317 (patch)
tree99d9326c06a03358bcb02cde8335ee8324fd1bf5 /gcc/cp
parentf9bb202b35f949eecb48adf75f9a0c5b117978d2 (diff)
downloadgcc-3c9aabbde58e5c540b0718c0a585e3ca97910317.zip
gcc-3c9aabbde58e5c540b0718c0a585e3ca97910317.tar.gz
gcc-3c9aabbde58e5c540b0718c0a585e3ca97910317.tar.bz2
re PR c++/54427 (Expose more vector extensions)
2014-10-03 Marc Glisse <marc.glisse@inria.fr> PR c++/54427 PR c++/57198 PR c++/58845 gcc/c-family/ * c-common.c (warn_logical_operator): Punt for vectors. gcc/cp/ * typeck.c (cp_build_binary_op): save_expr after convert to save redundant operations. [TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors. (cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise. gcc/ * doc/extend.texi (Vector Extensions): Document &&, ||, ! in C++. gcc/testsuite/ * g++.dg/ext/vector9.C: Update, not an error anymore. * g++.dg/ext/vector27.C: Replace with new test. * g++.dg/ext/vector28.C: New file. * g++.dg/other/error23.C: Update to a different error. From-SVN: r215872
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/typeck.c51
2 files changed, 56 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7a703aa..c0b6fb5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2014-10-03 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ PR c++/57198
+ PR c++/58845
+ * typeck.c (cp_build_binary_op): save_expr after convert to save
+ redundant operations.
+ [TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR]: Handle vectors.
+ (cp_build_unary_op) [TRUTH_NOT_EXPR]: Likewise.
+
2014-10-03 Jason Merrill <jason@redhat.com>
* decl.c (start_decl): Complain about static/thread_local vars
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 61d52bd..6a357bf 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4045,8 +4045,8 @@ cp_build_binary_op (location_t location,
return error_mark_node;
case stv_firstarg:
{
- op0 = save_expr (op0);
op0 = convert (TREE_TYPE (type1), op0);
+ op0 = save_expr (op0);
op0 = build_vector_from_val (type1, op0);
type0 = TREE_TYPE (op0);
code0 = TREE_CODE (type0);
@@ -4055,8 +4055,8 @@ cp_build_binary_op (location_t location,
}
case stv_secondarg:
{
- op1 = save_expr (op1);
op1 = convert (TREE_TYPE (type0), op1);
+ op1 = save_expr (op1);
op1 = build_vector_from_val (type0, op1);
type1 = TREE_TYPE (op1);
code1 = TREE_CODE (type1);
@@ -4191,11 +4191,49 @@ cp_build_binary_op (location_t location,
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
- if (VECTOR_TYPE_P (type0) || VECTOR_TYPE_P (type1))
+ if (!VECTOR_TYPE_P (type0) && VECTOR_TYPE_P (type1))
{
- sorry ("logical operation on vector type");
- return error_mark_node;
+ if (!COMPARISON_CLASS_P (op1))
+ op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
+ build_zero_cst (type1), complain);
+ if (code == TRUTH_ANDIF_EXPR)
+ {
+ tree z = build_zero_cst (TREE_TYPE (op1));
+ return build_conditional_expr (location, op0, op1, z, complain);
+ }
+ else if (code == TRUTH_ORIF_EXPR)
+ {
+ tree m1 = build_all_ones_cst (TREE_TYPE (op1));
+ return build_conditional_expr (location, op0, m1, op1, complain);
+ }
+ else
+ gcc_unreachable ();
}
+ if (VECTOR_TYPE_P (type0))
+ {
+ if (!COMPARISON_CLASS_P (op0))
+ op0 = cp_build_binary_op (EXPR_LOCATION (op0), NE_EXPR, op0,
+ build_zero_cst (type0), complain);
+ if (!VECTOR_TYPE_P (type1))
+ {
+ tree m1 = build_all_ones_cst (TREE_TYPE (op0));
+ tree z = build_zero_cst (TREE_TYPE (op0));
+ op1 = build_conditional_expr (location, op1, z, m1, complain);
+ }
+ else if (!COMPARISON_CLASS_P (op1))
+ op1 = cp_build_binary_op (EXPR_LOCATION (op1), NE_EXPR, op1,
+ build_zero_cst (type1), complain);
+
+ if (code == TRUTH_ANDIF_EXPR)
+ code = BIT_AND_EXPR;
+ else if (code == TRUTH_ORIF_EXPR)
+ code = BIT_IOR_EXPR;
+ else
+ gcc_unreachable ();
+
+ return cp_build_binary_op (location, code, op0, op1, complain);
+ }
+
result_type = boolean_type_node;
break;
@@ -5685,6 +5723,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
break;
case TRUTH_NOT_EXPR:
+ if (VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg)))
+ return cp_build_binary_op (input_location, EQ_EXPR, arg,
+ build_zero_cst (TREE_TYPE (arg)), complain);
arg = perform_implicit_conversion (boolean_type_node, arg,
complain);
val = invert_truthvalue_loc (input_location, arg);