[clang] [clang] Fix crash on assigning to _Atomic vectors (PR #225125)
Daniel Petrovic via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 22 02:28:56 PDT 2026
https://github.com/daniel-petrovic updated https://github.com/llvm/llvm-project/pull/225125
>From 4aae634aa29c18d3bf91cde0ad29454a61887e81 Mon Sep 17 00:00:00 2001
From: Daniel Petrovic <daniel-dev at hotmail.de>
Date: Mon, 21 Sep 2026 17:52:29 +0200
Subject: [PATCH] [clang] Fix crash on assigning to _Atomic vectors
d=c on _Atomic vector crashed during the overflow check because
isVectorType() doesn't look through _Atomic. Strip _Atomic
before checking operand types.
Fixes #225039
---
clang/lib/AST/ByteCode/Compiler.cpp | 21 ++++++++++++++-------
clang/lib/AST/ExprConstant.cpp | 8 +++++---
clang/test/Sema/vector-assign.c | 13 +++++++++++++
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 38a095f8a1164..747b55b6d8a57 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1862,12 +1862,19 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
const Expr *RHS = E->getRHS();
assert(!E->isCommaOp() &&
"Comma op should be handled in VisitBinaryOperator");
+
+ QualType LHSType = LHS->getType();
+ if (const auto *AT = LHSType->getAs<AtomicType>())
+ LHSType = AT->getValueType();
+ QualType RHSType = RHS->getType();
+ if (const auto *AT = RHSType->getAs<AtomicType>())
+ RHSType = AT->getValueType();
assert(E->getType()->isVectorType());
- assert(LHS->getType()->isVectorType());
- assert(RHS->getType()->isVectorType());
+ assert(LHSType->isVectorType());
+ assert(RHSType->isVectorType());
// We can only handle vectors with primitive element types.
- if (!canClassify(LHS->getType()->castAs<VectorType>()->getElementType()))
+ if (!canClassify(LHSType->castAs<VectorType>()->getElementType()))
return false;
// Prepare storage for result.
@@ -1884,14 +1891,14 @@ bool Compiler<Emitter>::VisitVectorBinOp(const BinaryOperator *E) {
? BinaryOperator::getOpForCompoundAssignment(E->getOpcode())
: E->getOpcode();
- PrimType ElemT = this->classifyVectorElementType(LHS->getType());
- PrimType RHSElemT = this->classifyVectorElementType(RHS->getType());
+ PrimType ElemT = this->classifyVectorElementType(LHSType);
+ PrimType RHSElemT = this->classifyVectorElementType(RHSType);
PrimType ResultElemT = this->classifyVectorElementType(E->getType());
if (E->getOpcode() == BO_Assign) {
assert(Ctx.getASTContext().hasSameUnqualifiedType(
- LHS->getType()->castAs<VectorType>()->getElementType(),
- RHS->getType()->castAs<VectorType>()->getElementType()));
+ LHSType->castAs<VectorType>()->getElementType(),
+ RHSType->castAs<VectorType>()->getElementType()));
if (!this->visit(LHS))
return false;
if (!this->visit(RHS))
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9242491832841..d43c55d4ec4c7 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12236,13 +12236,15 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
Expr *LHS = E->getLHS();
Expr *RHS = E->getRHS();
- assert(LHS->getType()->isVectorType() && RHS->getType()->isVectorType() &&
+ QualType LHSType = LHS->getType().getAtomicUnqualifiedType();
+ QualType RHSType = RHS->getType().getAtomicUnqualifiedType();
+ assert(LHSType->isVectorType() && RHSType->isVectorType() &&
"Must both be vector types");
// Checking JUST the types are the same would be fine, except shifts don't
// need to have their types be the same (since you always shift by an int).
- assert(LHS->getType()->castAs<VectorType>()->getNumElements() ==
+ assert(LHSType->castAs<VectorType>()->getNumElements() ==
E->getType()->castAs<VectorType>()->getNumElements() &&
- RHS->getType()->castAs<VectorType>()->getNumElements() ==
+ RHSType->castAs<VectorType>()->getNumElements() ==
E->getType()->castAs<VectorType>()->getNumElements() &&
"All operands must be the same size.");
diff --git a/clang/test/Sema/vector-assign.c b/clang/test/Sema/vector-assign.c
index 119a320585ef6..15e13492b49b9 100644
--- a/clang/test/Sema/vector-assign.c
+++ b/clang/test/Sema/vector-assign.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversion
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversion -fexperimental-new-constant-interpreter
typedef unsigned int v2u __attribute__ ((vector_size (8)));
typedef signed int v2s __attribute__ ((vector_size (8)));
typedef signed int v1s __attribute__ ((vector_size (4)));
@@ -51,3 +52,15 @@ void test3a(longlongvec *); // expected-note{{passing argument to parameter here
void test3(const unsigned *src) {
test3a(src); // expected-error {{incompatible pointer types passing 'const unsigned int *' to parameter of type 'longlongvec *'}}
}
+
+// #225039: assignment to an _Atomic vector
+typedef unsigned gh225039_vec __attribute__((vector_size(16)));
+typedef signed int gh225039_vec_i32 __attribute__((vector_size(16)));
+void test4(void) {
+ gh225039_vec c;
+ _Atomic gh225039_vec d;
+ d = c;
+ d += c;
+ _Atomic gh225039_vec_i32 e, f;
+ e = f;
+}
More information about the cfe-commits
mailing list