diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -772,3 +772,193 @@ } #endif } + +namespace vector_implicit_conversions { +// Test ext_vector_type builtin operators in the presence of implicit conversions + +typedef int __attribute__((ext_vector_type(4))) vec4i; + +struct vec4i_wrapper { + vec4i x; + + vec4i_wrapper(const vec4i& val): x(val) {} + operator vec4i() const { return x; } // expected-note 1+ {{candidate function}} +}; + +vec4i_wrapper operator| (const vec4i_wrapper& lhs, const vec4i_wrapper rhs) { return vec4i(lhs) | vec4i(rhs); } +vec4i_wrapper& operator|= (vec4i_wrapper& lhs, const vec4i_wrapper& rhs) { return lhs = lhs | rhs; } // #oreq_operator + +vec4i_wrapper test_compound_assignment_mixed(vec4i_wrapper a, vec4i b) { + // These are not accepted because the LHS isn't subject to conversions, so no built-in operators apply here + a += b; // expected-error{{no viable overloaded '+='}} + a -= b; // expected-error{{no viable overloaded '-='}} + a *= b; // expected-error{{no viable overloaded '*='}} + a /= b; // expected-error{{no viable overloaded '/='}} + a %= b; // expected-error{{no viable overloaded '%='}} + a &= b; // expected-error{{no viable overloaded '&='}} + // Note: This operator is explicitly defined above, so it is accpted via implicit conversions + a |= b; + a ^= b; // expected-error{{no viable overloaded '^='}} + a >>= b; // expected-error{{no viable overloaded '>>='}} + a <<= b; // expected-error{{no viable overloaded '<<='}} + + b += a; + b -= a; + b *= a; + b /= a; + // FIXME: Consistency for vector builtin operators with implicit conversions https://github.com/llvm/llvm-project/issues/62949 + b %= a; // expected-error{{invalid operands to binary expression}} + b &= a; // expected-error{{invalid operands to binary expression}} + b |= a; // expected-error{{invalid operands to binary expression}} + // expected-note@#oreq_operator{{candidate function not viable}} + b ^= a; // expected-error{{invalid operands to binary expression}} + b >>= a; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + b <<= a; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + + return a; +} + +vec4i_wrapper test_operators_mixed(vec4i_wrapper a, vec4i b) { + // The operator overload isn't defined, so this is implicitly: + // a = vec4i_wrapper(vec4i(a) + b) + a = a + b; + a = b + a; + a = a - b; + a = b - a; + a = a * b; + a = b * a; + a = a / b; + a = b / a; + // FIXME: Consistency for vector builtin operators with implicit conversions https://github.com/llvm/llvm-project/issues/62949 + a = a % b; // expected-error{{invalid operands to binary expression}} + a = b % a; // expected-error{{invalid operands to binary expression}} + + // Conditionals yield vectors of integers + vec4i c; + c = a == b; + c = b == a; + c = a != b; + c = b != a; + c = a <= b; + c = b <= a; + c = a >= b; + c = b >= a; + c = a < b; + c = b < a; + c = a > b; + c = b > a; + + a = a && b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{cannot convert between vector and non-scalar values}} + a = b && a; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{cannot convert between vector and non-scalar values}} + a = a || b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{cannot convert between vector and non-scalar values}} + a = b || a; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{cannot convert between vector and non-scalar values}} + + a = a & b; // expected-error{{invalid operands to binary expression}} + a = b & a; // expected-error{{invalid operands to binary expression}} + // Note: These have a user-defined operator overload which is being selected + a = a | b; + a = b | a; + a = a ^ b; // expected-error{{invalid operands to binary expression}} + a = b ^ a; // expected-error{{invalid operands to binary expression}} + a = a << b; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + a = b << a; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + a = a >> b; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + a = b >> a; // expected-error{{used type 'vec4i_wrapper' where integer is required}} + + return a; +} + +vec4i_wrapper test_operators_homogenous(vec4i_wrapper a, vec4i_wrapper b) { + // The operator overload isn't defined, so this is implicitly: + // a = vec4i_wrapper(vec4i(a) + vec4i(b)) + a = a + b; + a = a - b; + a = a * b; + a = a / b; + // FIXME: Consistency for vector builtin operators with implicit conversions https://github.com/llvm/llvm-project/issues/62949 + a = a % b; // expected-error{{invalid operands to binary expression}} + + // Conditionals yield vectors of integers + vec4i c; + c = a == b; + c = a != b; + c = a <= b; + c = a >= b; + c = a < b; + c = a > b; + + a = a && b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + a = a || b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + + a = a & b; // expected-error{{invalid operands to binary expression}} + // Note: This has a user-defined operator overload which is being selected + a = a | b; + a = a ^ b; // expected-error{{invalid operands to binary expression}} + a = a << b; // expected-error{{invalid operands to binary expression}} + a = a >> b; // expected-error{{invalid operands to binary expression}} + + return a; +} + +vec4i_wrapper test_operators_with_scalar(vec4i_wrapper a, int b) { + // The operator overload isn't defined, so this is implicitly: + // a = vec4i_wrapper(vec4i(a) + b) + // And b is implictly splatted + // FIXME: Consistency for vector builtin operators with implicit conversions https://github.com/llvm/llvm-project/issues/62949 + // FIXME: Provide vector/scalar builtin overloads https://github.com/llvm/llvm-project/issues/62869 + a = a + b; // expected-error{{invalid operands to binary expression}} + a = b + a; // expected-error{{invalid operands to binary expression}} + a = a - b; // expected-error{{invalid operands to binary expression}} + a = b - a; // expected-error{{invalid operands to binary expression}} + a = a * b; // expected-error{{invalid operands to binary expression}} + a = b * a; // expected-error{{invalid operands to binary expression}} + a = a / b; // expected-error{{invalid operands to binary expression}} + a = b / a; // expected-error{{invalid operands to binary expression}} + a = a % b; // expected-error{{invalid operands to binary expression}} + a = b % a; // expected-error{{invalid operands to binary expression}} + + // Conditionals yield vectors of integers + vec4i c; + c = a == b; // expected-error{{invalid operands to binary expression}} + c = b == a; // expected-error{{invalid operands to binary expression}} + c = a != b; // expected-error{{invalid operands to binary expression}} + c = b != a; // expected-error{{invalid operands to binary expression}} + c = a <= b; // expected-error{{invalid operands to binary expression}} + c = b <= a; // expected-error{{invalid operands to binary expression}} + c = a >= b; // expected-error{{invalid operands to binary expression}} + c = b >= a; // expected-error{{invalid operands to binary expression}} + c = a < b; // expected-error{{invalid operands to binary expression}} + c = b < a; // expected-error{{invalid operands to binary expression}} + c = a > b; // expected-error{{invalid operands to binary expression}} + c = b > a; // expected-error{{invalid operands to binary expression}} + + a = a && b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + a = b && a; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + a = a || b; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + a = b || a; // expected-error{{invalid operands to binary expression}} + // expected-error@-1{{no viable conversion from 'vec4i_wrapper' to 'bool'}} + + a = a & b; // expected-error{{invalid operands to binary expression}} + a = b & a; // expected-error{{invalid operands to binary expression}} + // Note: These have a user-defined operator overload which is being selected + a = a | b; + a = b | a; + a = a ^ b; // expected-error{{invalid operands to binary expression}} + a = b ^ a; // expected-error{{invalid operands to binary expression}} + a = a << b; // expected-error{{invalid operands to binary expression}} + a = b << a; // expected-error{{invalid operands to binary expression}} + a = a >> b; // expected-error{{invalid operands to binary expression}} + a = b >> a; // expected-error{{invalid operands to binary expression}} + + return a; +} +} // vector_implicit_conversions