+2019-12-23 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR c++/92789
+ * typeck.c (structural_comptypes): Make sure that two vector types
+ agree on gnu_vector_type_p.
+
2019-12-23 Richard Sandiford <richard.sandiford@arm.com>
* cvt.c (ocp_convert): Apply rvalue to the source of vector
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;
+2019-12-23 Richard Sandiford <richard.sandiford@arm.com>
+
+ 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 <richard.sandiford@arm.com>
* g++.dg/ext/vector39.C: New test.
// 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.
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'} }
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.
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.
{ 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]; }
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} }
(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} }
// 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'} }
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; }
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} }
(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} }
// 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'} }
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; }