Author: Aaron Ballman Date: 2026-10-01T07:43:50-04:00 New Revision: a9c5e57c03413e31a9293a4d938402e6204ff888
URL: https://github.com/llvm/llvm-project/commit/a9c5e57c03413e31a9293a4d938402e6204ff888 DIFF: https://github.com/llvm/llvm-project/commit/a9c5e57c03413e31a9293a4d938402e6204ff888.diff LOG: [clang] Fix crash with follow-on diagnostics w/invalid logical operator (#227837) If the logical operator involves a vector operand, we perform special vector-specific checks. `CheckVectorOperands()` returns a null QualType to signal there was an issue, and `CheckVectorLogicalOperands()` was using that signal to decide to report an "invalid operands to binary expression" diagnostic. However, `CheckVectorOperands()` also sometimes modifies the given LHS and RHS values and when that happens, the caller cannot assume they're still valid on a null QualType return. This was causing a crash from `CheckVectorLogicalOperands()` because it was attempting to use those newly invalidated expressions. This fixes the crash by letting `CheckVectorOperands()` report the diagnostics directly and removing the fallback logic from `CheckVectorLogicalOperands()`. This also helpfully removes some unhelpful follow-on diagnostics in other cases where we would report "cannot convert operands" followed by "invalid operands to binary expression". Fixes #227588 Added: Modified: clang/docs/ReleaseNotes.md clang/lib/Sema/SemaExpr.cpp clang/test/Sema/fp16vec-sema.c clang/test/Sema/vector-ops.c clang/test/SemaCXX/vector.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index bf190df9769dd..d22874d4130ee 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -579,6 +579,7 @@ features cannot lower the translation-unit ABI level; - Fixed a bug where a bit-field accessed as the result of a statement expression (e.g. `({ s.b; })`) was not subject to integer promotion, unlike an ordinary bit-field access. (#GH221542) +- No longer crashing due to follow-on diagnostics when there is an invalid operand in a logical operator involving a vector operand. (#GH227588) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3258abbc4d24f..34a36e98ba38e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13907,9 +13907,9 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, /*AllowBothBool*/ true, /*AllowBoolConversions*/ false, /*AllowBooleanOperation*/ false, - /*ReportInvalid*/ false); + /*ReportInvalid*/ true); if (vType.isNull()) - return InvalidOperands(Loc, LHS, RHS); + return QualType(); if (getLangOpts().OpenCL && getLangOpts().getOpenCLCompatibleVersion() < 120 && vType->hasFloatingRepresentation()) diff --git a/clang/test/Sema/fp16vec-sema.c b/clang/test/Sema/fp16vec-sema.c index 89f01c6dcf47b..7f4e855ae008a 100644 --- a/clang/test/Sema/fp16vec-sema.c +++ b/clang/test/Sema/fp16vec-sema.c @@ -44,7 +44,7 @@ void testFP16Vec(int c) { hv0 = c ? hv0 : fv1; // expected-error{{cannot convert between vector}} sv0 = hv0 == fv1; // expected-error{{cannot convert between vector}} sv0 = hv0 < fv1; // expected-error{{cannot convert between vector}} - sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} expected-error{{invalid operands to binary expression}} + sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} iv0 = hv0 == hv1; // expected-error{{assigning to}} // FIXME: clang currently disallows using these operators on vectors, which is diff --git a/clang/test/Sema/vector-ops.c b/clang/test/Sema/vector-ops.c index 575f38b972f5e..0f4a6e8f3f3e8 100644 --- a/clang/test/Sema/vector-ops.c +++ b/clang/test/Sema/vector-ops.c @@ -80,19 +80,19 @@ void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) { v2ua = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}} v2ua = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}} - v2sa = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}} - v2sa = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}} + v2sa = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} + v2sa = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} - v2ua = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}} - v2ua = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}} + v2ua = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} + v2ua = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} v2sa = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}} v2sa = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}} - v2ua = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}} - v2ua = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}} + v2ua = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} + v2ua = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} - v2sa = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}} - v2sa = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}} + v2sa = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} + v2sa = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} int s1; v2ua = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}} @@ -107,11 +107,11 @@ void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) { v2sa = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}} v2sa = v2ua || s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}} - v2ua = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}} - v2ua = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}} + v2ua = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} + v2ua = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} - v2sa = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}} - v2sa = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}} + v2sa = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} + v2sa = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} float f1; v2ua = v2ua && f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}} @@ -133,3 +133,20 @@ void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) { v2sa = v2fa || f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}} } + +void gh227588(void) { + typedef long v4l __attribute__((vector_size(32))); + v4l v; + register int a[4]; + // This would previously crash because of checking for the invalid vector + // operation after reporting the error from lvalue conversion. + int x = a && v; // expected-error {{address of register variable requested}} + + struct S { + int count; + union IncompleteUnionTy * __attribute__((counted_by_or_null(count))) buf; // expected-note {{consider providing a complete definition for 'union IncompleteUnionTy'}} expected-note {{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + } *s; + + // The same would happen here. + int y = s->buf && v; // expected-error {{annot use 's->buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} +} diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp index 87dfa3760541d..581d829560ea6 100644 --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -736,13 +736,9 @@ void test_enum_vector_scalar(Enum ea, v2u v2ua) { (void)(v2ua > ea); // expected-error{{cannot convert between vector values of diff erent size}} (void)(ea > v2ua); // expected-error{{cannot convert between vector values of diff erent size}} (void)(v2ua && ea); // expected-error{{cannot convert between vector values of diff erent size}} - // expected-error@-1{{invalid operands to binary expression}} (void)(ea && v2ua); // expected-error{{cannot convert between vector values of diff erent size}} - // expected-error@-1{{invalid operands to binary expression}} (void)(v2ua || ea); // expected-error{{cannot convert between vector values of diff erent size}} - // expected-error@-1{{invalid operands to binary expression}} (void)(ea || v2ua); // expected-error{{cannot convert between vector values of diff erent size}} - // expected-error@-1{{invalid operands to binary expression}} (void)(v2ua & ea); // expected-error{{cannot convert between vector values of diff erent size}} (void)(ea & v2ua); // expected-error{{cannot convert between vector values of diff erent size}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
