aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2013-07-14 10:36:47 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2013-07-14 08:36:47 +0000
commit07298ffd6f7c2d2623272bba009a23750db12397 (patch)
tree9d42f5227429601994deb716a51f062f0728c539 /gcc/cp/call.c
parent52d676b6c27f1c160c82251559606beec8089384 (diff)
downloadgcc-07298ffd6f7c2d2623272bba009a23750db12397.zip
gcc-07298ffd6f7c2d2623272bba009a23750db12397.tar.gz
gcc-07298ffd6f7c2d2623272bba009a23750db12397.tar.bz2
call.c (build_conditional_expr_1): Handle the case with 1 vector and 2 scalars.
2013-07-14 Marc Glisse <marc.glisse@inria.fr> gcc/cp/ * call.c (build_conditional_expr_1): Handle the case with 1 vector and 2 scalars. Call save_expr before building a vector. * typeck.c (cp_build_binary_op): Check complain before complaining. gcc/testsuite/ * g++.dg/ext/vector19.C: Adapt. * g++.dg/ext/vector23.C: New testcase. From-SVN: r200947
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 02daf82..3bb90ef 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4405,10 +4405,54 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
if (TREE_CODE (arg2_type) != VECTOR_TYPE
&& TREE_CODE (arg3_type) != VECTOR_TYPE)
{
- if (complain & tf_error)
- error_at (loc, "at least one operand of a vector conditional "
- "operator must be a vector");
- return error_mark_node;
+ /* Rely on the error messages of the scalar version. */
+ tree scal = build_conditional_expr_1 (loc, integer_one_node,
+ orig_arg2, orig_arg3, complain);
+ if (scal == error_mark_node)
+ return error_mark_node;
+ tree stype = TREE_TYPE (scal);
+ tree ctype = TREE_TYPE (arg1_type);
+ if (TYPE_SIZE (stype) != TYPE_SIZE (ctype)
+ || (!INTEGRAL_TYPE_P (stype) && !SCALAR_FLOAT_TYPE_P (stype)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "inferred scalar type %qT is not an integer or "
+ "floating point type of the same size as %qT", stype,
+ COMPARISON_CLASS_P (arg1)
+ ? TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+ : ctype);
+ return error_mark_node;
+ }
+
+ tree vtype = build_opaque_vector_type (stype,
+ TYPE_VECTOR_SUBPARTS (arg1_type));
+ /* We could pass complain & tf_warning to unsafe_conversion_p,
+ but the warnings (like Wsign-conversion) have already been
+ given by the scalar build_conditional_expr_1. We still check
+ unsafe_conversion_p to forbid truncating long long -> float. */
+ if (unsafe_conversion_p (stype, arg2, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qT to vector %qT "
+ "involves truncation", arg2_type, vtype);
+ return error_mark_node;
+ }
+ if (unsafe_conversion_p (stype, arg3, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qT to vector %qT "
+ "involves truncation", arg3_type, vtype);
+ return error_mark_node;
+ }
+
+ arg2 = cp_convert (stype, arg2, complain);
+ arg2 = save_expr (arg2);
+ arg2 = build_vector_from_val (vtype, arg2);
+ arg2_type = vtype;
+ arg3 = cp_convert (stype, arg3, complain);
+ arg3 = save_expr (arg3);
+ arg3 = build_vector_from_val (vtype, arg3);
+ arg3_type = vtype;
}
if ((TREE_CODE (arg2_type) == VECTOR_TYPE)
@@ -4424,6 +4468,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
return error_mark_node;
case stv_firstarg:
{
+ arg2 = save_expr (arg2);
arg2 = convert (TREE_TYPE (arg3_type), arg2);
arg2 = build_vector_from_val (arg3_type, arg2);
arg2_type = TREE_TYPE (arg2);
@@ -4431,6 +4476,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
}
case stv_secondarg:
{
+ arg3 = save_expr (arg3);
arg3 = convert (TREE_TYPE (arg2_type), arg3);
arg3 = build_vector_from_val (arg2_type, arg3);
arg3_type = TREE_TYPE (arg3);