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)
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);
}
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);
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
TREE_TYPE (type1)))
{
- error_at (location, "comparing vectors with different "
- "element types");
- inform (location, "operand types are %qT and %qT", type0, type1);
+ if (complain & tf_error)
+ {
+ error_at (location, "comparing vectors with different "
+ "element types");
+ inform (location, "operand types are %qT and %qT",
+ type0, type1);
+ }
return error_mark_node;
}
if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1))
{
- error_at (location, "comparing vectors with different "
- "number of elements");
- inform (location, "operand types are %qT and %qT", type0, type1);
+ if (complain & tf_error)
+ {
+ error_at (location, "comparing vectors with different "
+ "number of elements");
+ inform (location, "operand types are %qT and %qT",
+ type0, type1);
+ }
return error_mark_node;
}
/* Always construct signed integer vector type. */
intt = c_common_type_for_size (GET_MODE_BITSIZE
(TYPE_MODE (TREE_TYPE (type0))), 0);
+ if (!intt)
+ {
+ if (complain & tf_error)
+ error_at (location, "could not find an integer type "
+ "of the same size as %qT", TREE_TYPE (type0));
+ return error_mark_node;
+ }
result_type = build_opaque_vector_type (intt,
TYPE_VECTOR_SUBPARTS (type0));
converted = 1;
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-std=gnu++1y -Wsign-conversion" } */
+
+typedef double vecd __attribute__((vector_size(4*sizeof(double))));
+typedef float vecf __attribute__((vector_size(8*sizeof(float))));
+typedef long vecl __attribute__((vector_size(4*sizeof(long))));
+typedef short vecs __attribute__((vector_size(8*sizeof(short))));
+typedef char vecc __attribute__((vector_size(16*sizeof(char))));
+
+auto f(vecf*a,float d,long long i){
+ return (*a<0)?d:i; // { dg-error "truncation" }
+}
+auto g(vecc*a){
+ return (*a<0)?3LL:42UL; // { dg-error "inferred scalar type" }
+}
+auto h(vecd*a){
+ return (*a<0)?'a':'c'; // { dg-error "inferred scalar type \[^\\n\]*double" }
+}
+auto i(vecc*a){
+ return (*a<0)?1:0.; // { dg-error "inferred scalar type" }
+}
+auto j(vecl*a,long i,unsigned long k){
+ return (*a<0)?i:k; // { dg-warning "may change the sign" }
+}