Hi!

On ia32, we don't support __int128, nor mode (TI) integers, but we do
support 128-bit __float128 and (generic) vectors containing it.  The result
of a comparison of such vectors is supposed to be integral vector with the
same element size, but we really don't want to allow one in this case,
it would be a loophole for full support of __int128/mode(TI), just do:
typedef __float128 V __attribute__ ((__vector_size__ (2 * sizeof 
(__float128))));
extern V v;
typedef typeof ((v != 0)[0]) my_int128;
and suddenly you have __int128.

The C++ errors out in this case, you can use such floating point vectors,
but can't use them in comparisons, the C FE instead just segfaulted.

Fixed thusly, making the C FE consistent with what C++ FE does,
bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-03-21  Jakub Jelinek  <ja...@redhat.com>

        PR c/84999
        * c-typeck.c (build_binary_op): If c_common_type_for_size fails when
        building vector comparison, diagnose it and return error_mark_node.

        * c-c++-common/pr84999.c: New test.

--- gcc/c/c-typeck.c.jj 2018-03-15 08:37:11.640779243 +0100
+++ gcc/c/c-typeck.c    2018-03-21 14:01:25.088183657 +0100
@@ -11504,6 +11504,13 @@ build_binary_op (location_t location, en
           intt = c_common_type_for_size (GET_MODE_BITSIZE
                                         (SCALAR_TYPE_MODE
                                          (TREE_TYPE (type0))), 0);
+         if (!intt)
+           {
+             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;
@@ -11665,6 +11672,13 @@ build_binary_op (location_t location, en
           intt = c_common_type_for_size (GET_MODE_BITSIZE
                                         (SCALAR_TYPE_MODE
                                          (TREE_TYPE (type0))), 0);
+         if (!intt)
+           {
+             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;
--- gcc/testsuite/c-c++-common/pr84999.c.jj     2018-03-21 14:34:12.819329771 
+0100
+++ gcc/testsuite/c-c++-common/pr84999.c        2018-03-21 14:32:37.816361905 
+0100
@@ -0,0 +1,12 @@
+/* PR c/84999 */
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "" } */
+
+typedef __float128 V __attribute__ ((__vector_size__ (2 * sizeof 
(__float128))));
+V a;
+typeof (a != 0) b;     /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */
+typeof (a == 0) c;     /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */
+typeof (a < 0) d;      /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */
+typeof (a <= 0) e;     /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */
+typeof (a > 0) f;      /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */
+typeof (a >= 0) g;     /* { dg-error "could not find an integer type of the 
same size as" "" { target ia32 } } */

        Jakub

Reply via email to