call.c (build_conditional_expr_1): Handle the case with 1 vector and 2 scalars.
authorMarc Glisse <marc.glisse@inria.fr>
Sun, 14 Jul 2013 08:36:47 +0000 (10:36 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Sun, 14 Jul 2013 08:36:47 +0000 (08:36 +0000)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vector19.C
gcc/testsuite/g++.dg/ext/vector23.C [new file with mode: 0644]

index 3cf5e77..b7de099 100644 (file)
@@ -1,3 +1,9 @@
+2013-07-14  Marc Glisse  <marc.glisse@inria.fr>
+
+       * 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.
+
 2013-07-13  Lubos Lunak  <l.lunak@suse.cz>
 
        PR c++/55203
index 02daf82..3bb90ef 100644 (file)
@@ -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);
index 1d504ad..ef781a3 100644 (file)
@@ -4535,23 +4535,38 @@ cp_build_binary_op (location_t location,
          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;
index 41cea55..8f2d5a9 100644 (file)
@@ -1,3 +1,8 @@
+2013-07-14  Marc Glisse  <marc.glisse@inria.fr>
+
+       * g++.dg/ext/vector19.C: Adapt.
+       * g++.dg/ext/vector23.C: New testcase.
+
 2013-07-12  Michael Matz  <matz@suse.de>
 
        PR middle-end/55771
index ace1c64..4fd937f 100644 (file)
@@ -37,8 +37,7 @@ void j (vec2 *x, vec2 *y, vec2 *z, vec *t)
   *x = (*y < *z) ? *x : 4.2; /* { dg-error "" } */
   *y = (*x < *z) ? 2.5 : *y; /* { dg-error "" } */
   *t = *t ? *t : *t; /* { dg-error "" } */
-  *z = (*x < *z) ? '1' : '0'; /* { dg-error "" } */
-  // The last one may eventually be accepted.
+  *z = (*x < *z) ? '1' : '0';
 }
 
 template <class A, class B>
diff --git a/gcc/testsuite/g++.dg/ext/vector23.C b/gcc/testsuite/g++.dg/ext/vector23.C
new file mode 100644 (file)
index 0000000..4e18427
--- /dev/null
@@ -0,0 +1,24 @@
+/* { 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" }
+}