From: Richard Sandiford Date: Mon, 23 Dec 2019 09:43:46 +0000 (+0000) Subject: [C++] Make same_type_p return false for gnu_vector_type_p differences (PR 92789) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b8c9cc5100a8ba3aa56a6ffdd58d370cbb0134a4;p=gcc.git [C++] Make same_type_p return false for gnu_vector_type_p differences (PR 92789) As Jason pointed out in the review of the C++ gnu_vector_type_p patch: https://gcc.gnu.org/ml/gcc-patches/2019-12/msg00173.html the real fix for the XFAILs in acle/general-c++/gnu_vectors_*.C is to make same_type_p return false for two types if one is gnu_vector_type_p and the other isn't. This patch does that and fixes the fallout. Originally I'd tried to make it so that "X *" and "Y *" are interconvertible whenever X and Y are, and similarly for "X &" and "Y &". That doesn't fall out naturally though, and is different from how -flax-vector-conversions works. The patch therefore accepts all the consequences of making X and Y !same_type_p instead of trying to work around them. 2019-12-23 Richard Sandiford gcc/cp/ PR c++/92789 * typeck.c (structural_comptypes): Make sure that two vector types agree on gnu_vector_type_p. gcc/testsuite/ PR c++/92789 * g++.dg/ext/sve-sizeless-2.C (statements): Expect pointer difference and comparisons between GNU and non-GNU types to be rejected. Expect __is_same to be false for such pairs. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C: Remove XFAILs. Expect conversions between SVE vector pointers and GNU vector pointers to be rejected. Test references. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C: Likewise. From-SVN: r279717 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 720c3ee0e73..14c6d324580 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-12-23 Richard Sandiford + + PR c++/92789 + * typeck.c (structural_comptypes): Make sure that two vector types + agree on gnu_vector_type_p. + 2019-12-23 Richard Sandiford * cvt.c (ocp_convert): Apply rvalue to the source of vector diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d2f4a001e50..18c16857a82 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1425,7 +1425,8 @@ structural_comptypes (tree t1, tree t2, int strict) break; case VECTOR_TYPE: - if (maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)) + if (gnu_vector_type_p (t1) != gnu_vector_type_p (t2) + || maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)) || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))) return false; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 321d54b47fc..59fc56447ac 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2019-12-23 Richard Sandiford + + PR c++/92789 + * g++.dg/ext/sve-sizeless-2.C (statements): Expect pointer + difference and comparisons between GNU and non-GNU types + to be rejected. Expect __is_same to be false for such pairs. + * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C: Remove + XFAILs. Expect conversions between SVE vector pointers and + GNU vector pointers to be rejected. Test references. + * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C: Likewise. + 2019-12-23 Richard Sandiford * g++.dg/ext/vector39.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C index f6b9c319147..40b65d37f8a 100644 --- a/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C +++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-2.C @@ -183,8 +183,8 @@ statements (int n) // Pointer assignment. - gnu_sc_ptr = sve_sc_ptr; - sve_sc_ptr = gnu_sc_ptr; + gnu_sc_ptr = sve_sc_ptr; // { dg-error {invalid conversion from 'svint8_t\*' to 'int8x32_t\*'} } + sve_sc_ptr = gnu_sc_ptr; // { dg-error {invalid conversion from 'int8x32_t\*'[^\n]* to 'svint8_t\*'} } // Pointer arithmetic. @@ -197,8 +197,8 @@ statements (int n) sve_sc_ptr -= 0; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc_ptr -= 1; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc_ptr - sve_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } - gnu_sc_ptr - sve_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } - sve_sc_ptr - gnu_sc_ptr; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } + gnu_sc_ptr - sve_sc_ptr; // { dg-error {invalid operands of types 'int8x32_t\*'[^\n]* and 'svint8_t\*' to binary 'operator-'} } + sve_sc_ptr - gnu_sc_ptr; // { dg-error {invalid operands of types 'svint8_t\*' and 'int8x32_t\*'[^\n]* to binary 'operator-'} } sve_sc1 = sve_sc_ptr[0]; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } sve_sc1 = sve_sc_ptr[1]; // { dg-error {arithmetic on pointer to SVE type 'svint8_t'} } @@ -210,18 +210,18 @@ statements (int n) sve_sc_ptr <= &sve_sc1; sve_sc_ptr > &sve_sc1; sve_sc_ptr >= &sve_sc1; - gnu_sc_ptr == sve_sc_ptr; - gnu_sc_ptr != sve_sc_ptr; - gnu_sc_ptr < sve_sc_ptr; - gnu_sc_ptr <= sve_sc_ptr; - gnu_sc_ptr > sve_sc_ptr; - gnu_sc_ptr >= sve_sc_ptr; - sve_sc_ptr == gnu_sc_ptr; - sve_sc_ptr != gnu_sc_ptr; - sve_sc_ptr < gnu_sc_ptr; - sve_sc_ptr <= gnu_sc_ptr; - sve_sc_ptr > gnu_sc_ptr; - sve_sc_ptr >= gnu_sc_ptr; + gnu_sc_ptr == sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr != sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr < sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr <= sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr > sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + gnu_sc_ptr >= sve_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr == gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr != gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr < gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr <= gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr > gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } + sve_sc_ptr >= gnu_sc_ptr; // { dg-error {comparison between distinct pointer types [^\n]*lacks a cast} } // New and delete. @@ -243,8 +243,8 @@ statements (int n) 0 ? 0 : sve_sc1; // { dg-error {different types 'int' and 'svint8_t'} } 0 ? sve_sc1 : sve_sc1; 0 ? sve_sc_ptr : sve_sc_ptr; - 0 ? sve_sc_ptr : gnu_sc_ptr; - 0 ? gnu_sc_ptr : sve_sc_ptr; + 0 ? sve_sc_ptr : gnu_sc_ptr; // { dg-error {conditional expression between distinct pointer types [^\n]*lacks a cast} } + 0 ? gnu_sc_ptr : sve_sc_ptr; // { dg-error {conditional expression between distinct pointer types [^\n]*lacks a cast} } // Function arguments. @@ -321,11 +321,11 @@ statements (int n) { typedef int f[__is_pod (svint8_t) ? 1 : -1]; } { typedef int f[!__is_polymorphic (svint8_t) ? 1 : -1]; } { typedef int f[__is_same_as (svint8_t, svint8_t) ? 1 : -1]; } - { typedef int f[__is_same_as (svint8_t, int8x32_t) ? 1 : -1]; } - { typedef int f[__is_same_as (int8x32_t, svint8_t) ? 1 : -1]; } + { typedef int f[!__is_same_as (svint8_t, int8x32_t) ? 1 : -1]; } + { typedef int f[!__is_same_as (int8x32_t, svint8_t) ? 1 : -1]; } { typedef int f[__is_same_as (svint8_t *, svint8_t *) ? 1 : -1]; } - { typedef int f[__is_same_as (svint8_t *, int8x32_t *) ? 1 : -1]; } - { typedef int f[__is_same_as (int8x32_t *, svint8_t *) ? 1 : -1]; } + { typedef int f[!__is_same_as (svint8_t *, int8x32_t *) ? 1 : -1]; } + { typedef int f[!__is_same_as (int8x32_t *, svint8_t *) ? 1 : -1]; } { typedef int f[!__is_same_as (svint8_t, int) ? 1 : -1]; } { typedef int f[!__is_same_as (svint8_t, svint16_t) ? 1 : -1]; } { typedef int f[__is_trivial (svint8_t) ? 1 : -1]; } diff --git a/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C b/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C index d1da64c901b..f60ffe4a262 100644 --- a/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C +++ b/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_1.C @@ -36,14 +36,14 @@ f (svuint8_t sve_u1, svint8_t sve_s1, gnu_uint8_t init_gnu_u1 = 0; // { dg-error {cannot convert 'int' to 'gnu_uint8_t'[^\n]* in initialization} } gnu_uint8_t init_gnu_u2 = {}; - gnu_uint8_t init_gnu_u3 = { sve_u1 }; + gnu_uint8_t init_gnu_u3 = { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u4 = { gnu_u1 }; gnu_uint8_t init_gnu_u5 = { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u6 = { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u7 = { 0 }; gnu_uint8_t init_gnu_u8 = { sve_u1, sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u9 = { gnu_u1, gnu_u1 }; // { dg-error {cannot convert 'gnu_uint8_t'[^\n]* to 'unsigned char' in initialization} } - gnu_uint8_t init_gnu_u10 { sve_u1 }; + gnu_uint8_t init_gnu_u10 { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u11 { gnu_u1 }; gnu_uint8_t init_gnu_u12 { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u13 { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } @@ -69,7 +69,7 @@ f (svuint8_t sve_u1, svint8_t sve_s1, (gnu_uint8_t) {}; (gnu_uint8_t) { 0 }; - (gnu_uint8_t) { sve_u1 }; + (gnu_uint8_t) { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } (gnu_uint8_t) { gnu_u1 }; (gnu_uint8_t) { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } (gnu_uint8_t) { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } @@ -434,8 +434,8 @@ f (svuint8_t sve_u1, svint8_t sve_s1, // Conditional expressions. uc ? sve_u1 : sve_u1; - uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} "" { xfail *-*-* } } - uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} "" { xfail *-*-* } } + uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} } + uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} } uc ? gnu_u1 : gnu_u1; sve_u1 ? sve_u1 : sve_u1; // { dg-error {could not convert 'sve_u1' from 'svuint8_t' to 'bool'} } @@ -474,15 +474,29 @@ f (svuint8_t sve_u1, svint8_t sve_s1, static_assert(__is_literal_type(svuint8_t)); static_assert(__is_literal_type(gnu_uint8_t)); + // Pointers. + svuint8_t *sve_ptr1 = &sve_u1; - svuint8_t *sve_ptr2 = &gnu_u1; + svuint8_t *sve_ptr2 = &gnu_u1; // { dg-error {invalid conversion} } svuint8_t *sve_ptr3 = &sve_s1; // { dg-error {cannot convert 'svint8_t\*' to 'svuint8_t\*' in initialization} } svuint8_t *sve_ptr4 = &gnu_s1; // { dg-error {cannot convert 'gnu_int8_t\*'[^\n]* to 'svuint8_t\*' in initialization} } - gnu_uint8_t *gnu_ptr1 = &sve_u1; + gnu_uint8_t *gnu_ptr1 = &sve_u1; // { dg-error {invalid conversion} } gnu_uint8_t *gnu_ptr2 = &gnu_u1; gnu_uint8_t *gnu_ptr3 = &sve_s1; // { dg-error {cannot convert 'svint8_t\*' to 'gnu_uint8_t\*'} } gnu_uint8_t *gnu_ptr4 = &gnu_s1; // { dg-error {cannot convert 'gnu_int8_t\*'[^\n]* to 'gnu_uint8_t\*'} } + + // References. + + svuint8_t &sve_ref1 = sve_u1; + svuint8_t &sve_ref2 = gnu_u1; // { dg-error {cannot bind non-const lvalue reference} } + svuint8_t &sve_ref3 = sve_s1; // { dg-error {invalid initialization of reference of type 'svuint8_t\&' from expression of type 'svint8_t'} } + svuint8_t &sve_ref4 = gnu_s1; // { dg-error {invalid initialization of reference of type 'svuint8_t\&' from expression of type 'gnu_int8_t'} } + + gnu_uint8_t &gnu_ref1 = sve_u1; // { dg-error {cannot bind non-const lvalue reference} } + gnu_uint8_t &gnu_ref2 = gnu_u1; + gnu_uint8_t &gnu_ref3 = sve_s1; // { dg-error {invalid initialization of reference of type 'gnu_uint8_t\&} } + gnu_uint8_t &gnu_ref4 = gnu_s1; // { dg-error {invalid initialization of reference of type 'gnu_uint8_t\&} } } constexpr svuint8_t const1 (svuint8_t x) { return x; } diff --git a/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C b/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C index da4462b2421..30b2ca59d79 100644 --- a/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C +++ b/gcc/testsuite/g++.target/aarch64/sve/acle/general-c++/gnu_vectors_2.C @@ -36,14 +36,14 @@ f (svuint8_t sve_u1, svint8_t sve_s1, gnu_uint8_t init_gnu_u1 = 0; // { dg-error {cannot convert 'int' to 'gnu_uint8_t'[^\n]* in initialization} } gnu_uint8_t init_gnu_u2 = {}; - gnu_uint8_t init_gnu_u3 = { sve_u1 }; + gnu_uint8_t init_gnu_u3 = { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u4 = { gnu_u1 }; gnu_uint8_t init_gnu_u5 = { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u6 = { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u7 = { 0 }; gnu_uint8_t init_gnu_u8 = { sve_u1, sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u9 = { gnu_u1, gnu_u1 }; // { dg-error {cannot convert 'gnu_uint8_t'[^\n]* to 'unsigned char' in initialization} } - gnu_uint8_t init_gnu_u10 { sve_u1 }; + gnu_uint8_t init_gnu_u10 { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u11 { gnu_u1 }; gnu_uint8_t init_gnu_u12 { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } gnu_uint8_t init_gnu_u13 { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } @@ -69,7 +69,7 @@ f (svuint8_t sve_u1, svint8_t sve_s1, (gnu_uint8_t) {}; (gnu_uint8_t) { 0 }; - (gnu_uint8_t) { sve_u1 }; + (gnu_uint8_t) { sve_u1 }; // { dg-error {cannot convert 'svuint8_t' to 'unsigned char' in initialization} } (gnu_uint8_t) { gnu_u1 }; (gnu_uint8_t) { sve_s1 }; // { dg-error {cannot convert 'svint8_t' to 'unsigned char' in initialization} } (gnu_uint8_t) { gnu_s1 }; // { dg-error {cannot convert 'gnu_int8_t'[^\n]* to 'unsigned char' in initialization} } @@ -434,8 +434,8 @@ f (svuint8_t sve_u1, svint8_t sve_s1, // Conditional expressions. uc ? sve_u1 : sve_u1; - uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} "" { xfail *-*-* } } - uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} "" { xfail *-*-* } } + uc ? gnu_u1 : sve_u1; // { dg-error {operands to '\?:' have different types 'gnu_uint8_t'[^\n]* and 'svuint8_t'} } + uc ? sve_u1 : gnu_u1; // { dg-error {operands to '\?:' have different types 'svuint8_t' and 'gnu_uint8_t'} } uc ? gnu_u1 : gnu_u1; sve_u1 ? sve_u1 : sve_u1; // { dg-error {could not convert 'sve_u1' from 'svuint8_t' to 'bool'} } @@ -474,15 +474,29 @@ f (svuint8_t sve_u1, svint8_t sve_s1, static_assert(__is_literal_type(svuint8_t)); static_assert(__is_literal_type(gnu_uint8_t)); + // Pointers. + svuint8_t *sve_ptr1 = &sve_u1; - svuint8_t *sve_ptr2 = &gnu_u1; + svuint8_t *sve_ptr2 = &gnu_u1; // { dg-error {invalid conversion} } svuint8_t *sve_ptr3 = &sve_s1; // { dg-error {invalid conversion from 'svint8_t\*' to 'svuint8_t\*'} } svuint8_t *sve_ptr4 = &gnu_s1; // { dg-error {invalid conversion from 'gnu_int8_t\*'[^\n]* to 'svuint8_t\*'} } - gnu_uint8_t *gnu_ptr1 = &sve_u1; + gnu_uint8_t *gnu_ptr1 = &sve_u1; // { dg-error {invalid conversion} } gnu_uint8_t *gnu_ptr2 = &gnu_u1; gnu_uint8_t *gnu_ptr3 = &sve_s1; // { dg-error {invalid conversion from 'svint8_t\*' to 'gnu_uint8_t\*'} } gnu_uint8_t *gnu_ptr4 = &gnu_s1; // { dg-error {invalid conversion from 'gnu_int8_t\*'[^\n]* to 'gnu_uint8_t\*'} } + + // References. + + svuint8_t &sve_ref1 = sve_u1; + svuint8_t &sve_ref2 = gnu_u1; // { dg-error {cannot bind non-const lvalue reference} } + svuint8_t &sve_ref3 = sve_s1; // { dg-error {cannot bind non-const lvalue reference} } + svuint8_t &sve_ref4 = gnu_s1; // { dg-error {cannot bind non-const lvalue reference} } + + gnu_uint8_t &gnu_ref1 = sve_u1; // { dg-error {cannot bind non-const lvalue reference} } + gnu_uint8_t &gnu_ref2 = gnu_u1; + gnu_uint8_t &gnu_ref3 = sve_s1; // { dg-error {cannot bind non-const lvalue reference} } + gnu_uint8_t &gnu_ref4 = gnu_s1; // { dg-error {cannot bind non-const lvalue reference} } } constexpr svuint8_t const1 (svuint8_t x) { return x; }