Author: Daniel Petrovic Date: 2026-09-23T10:53:19+02:00 New Revision: c41e1ef6e1cc650cd05328155408ecb705986f09
URL: https://github.com/llvm/llvm-project/commit/c41e1ef6e1cc650cd05328155408ecb705986f09 DIFF: https://github.com/llvm/llvm-project/commit/c41e1ef6e1cc650cd05328155408ecb705986f09.diff LOG: [clang] Fix crash on assigning to _Atomic vectors (#225125) As described in the issue itself: 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 bt: <img width="1908" height="825" alt="225039_crash_atomic_vector" src="https://github.com/user-attachments/assets/c5d48ba5-fa9b-43f8-a555-8b9bbe558152" /> Co-authored-by: Timm Baeder <[email protected]> Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ExprConstant.cpp clang/test/Sema/vector-assign.c Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 99ad69562e314..16f2a768fe06c 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1881,12 +1881,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. @@ -1903,14 +1910,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 9749d0b43a629..bb7721df5a28b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12244,13 +12244,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; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
