[clang] a9c5e57 - [clang] Fix crash with follow-on diagnostics w/invalid logical operator (#227837)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 1 04:43:59 PDT 2026
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 at -1{{invalid operands to binary expression}}
(void)(ea && v2ua); // expected-error{{cannot convert between vector values of
diff erent size}}
- // expected-error at -1{{invalid operands to binary expression}}
(void)(v2ua || ea); // expected-error{{cannot convert between vector values of
diff erent size}}
- // expected-error at -1{{invalid operands to binary expression}}
(void)(ea || v2ua); // expected-error{{cannot convert between vector values of
diff erent size}}
- // expected-error at -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}}
More information about the cfe-commits
mailing list