diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index bdbabf2cd98d0..5c45cde0a39fe 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -450,6 +450,7 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when declaring a member template within a local class inside an OpenMP region. (#GH216052) - Fixed a bug where repeated #imports of modular headers in non-modular compilation were translated to #pragma clang module import. (#GH216924) - Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier. (#GH217204) +- Fixed an assertion failure when a value of a Unicode character type (`char8_t`, `char16_t`, `char32_t`) was implicitly splatted to a vector of the same element type, e.g. when comparing an `ext_vector_type` of `char32_t` with one of its elements. (#GH202317) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5c831e6cdebce..8aa58b1f877bc 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -13585,6 +13585,11 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, if (TargetBT && TargetBT->isSveVLSBuiltinType()) Target = TargetBT->getSveEltType(Context).getTypePtr(); + // Nothing to diagnose if stripping the wrappers left identical element types + // (e.g. a scalar splatted to a vector of its own type). + if (Source == Target) + return; + // If the source is floating point... if (SourceBT && SourceBT->isFloatingPoint()) { // ...and the target is floating point... diff --git a/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp b/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp index 6f9f8f3898625..80420d836a55d 100644 --- a/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp +++ b/clang/test/SemaCXX/warn-implicit-unicode-conversions.cpp @@ -149,3 +149,22 @@ void check_arithmetic(char8_t u8, char16_t u16, char32_t u32) { (void)(u16 | u32); // expected-warning {{bitwise operation between different Unicode character types 'char16_t' and 'char32_t'}} (void)(1 ? u32 : u16); // expected-warning {{conditional expression between different Unicode character types 'char32_t' and 'char16_t'}} } + +namespace GH202317 { +typedef __attribute__((__ext_vector_type__(4))) char32_t vf4; +typedef __attribute__((__ext_vector_type__(4))) int vi4; + +vi4 foo(vf4 &V) { return V.xyzw < V.x; } + +void same_element_type(vf4 &V, char32_t u32) { + vf4 v = u32; + v = V.x; + (void)(V.xyzw == u32); + (void)(u32 < V.xyzw); +} + +void different_element_type(vf4 &V, char8_t u8) { + (void)(V.xyzw < u8); // expected-warning {{implicit conversion from 'char8_t' to 'vf4'}} + vf4 v = u8; // expected-warning {{implicit conversion from 'char8_t' to 'vf4'}} +} +}