Hello,
as discussed in the PR, I did not add a sequence point, it can be done
later if we decide so (the other direction would be bad), but if we ever
do I believe we should add one to ?: at the same time.
For the mixed 'scalar vector', I chose to implement it with a branch,
since we can, it made sense to me to give it semantics closer to
scalar scalar, while 'vector scalar' gets the same semantics as
'vector vector' because there is no choice. So ab is always
equivalent to a?(b?T:F):F where T and F are vectors of the right type.
I replaced vector27, it was mostly a placeholder. I should probably remove
vector9 instead of updating it, it is pretty useless now.
I swapped save_expr and convert because gratuitously repeating the
conversion as many times as there are elements in the vector makes the
dumps quite horrible (and wastes compilation time).
Bootstrap+testsuite on x86_64-linux-gnu.
2014-08-18 Marc Glisse marc.gli...@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.
--
Marc GlisseIndex: gcc/c-family/c-common.c
===
--- gcc/c-family/c-common.c (revision 214073)
+++ gcc/c-family/c-common.c (working copy)
@@ -1663,20 +1663,24 @@ warn_logical_operator (location_t locati
if (CONSTANT_CLASS_P (op_left) || CONSTANT_CLASS_P (op_right))
return;
/* This warning only makes sense with logical operands. */
if (!(truth_value_p (TREE_CODE (op_left))
|| INTEGRAL_TYPE_P (TREE_TYPE (op_left)))
|| !(truth_value_p (TREE_CODE (op_right))
|| INTEGRAL_TYPE_P (TREE_TYPE (op_right
return;
+ /* The range computations only work with scalars. */
+ if (VECTOR_TYPE_P (TREE_TYPE (op_left))
+ || VECTOR_TYPE_P (TREE_TYPE (op_right)))
+return;
/* We first test whether either side separately is trivially true
(with OR) or trivially false (with AND). If so, do not warn.
This is a common idiom for testing ranges of data types in
portable code. */
lhs = make_range (op_left, in0_p, low0, high0, strict_overflow_p);
if (!lhs)
return;
if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
Index: gcc/cp/typeck.c
===
--- gcc/cp/typeck.c (revision 214073)
+++ gcc/cp/typeck.c (working copy)
@@ -4061,32 +4061,32 @@ cp_build_binary_op (location_t location,
{
enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1,
complain tf_error);
switch (convert_flag)
{
case stv_error:
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);
converted = 1;
break;
}
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);
converted = 1;
break;
}
default:
break;
}
}
@@ -4207,25 +4207,63 @@ cp_build_binary_op (location_t location,
|| (TREE_CODE (op1) == INTEGER_CST
! integer_all_onesp (op1)));
common = 1;
}
break;
case TRUTH_ANDIF_EXPR:
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 =