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

Reply via email to